[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Unable to load bitmaps from extension DLL

Posted on 1998-03-17
10
Medium Priority
?
687 Views
Last Modified: 2012-08-14
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
Comment
Question by:DenMan
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
10 Comments
 
LVL 23

Expert Comment

by:chensu
ID: 1183550
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
 

Author Comment

by:DenMan
ID: 1183551
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
 

Expert Comment

by:jann
ID: 1183552
Try set vInstance (why don't you use hInstance) returned by AfxGetModuleHandle() instead by AfxGetInstanceHandle().
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:DenMan
ID: 1183553
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
 
LVL 23

Accepted Solution

by:
chensu earned 100 total points
ID: 1183554
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
 

Author Comment

by:DenMan
ID: 1183555
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
 
LVL 23

Expert Comment

by:chensu
ID: 1183556
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
 

Author Comment

by:DenMan
ID: 1183557
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
 
LVL 23

Expert Comment

by:chensu
ID: 1183558
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
 

Author Comment

by:DenMan
ID: 1183559
Nope, I got your response.  Thanks!  I'll give it a shot.
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
Suggested Courses

649 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question