Another problem sent to destroy me! ;0

I'm have created a hook to hook a thread from another app. This all works fine. It monitors a RICHEDIT window and sends a message to my own app every time the EM_REPLACESEL message is sent to the Richedit control. This would be fine except that the string pointer passed with EM_REPLACESEL seems to be invalid when I send it to my app.

In my DLL which implements my hook I have the following:

Code:
LRESULT CALLBACK HookProc(int iCode, WPARAM wParam, LPARAM lParam)
{
	if (iCode < 0)
		return CallNextHookEx(g_hook, iCode, wParam, lParam);

	CWPSTRUCT *msg = (CWPSTRUCT *)lParam;
	if(msg->hwnd == g_watchWnd)
	{
		if(msg->message == EM_REPLACESEL)
			SendMessage(g_callingWnd, WM_NEWACTION, 0, msg->lParam);

		if(msg->message == WM_DESTROY)
			RemoveTableHook();		
	}

	return 0;
}
g_watchWnd is the RICHEDIT window and g_callingWnd is the main window of my app. In my app I have the following message handling procedure:

Code:
LRESULT CDLLTestAppDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{	
	if(message == WM_NEWACTION)
	{
		m_Edit.SetWindowText((LPCTSTR)lParam);
		return TRUE;
	}

	return CDialog::WindowProc(message, wParam, lParam);
}
m_Edit is an edit control in my app which I'm using for test purposes only - it wont be used in the actual implementation.

The WM_NEWACTION messageID was declared using RegisterWindowMessage() in both the app and the DLL and this seems to work fine. the message gets sent and is picked up. However, the string pointer in lParam seems no longer to work, as if the address does not point to a string any longer.

If my hook is set as thread specific (using the thread that the RICHEDIT window belongs to), the message handling code causes the app to crash. If the hook is declared system wide, it doesn't crash but no text is passed over, I just get "".

The thing that really confuses me is that if I do the following there is no problem:

Code:
	CWPSTRUCT *msg = (CWPSTRUCT *)lParam;
	if(msg->hwnd == g_watchWnd)
	{
		if(msg->message == EM_REPLACESEL)
			SendMessage(g_callingWnd, EM_REPLACESEL, 0, msg->lParam);
...

	if(message == EM_REPLACESEL)
	{
		m_Edit.SetWindowText((LPCTSTR)lParam);
		return TRUE;
	}
What is the EM_REPLACESEL messageID doing that my own messageID isnt??!

I know I can use this code - but I don't want to send the EM_REPLACESEL message when that's not want I'm going to be doing with the text - and I want to solve this problem!!

Any help would be very much appreciated

dt