Introduction
On occasions, I have needed to send a CString
object to a window in my application via SendMessage
or PostMessage
(usually 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
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 WPARAM
or 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
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 CString
s 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.
The Implementation
I have created 2 classes CMessageString
(derived from CString
) and 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
class.
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
type. CMessageStringManager
consists of a protected member CPtrList
, an Add
method, Delete
method, 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 TRACE
macro.
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)
ForceCleanup ()
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 CMainFrame
class.
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
void SendAString()
{
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;
if (CMessageString::IsStringValid(pString))
{
delete pString;
}
else
{
ASSERT(FALSE);
return MESSAGESTRING_NOT_RECEIVED;
}
return 0;
}
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.