I had really a hard time to figure out how to integrate my DLL in projectWise menu and make it work, hence, I'm uploading my code hopefully it comes in help for someone.
Let me tell you since now, that the secret is on the .def file.
1 - First, I have created a new c++ class I called mydll, my project is called "e3cppdll"
Here is the mydll.h
#pragma once class mydll { public: _declspec (dllexport) mydll(); _declspec (dllexport) int do_some(int a); };
and this is my mydll.cpp
#include "stdafx.h" #include "mydll.h" #include <stdexcept> #include<iostream>//for cin, cout and endl #include <fstream> using namespace std; int do_some( ) { ofstream myfile; myfile.open("C:/Users/LTF/Desktop/c++.txt"); myfile << "Writing this to a file.....\n"; myfile.close(); return 10; } //}
3 - Now, right click on your project and select "Properties"
4 - Go to Linker and click on input
4 - On the option "Module Definition File", set your .def file, make sure to name your file as the name of your class, just to make your life easy.
5 - Now , final step, Create a text file, on the same folder where your DLL is located and copy paste the following text:
LIBRARY e3cppdll DESCRIPTION "mydll ..." EXPORTS write_file @1 do_some @2
I suppose you have already installed ProjectWise SDK,
6 - Now, Open "Custom Module Manager", you usually find it in C:\Program Files (x86)\Bentley\ProjectWise\SDK\bin\x86 (or X64)
7 - Click on add, and follow the following parameters
Please don't forget that I have named my project "e3cppdll"
8 - Last step now, Open the projectWise Menu Editor, you find it normally in "C:\Program Files (x86)\Bentley\ProjectWise\bin\MrrEdit.exe" (or X64)
9 - Click on New, to create a new menu, and follow the screenshot below
Restart your ProjectWise Explorer and that's all.
Lotfi,
Well, not exactly. You are actually doing two different things in your approach. The registry entries that you are making with the Custom Module Manager are for initializing Custom Modules, which you can use to do various things, typically add hooks, custom menus implemented by API calls, etc. This "works" only because of what you have done with the Menu Editor tool. The function that you define with the Custom Module Manager is defined as having a specific function prototype and depending upon what you return, with either keep your module (dll) loaded, or it will unload your DLL. Take a look at the documentation under Modules > ProjectWise DMS API > Iitialization Functions, as well as searching for "Custom Module" (or Customer NEAR Module).
A few tips from the PW SDK training:
If you are using MFC with dynamic linking, your initialization function should look something like this:
/******************************************************************************
Add your custom initialize function here. Make sure that you export it.Look at previous labs for the prototype or search the SDK samples for"CustomInitialize".
Note:All we need to do is return IDOK as we will set the hooks in CMyHooks01App::InitInstance()
Don't forget to add the AFX_MANAGE_STATE macro as described at the top of this file
*******************************************************************************/extern "C" LONG CustomInitialize(ULONG ulMask, /* i Application Mask */LPVOID lpReserved /* i Reserved (must be NULL) */){ AFX_MANAGE_STATE(AfxGetStaticModuleState());
TRACE(L"CustomInitialize() called...\n");
/* add your initialization code here if you don't use ::InitInstance() to do so */
return IDOK;}
Or like this if you are using a "Win32 DLL" (you need to make sure that your initialization calls are only done once, hence the static BOOL) :
What you are doing with the Custom Module Manager has nothing to do with what you are showing with the Menu Editor tool. The menu editor tool allows you to add or modify menu items. The way that it works is when ProjectWise Explorer starts, it looks for .mrr files in the "bin" directory (and only in the bin directory). For each .mrr file found, if the functions specified for a menu item are not exported, or are not found, or if the dll doesn't exist, no error is reported, and the menu item is ignored. These too have specific function prototypes defined in the help under ProjectWise API Documentation > ProjectWise SDK Tools > ProjectWise Menu Editor. Look under "Function prototypes". If you need more control over ProjectWise menus, take a look at the sample "MYMENU" which doesn't use a .mrr file. Since your function (defined as for a "Document Command") doesn't match the expected prototype, you are likely corrupting your stack, or at least setting yourself up for a crash, sooner or later.
HTHs
Thank you so much Dan, this is a great explanation.
I have tried to use the MRR without registering my dll but it didn't work, I tried even to register it in the registry with no luck.
Now with what you said, it makes more sense
------------------------ LTF
Hi Dan, I couldnt find the ProjectWise Menu Editor mentioned by @Lotfi in the following location "C:\Program Files (x86)\Bentley\ProjectWise\bin\MrrEdit.exe". Where can I find the ProjectWise Menu Editor? But I could see in the SDK describing about the mrredit as shown in the image below.
Hi Dan, in ProjectWise SDK help document where is the function declaration of hoot initialization function "CustomInitialize"? Thank you.
A couple of things:
To "initialize" any hooks, you call aaApi_AddHook() from the "CustomInitialize" function that you register. Take a look at the "hookimpl.cpp" file in the samples.