A Journey 2 Eternity

Set resource handle in MFC and ATL

Posted on: April 15, 2009

When working in MFC/ATL and then using a resource dll can at times cause bugs because resource handle is not properly set. For e.g. if you have a dialog resource in a dll and you instantiate a CDialog which results in an error because resource cannot be located in this application or dll since it’s in the resource dll. So solution for above problem will be to set correct resource handle.

MFC provides two functions…

1. AfxGetResourceHandle

2. AfxSetResourceHandle

So we should first save our current resource handle and then set new resource handle before loading such a resource. Also don’t forget to set our old handle since its good practice.

Internally MFC calls FindResource and LoadResource using this handle, so if it’s not properly set this will cause failure in loading resources.

In ATL it’s quite similar except that we’ve got a new function called AddResourceInstance which adds our new resource handle to existing list of handles. So when a look up is done given resource handle is also used. Following functions are provided in ATL to work with resource handles…

1. AddResourceInstance

2. GetResourceInstance – Similar to AfxGetResourceHandle

3. SetResourceInstance – Similar to AfxGetSetResourceHandle

For newbies this is always a painful bug to resolve as they don’t know what went wrong since they expect this to be automagically done.

Sample code snippet:

class CEMCResourceHandle
{
public:
	CEMCResourceHandle() {
		m_hPrevInst = AfxGetResourceHandle();
		m_hDLLInstance = ::LoadLibrary(szESIMFCControlsDLLName);
		if (m_hDLLInstance) {
			AfxSetResourceHandle(m_hDLLInstance);
		}
	}

	virtual ~CEMCResourceHandle() {
		AfxSetResourceHandle(m_hPrevInst);
		if(m_hDLLInstance != NULL) {
			FreeLibrary(m_hDLLInstance);
		}
	}

	//! Retrieves the current resource instance
	//!
	//! \return Return the current resource instance
	HINSTANCE GetCurrentInstance() const { return m_hDLLInstance; }

	//! Retrieves the previous resource instance
	//!
	//! \return Return the previous resource instance
	HINSTANCE GetPrevInstance() const { return m_hPrevInst; }

private:
	//! Handle of previous resource instance
	HMODULE m_hPrevInst;

	//! Handle of loaded DLL resource instance
	HMODULE m_hDLLInstance;
};

// Just made an temporary instance of CEMCResourceHandle class
// Load resource from the DLL
CEMCResourceHandle resHandle;

// Set bitmap to the MoveUp button
m_btnUp.SetBitmap(::LoadBitmap(resHandle.GetCurrentInstance(), MAKEINTRESOURCE(IDB_BITMAP_UPARROW)));
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Pages

Categories

April 2009
M T W T F S S
« Dec   May »
 12345
6789101112
13141516171819
20212223242526
27282930  

Blog Stats

  • 27,491 hits
%d bloggers like this: