[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 691
  • Last Modified:

Unable to load bitmaps from extension DLL

I have created an MFC extension DLL in MSVC++ 5.0, which contains a few classes, dialogs, and bitmaps.  I have exported one of the classes, and this class calls another non-exported dialog in the dll.  The dialog works fine, but the buttons (which are supposed to be bitmap buttons) do not display their bitmaps.  The only time the bitmaps DO show up are when I define a bitmap resource with the same name in the .exe module.  How can I specify that I want to load the bitmaps from the DLL?

This is a sample of the code I use to attach the bitmap to the button:
      m_cOkButton.SetBitmap(::LoadBitmap(vInstance, MAKEINTRESOURCE(IDB_OK_BITMAP)));

This code worked fine before it was segregated into a DLL, and it works fine when the .EXE contains an IDB_OK_BITMAP resource.
0
DenMan
Asked:
DenMan
  • 5
  • 4
1 Solution
 
chensuCommented:
What is vInstance? It should be the instance handle of the DLL, which you can get in DLLMain().

BTW, the application must call the DeleteObject function to delete each bitmap handle returned by the LoadBitmap function.
0
 
DenManAuthor Commented:
vInstance is the HINSTANCE returned by AfxGetInstanceHandle(), which according to the docs should return an instance of the DLL (since it's called from within the DLL).

How would I get the instance handle from DLLMain()?  Should I set a member variable equal to that, so it can be passed to other classes (such as the one that's supposed to show the bitmaps)?
0
 
jannCommented:
Try set vInstance (why don't you use hInstance) returned by AfxGetModuleHandle() instead by AfxGetInstanceHandle().
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
DenManAuthor Commented:
AfxGetModuleHandle() is not a function that MSVC++ 5 recognizes.  At least, the compiler didn't recognize it and I couldn't find any references to it in the help files.

I actually have had success using AfxFindResourceHandle and searching for one of the bitmaps I know is in the DLL.  How can I load one of the DLL resources in the calling application?
0
 
chensuCommented:
I see. Have you ever read thru the following documentation? The HINSTANCE returned by AfxGetInstanceHandle() is not the instance handle of the DLL. You need to use AFX_MANAGE_STATE(AfxGetStaticModuleState( )); at the beginning of the functions.
BTW, the DLLMain() is hidden by MFC code.


For exported functions from a DLL, such as one that launches a dialog box in your DLL, you need to add 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.

Problems with resources in DLLs will occur if the AFX_MODULE_STATE macro is not used. By default, MFC uses the resource handle of the main application to load the resource template. This template is actually stored in the DLL. The root cause is that MFC's module state information has not been switched by the AFX_MODULE_STATE macro. The resource handle is recovered from MFC's module state. Not switching the module state causes the wrong resource handle to be used.

AFX_MODULE_STATE does not need to be put in every function in the DLL. For example, InitInstance can be called by the MFC code in the application without AFX_MODULE_STATE because MFC automatically shifts the module state before InitInstance and then switches it back after InitInstance returns. The same is true for all message map handlers. Regular DLLs actually have a special master window procedure that automatically switches the module state before routing any message.

0
 
DenManAuthor Commented:
I am exporting entire classes, not specific functions.  Do I need to put the AFX_MANAGE_STATE in each function of the class?  Also, the dialog that I was having the most trouble with is not called from outside the DLL -- it is called by one of the functions in another class that IS exported.  It should be retrieving everything internally, I would think, but it tries to look in the .exe module's resources instead of its own.

I tried putting AFX_MANAGE_STATE into the InitDialog() of the internal dialog that I have been having trouble with, and got a number of compiler errors about how "DllMain was already defined in xxxx.obj".

I have had no trouble with exporting other dialogs, even though I am not using AFX_MANAGE STATE.  Is that because this is an Extension DLL as opposed to a regular DLL?
0
 
chensuCommented:
Forget it.

Since it is an MFC extension DLL, the initilization should look like this:

/////////////////////////////////////////////////////////////////////////////
// Initialization of MFC Extension DLL

#include "afxdllx.h"    // standard MFC Extension DLL routines

static AFX_EXTENSION_MODULE NEAR extensionDLL = { NULL, NULL };

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
      if (dwReason == DLL_PROCESS_ATTACH)
      {
            // Extension DLL one-time initialization - do not allocate memory here,
            //   use the TRACE or ASSERT macros or call MessageBox
            if (!AfxInitExtensionModule(extensionDLL, hInstance))
                  return 0;

            // Other initialization could be done here, as long as
            // it doesn't result in direct or indirect calls to AfxGetApp.
            // This extension DLL doesn't need to access the app object
            // but to be consistent with testdll1.dll, this DLL requires
            // explicit initialization as well (see below).

            // This allows for greater flexibility later in development.
      }
      return 1;   // ok
}


So, you can do this,

vInstance = extensionDLL.hModule;
m_cOkButton.SetBitmap(::LoadBitmap(vInstance, MAKEINTRESOURCE(IDB_OK_BITMAP)));

0
 
DenManAuthor Commented:
Since the SetBitmap() function is in a different source file than the DllMain function (and the AFX_EXTENSION_ MODULE extensionDLL declaration), it doesn't recognize the reference to extensionDLL.  Should I put the AFX_EXTENSION_ MODULE in a common header file instead?

Thanks for all your help!
0
 
chensuCommented:
Remove the "static" keyword before AFX_EXTENSION_MODULE and declare "extern AFX_EXTENSION_MODULE extensionDLL;" in other source files before you use it.

I didn't receive any notification when you added this comment. Until today, I received the notification of "Good answer". Is it too late?
0
 
DenManAuthor Commented:
Nope, I got your response.  Thanks!  I'll give it a shot.
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now