Outlook add-in, display dialog box

  • Thread starter Thread starter Phoenix
  • Start date Start date
P

Phoenix

Hi all,

I am currently developping in C++ (with Visual Studio 6) an outlook
add-in. I need to ask the user to choose something from a combobox. So
what I thought is to do a Dialog Box asking the user to select an item
in a combobox. I did the same thing I would do for a normal exe that
is: creating the ressource, the class linked to the ressource and then
in my code when pressing a certain button displaying the DialogBox in a
modal way :

CDialogLabels dlgLabels;
dlgLabels.DoModal();

Yes but it doesn't work ! GetLastError returns 1812
(ERROR_RESOURCE_DATA_NOT_FOUND : The specified image file did not
contain a resource section.). After a few researches I found out that
for a dll when doing that windows tries to load the ressource from the
exe (using the exe context) when it should load it from the DLL. Some
people proposed to add :

HINSTANCE hRes = NULL;
hPrevRes = AfxGetResourceHandle();
hRes = LoadLibrary("OutlookPhoenix.dll");

if(hRes)
AfxSetResourceHandle(hRes)

in the InitInstance of the dll

And then
AfxSetResourceHandle(hPrevRes);

in the ExitInstance.

This is setting the global resource handler to the dll instance
handler.

Right now the DialogBox is showing but ... Outlook crashes.
I tried a FreeLibrary in the ExitInstance, I tried not to get the hRes
by loading the library but using some
GetModuleHandle("OutlookPhoenix.dll") ... But still it's not working !
Outlook still crashes. I think it's because I'm setting globaly the
ResourceHandle for all the application and Outlook doesn't like that
(probably it tries also to load some resources and then crashes).

I tried to do the job using a modeless dialog box but can't manage to
display it (the Create fails, I can't get the full error description).

I don't have anymore ideas, could you help me ?

Thanks in advance,
Best Regards,
Maximilien
 
Phoenix said:
Hi all,

I am currently developping in C++ (with Visual Studio 6) an outlook
add-in. I need to ask the user to choose something from a combobox. So
what I thought is to do a Dialog Box asking the user to select an item
in a combobox. I did the same thing I would do for a normal exe that
is: creating the ressource, the class linked to the ressource and then
in my code when pressing a certain button displaying the DialogBox in a
modal way :

CDialogLabels dlgLabels;
dlgLabels.DoModal();

Yes but it doesn't work ! GetLastError returns 1812
(ERROR_RESOURCE_DATA_NOT_FOUND : The specified image file did not
contain a resource section.). After a few researches I found out that
for a dll when doing that windows tries to load the ressource from the
exe (using the exe context) when it should load it from the DLL. Some
people proposed to add :

HINSTANCE hRes = NULL;
hPrevRes = AfxGetResourceHandle();
hRes = LoadLibrary("OutlookPhoenix.dll");

if(hRes)
AfxSetResourceHandle(hRes)

in the InitInstance of the dll

And then
AfxSetResourceHandle(hPrevRes);

in the ExitInstance.

This is setting the global resource handler to the dll instance
handler.

Right now the DialogBox is showing but ... Outlook crashes.
I tried a FreeLibrary in the ExitInstance, I tried not to get the hRes
by loading the library but using some
GetModuleHandle("OutlookPhoenix.dll") ... But still it's not working !
Outlook still crashes. I think it's because I'm setting globaly the
ResourceHandle for all the application and Outlook doesn't like that
(probably it tries also to load some resources and then crashes).

I tried to do the job using a modeless dialog box but can't manage to
display it (the Create fails, I can't get the full error description).

I don't have anymore ideas, could you help me ?


From the tech ref...

-Mark

AFX_MANAGE_STATE
AFX_MANAGE_STATE( AFX_MODULE_STATE* pModuleState )

Parameters

pModuleState

A pointer to an AFX_MODULE_STATE structure.

Remarks

Call this macro to protect an exported function in a DLL. When this macro is
invoked, pModuleState is the effective module state for the remainder of the
immediate containing scope. Upon leaving the scope, the previous effective
module state will be automatically restored.

The AFX_MODULE_STATE structure contains global data for the module, that is,
the portion of the module state that is pushed or popped.

By default, MFC uses the resource handle of the main application to load the
resource template. If you have an exported function in a DLL, such as one
that launches a dialog box in the DLL, this template is actually stored in
the DLL module. You need to switch the module state for the correct handle
to be used. You can do this by adding the following code to the beginning of
the function:

AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
This swaps the current module state with the state returned from
AfxGetStaticModuleState until the end of the current scope.
 
I don't understand how I missed that ! This is working damn good !
Thanks Mark.

Oh and for information (for other people who may have the same issue)
you should make sure that an initialisation function of the Dialog is
not putting back the state to the application state. That is, all the
function of the Dialog should use
AFX_MANAGE_STATE(AfxGetStaticModuleState( )); rather than the usual
AfxGetAppModuleState.

Regards,
Maximilien

Mark J. McGinty ha scritto:
 
Back
Top