HOWTO: Clean Up Temporary MFC Object in _USRDLL DLLsLast reviewed: July 31, 1997Article ID: Q105286 |
The information in this article applies to:
SUMMARYThe Microsoft Foundation Class (MFC) Libraries create temporary objects that are used inside of message handler functions. In MFC applications, these temporary objects are automatically cleaned up in the CWinApp::OnIdle() function that is called in between processing messages. However, in MFC dynamic-link libraries (DLLs) built using the _USRDLL model, the OnIdle() function is not automatically called. As a result, temporary objects are not automatically cleaned up. To clean up temporary objects, the DLL must explicitly call OnIdle(1) periodically.
MORE INFORMATIONMFC maintains a set of maps that associate windows' handles with MFC objects. When the FromHandle() function is called, it checks the map to see whether an MFC object exists that is associated with the handle. If there is, FromHandle() returns a pointer to the object; if not, FromHandle() creates a temporary object. These temporary objects are cleaned up when CWinApp::OnIdle() is called with a count of 1. In an MFC application, the OnIdle() function is called when the message loop is idle. It is called inside of a ::PeekMessage() loop that checks for new messages. The ::PeekMessage() loop is in the function CWinApp::Run(). The OnIdle() function is passed an "lCount" parameter, which indicates how many times OnIdle() has been called since the last message. When OnIdle() is called with an lCount equal to 1, the temporary objects are cleaned up. However, because an MFC _USRDLL DLL does not contain a main message loop, OnIdle() is not automatically called and the temporary objects are not cleaned up. To clean up the temporary objects, the DLL must call OnIdle() explicitly. In general, it can be difficult to determine the best time to call OnIdle()- -it needs to be called often enough that temporary objects do not accumulate, and it needs to be called when no temporary objects are in use. Below are three strategies for calling OnIdle() in _USRDLL DLLs:
Sample Code
static DWORD dwEntryCount = 0; void LockTemporaryObjects() { InterlockedIncrement (&dwEntryCount); } void UnlockTemporaryObjects() { if (dwEntryCount == 0) return;//Keep us from going negative if (0 == InterlockedDecrement((&dwEntryCount)) { AfxGetApp()->CWinApp::OnIdle(0); // Updates UI objects AfxGetApp()->CWinApp::OnIdle(1); // Free's tempory objects } }The LockTemporaryObjects() and UnlockTemporaryObjects() function are then used as follows:
Sample Code
void PASCAL FAR EXPORT MyDllRoutine() { TRY { LockTemporaryObjects(); // Do work UnlockTemporaryObjects(); } CATCH_ALL(e) { // Good idea to deal with exceptions in _USRDLL anyway UnlockTemporaryObjects(); } END_CATCH_ALL }These approaches are easy to implement for functions that the DLL explicitly exports; however, it is also possible to enter the DLL through the window procedure used by MFC windows created in the DLL. If the DLL creates a window that has a long lifetime, such as a modeless dialog box or a frame window, then you may want to clean up temporary objects in between calls to the this window's window procedure. You can do this by overriding the WindowProc() function for the window object. This function is called once for each message that the window processes. Because it is very common for message handlers to call functions that end up sending more messages to the window, you need to use the counter method mentioned above to make sure that you aren't cleaning up temporary objects that are still being used. The following code fragment demonstrates how this could be done for a modeless dialog box in a class derived from CDialog:
CMyDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { LockTemporaryObjects(); LRESULT lResult = CDialog::WindowProc( message, wParam, lParam); UnlockTemporaryObjects(); return lResult; } Keywords : MfcDLL kbhowto Technology : kbmfc Version : 1.0 1.5 1.51 1.52 2.0 2.1 4.0 7. Platform : MS-DOS NT WINDOWS |
================================================================================
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |