On occasions, I have needed to send a
CString object to a window in my application via
PostMessage). I have seen this particular question posted on the message boards several times, so I decided to post the code that I use to deal with this situation.
The problem is that for whatever reason, you need to send a message to another window in your application and that message needs to include a
CString object (passed via the
LPARAM parameters). This is problematic because you must be careful to allocate the
CString object on the heap (via the
new operator), and you must take care to insure that the
CString object is deleted when your application is finished with it. Not only this, but potential problems exist, such as accidentally sending the same message to the target window with no
CString object passed in and various other situations.
The solution is to use a
CString derived class specifically designed to deal with this situation which deals with all of the issues involved in sending
CStrings via Windows messaging. The solution involves 2 classes which work together to:
- Ensure that
CString objects are only sent to windows within the current process (sending to other processes would cause unpredictable problems)
- Ensure that
CString objects are properly cleaned up after they have been used
- Ensure that if the message does not make it to the intended target, that the
CString object is not leaked
- Ensure that the receiving window does not process the message if the
CString object is invalid.
- Avoid over-complicating the problem with global variables,
CWinApp variables, etc.
I have created 2 classes
CMessageString (derived from
CMessageStringManager (not derived from any class).
CMessageStringManager is not called directly by the program, it is managed as a protected static member of the
CMessageString is a public derived class of
CString which implements all of the currently defined constructors for
CString (from MSDN).
CMessageString has a protected static member of
CMessageStringManager consists of a protected member
ForceCleanup function and
IsValid function. Each time a
CMessageString is constructed, the
Add method of
CMessageStringManager is called to add the new
CMessageString object into the
CPtrList. When a
CMessageString is destroyed, the
Delete method is called to remove it from the
CPtrList. When the app closes and the
CMessageStringManager class is destroyed, it ensures that there are no
CMessageString objects left in the list. If there are, it deletes them and if in debug mode, notifies the programmer through the
CMessageString implements 5 public methods.
SendAsWParam (HWND hwndTarget, UINT uiMessage, WPARAM wParam)
SendAsLParam (HWND hwndTarget, UINT uiMessage, LPARAM lParam)
PostAsWParam (HWND hwndTarget, UINT uiMessage, WPARAM wParam)
PostAsLParam (HWND hwndTarget, UINT uiMessage, LPARAM lParam)
static IsStringValid (CMessageString* pString)
How to use these classes
I have included a simple demo project to show how this is used. In order to use these classes in your application, first add the 4 files to your project. To see how a
CMessageString is sent, look in the
CStringMessageDemoView class. To see how a
CMessageString is received, look in the
First, include the messagestring.h file in your stdafx.h file (or some other appropriate file, I include it here because is makes it easy to use the class throughout my program).
TO SEND A CMessageString as a message
CMessageString* pString = new CMessageString;
(*pString) = "bla.bla.bla";
pString->PostAsWParam(hwnd, ID_SOME_MESSAGE, 0);
TO RECEIVE A CMessageString as a message
LRESULT CSomeWindow::OnStringMessage(WPARAM wParam, LPARAM lParam)
CMessageString* pString = (CMessageString*)wParam;