Link to home
Start Free TrialLog in
Avatar of DenMan
DenMan

asked on

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.
Avatar of chensu
chensu
Flag of Canada image

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.
Avatar of DenMan
DenMan

ASKER

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)?
Try set vInstance (why don't you use hInstance) returned by AfxGetModuleHandle() instead by AfxGetInstanceHandle().
Avatar of DenMan

ASKER

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?
ASKER CERTIFIED SOLUTION
Avatar of chensu
chensu
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of DenMan

ASKER

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?
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)));

Avatar of DenMan

ASKER

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!
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?
Avatar of DenMan

ASKER

Nope, I got your response.  Thanks!  I'll give it a shot.