Send Cstring using and get answer using Win Message - c++

I need to send string using win message and get back answer. Does following method has memory management problems regarding CString?
Call:
CString params = "Hello";
SendMessage(hWnd,WM_AUT_MESSAGE, (WPARAM)&params,0);
Answer:
LRESULT CMainWindow::OnMessageAuthorise(WPARAM wParam, LPARAM lParam)
{
CString *pStr = (CString*)wParam;
*pStr="Bye";
return 0;
}

It looks OK. SendMessage blocks and does not return until OnMessageAuthorise returns, so even with a pointer to a stack variable there is no race condition. (Assuming, of course, that all of this happens within the same process.)

Related

How does one move a std::unique_ptr between windows without risking a memory leak?

I want to do this project in C++ and be done with it once and for all:
select a movie from a list in one window and display the movie's details in another window.
I'd already arrived at Remy Lebeau's solution here and found his post because I'd realized the same limitation he did: it exposes the raw pointer to memory leakage.
(Please excuse my coding style).
MoviesWindow::MovieSelected( const unsigned int uint__MovieKey )
{ ...
std::unique_ptr<MovieBean> uptr__MovieBean = std::make_unique...
...
uptr__MovieBean->SetMovieTitle( row["MovieTitle"] );
uptr__MovieBean->SetYearReleased( row["YearReleased"] );
...
SendMessage( hwnd__MovieWindow, UWM_SendMovieBean, 0, (LPARAM) uptr__MovieBean->get() );
...
}
Fortunately, I have an advantage with SendMessage(): it won't end (releasing the std::unique_ptr) until the message handler returns, and the message handler's job is to clone the MovieBean.
MovieWindow::HandleUwmSendMovieBean( const HWND hwnd__MovieWindow, const UINT uint__WindowMessage, const WPARAM wParam, const LPARAM lParam )
{ UPTR__MovieBean = std::move( (*((MovieBean*) lParam).Clone() );
...
}
It seems the right way to do it is leave ownership of the std::unique_ptr with MovieSelected() until the actual moment of transfer by sending a reference to the handler, and using std::move on the reference.
MoviesWindow::MovieSelected( const unsigned int uint__MovieKey )
{ ...
SendMessage( hwnd__MovieWindow, UWM_SendMovieBean, 0, (LPARAM) &uptr__MovieBean );
...
}
But I cannot figure out how to get the reference out of lParam and into std::move. This would seem to be the one, but nope.
MovieWindow::HandleUwmSendMovieBean( const HWND hwnd__MovieWindow, const UINT uint__WindowMessage, const WPARAM wParam, const LPARAM lParam )
{ UPTR__NewMovieBean = std::move( reinterpret_cast<std::unique_ptr<MovieBean>*>( lParam ) );
...
}
I've tried every combination I can think of and ensured that the address sent is the address received and supplied to std::move. All I get are constant compiler errors (including a now-much-hated one about std::remove_reference), and crashes. Any insight would be appreciated.
SendMessage and unique_ptr are definitely not made for each other. I can give lots of hints here, but the best thing to do is to not be smuggling smart pointers through HWND messages.
I don't know what a UWM_SendMovieBean, but I'm guessing that's a custom windows message you either based of off WM_USER or RegisterWindowsMessage. So what you are really doing sounds like you are trying to signal another code component with SendMessage instead of a formal contract between the backing classes of both windows. It's not the worst thing ever to do this, but with a class as specialized as unique_ptr, it gets much harder to pull off.
The cheap and easy thing to do would be to have both windows share the row data structure that you have. Then your send message simply sends the uint__MovieKey as the WPARAM or LPARAM of your custom message.
But if you were on my team, and we were building this app together, I'd give you the crash course in Model-View-Presenter (and other MVC designs) that make these types of feature designs more maintainable.
I got the answer in two more tries:
MovieWindow::HandleUwmSendMovieBean( const HWND hwnd__MovieWindow, const UINT uint__WindowMessage, const WPARAM wParam, const LPARAM lParam )
{ UPTR__NewMovieBean = std::move( *((std::unique_ptr<MovieBean>*) lParam) );
...
}
Basically, sending the address of the std::unique_ptr<MovieBean> meant I was sending a pointer, so I needed to std::move(...) what the pointer was pointing to. It works fine.
This still seems sound to me: I'm leaving the MovieBean protected by a smart pointer while it's "in flight". It's effectively just a pass-by-reference that doesn't violate C++ Core Rule 33: Take a unique_ptr<widget>& parameter to express that a function reseats the widget.
The substantial problem in this usage is that my message handler is also the signal to read the MovieBean's copious information into the various CommonControls of the MovieWindow. Message handlers are supposed to be quick. The better approach is what #selbie suggested: the formal contract between the backing classes.

C++ Windows: Access same variable from main process and CallWndProc process

I have a single-file DLL that receives and stores a _bstr_t as a global variable, then sets a Windows hook for the WH_CALLWNDPROC procedure.
In the CallWndProc function, I attempt to read the _bstr_t, but it has no value.
I printed out the variable's address from both functions and they are different.
This is not surprising as I think that the CallWndProc function is called in a different process' thread.
My question is, what is the easiest and best way to share the variable between them?
I am trying to avoid having to use ATL COM to store it for inter-process access.
Example code:
// foo.cpp
#include <comutil.h>
static HHOOK g_hook = NULL;
static _bstr_t shared = "";
static LRESULT WINAPI CallWndProc(int nHookCode, WPARAM wParam, LPARAM lParam) {
if (nHookCode == 12345) {
// Do something with '_bstr_t shared'
shared += " bar";
return 0;
}
return CallNextHookEx(g_hook, nHookCode, wParam, lParam);
}
extern "C" __declspec(dllexport) void _stdcall Do(char* someStr, long handle) {
shared = someStr;
DWORD threadId = GetWindowThreadProcessId((HWND) handle, &process);
HINSTANCE hInst = GetModuleHandle("foo.dll");
g_hook = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, hInst, thread);
// Check value of '_bstr_t shared', or call a COM function to store it somewhere.
// However, the value of 'shared' does not include the string appended in CallWndProc.
}
Extra info:
DLL is called by Java using JNI.
DLL is built as a multi-threaded DLL.
I went with the ATL COM approach to act as a global store of values.
Not my ideal solution, but a workable one.
However, I think Hans Passant's comment on the question is a better way of doing it since it does not require a separate process to be running.

Using MFC, posting variable to thread along with message

I am using CWinThread. And I have made the main GUI send to the thread an array in LPARAM. Example, this code WORKS:
//On GUI
char *headData = "L1";
PostThreadMessage(threadID,SEND_HEAD, 0, (LPARAM)head);
On the thread:
void CMyThread::OnSendhead( WPARAM, LPARAM lParam){
char *head = (char*)lParam;
if (strcmp(head,"L1")==0){
//This line is reached.
}
return;
}
But when I make a little change here:
char *head = "L1"
unsigned char byteHead[3];
memcpy(byteHead, head, 3);
PostThreadMessage(threadID,SEND_HEAD, 0, (LPARAM)byteHead);
On the thread:
void CMyThread::OnSendhead( WPARAM, LPARAM lParam){
unsigned char* byteHead = (unsigned char*)lParam;
char head[3];
memcpy(head, byteHead,3);
head[3] = '\0';
if (strcmp(head,"L1")==0){
//This line is nerver reached.
}
return;
}
The line inside if is not reach. I have moved the code on thread to GUI for testing (without casting to LPARAM), and everthing works. So I guess I can't cast between lParam and unsigned char*? Why, and how can I do this? Thank you guys
PostMessage doesn't process the message immediately, but leaves it for the message loop to pick up later. If the data pointed to by lparam has been destroyed in the meantime, it's going to fail.
In your first example, you're passing a string literal. String literals tend to stay valid for the full lifetime of the program, so this is OK.
In the second example, you're using a local variable that presumably gets destroyed soon after you do the PostMessage.
To make this work, use SendMessage instead; it gets processed immediately. Or use a variable that is guaranteed to be valid until the message is processed.
With PostMessage or PostThreadMessage you should always use heap allocated memory to send data, as small as bool and in the message handler function you delete it. You can wrap a message in some struct, for example:
struct MyMsg
{
int msgCode; // specific to you, and you know underlying datatype
char buffer[1024]; // or have a `vector` or dynamic-array you'd manage
};
Sender:
MyMsg* msg = new MyMsg;
msg->msgCode = 0x1; // It's a string
strcpy_s(msg->buffer, "abc");
PostThreadMessage(threadID,SEND_HEAD, 0, (LPARAM)msg);
Receiver:
void CMyThread::OnSendhead( WPARAM, LPARAM lParam)
{
MyMsg* msg= (MyMsg*)lParam;
// use msg
delete msg;
}

Pointer Not Pointing Correctly?

I am running this code in a thread, assuming receivedPosts and td->window are valid:
std::vector<Post> *receivedPosts_n = new std::vector<Post>;
*receivedPosts_n = receivedPosts;
SendMessage(td->window, WM_TIMER, IDT_TIMER_FIND_NEW_POSTS_CALLBACK,
(LPARAM) receivedPosts_n);
I'm running this code at IDT_TIMER_FIND_NEW_POSTS_CALLBACK (hwnd is td->window):
case IDT_TIMER_FIND_NEW_POSTS_CALLBACK:
{
std::vector<Post> *currentPosts_ptr = (std::vector<Post> *)lParam;
//This vector turns up as undefined
std::vector<Post> currentPosts = *currentPosts_ptr;
}
break;
But the problem is that *currentPosts_ptr turns up as an invalid pointer, i.e. it points to random memory.
What is wrong with the pointer?
Thanks.
MSDN documentation says that for WM_TIMER message value of lParam is
A pointer to an application-defined callback function that was passed to the SetTimer function when the timer was installed.
If you need to send custom messages it is much better idea just to use WM_USER through 0x7FFF that were specially designed for this scenario.

Unitialized Class Calling Function, No exception. What is going on here?

Is this normal behavior; this never happened to me before. I assume it would cause an exception but why doesn't it here? Take a look.
CWindowsApplication::MsgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static CWindowApplication* pApp = NULL;
if (message == WM_NCCREATE)
{
//// retrieve Window instance from window creation data and associate
//pApp = reinterpret_cast(((LPCREATESTRUCT)lParam)->lpCreateParams);
//::SetWindowLong(hWnd, GWL_USERDATA, reinterpret_cast(pApp));
//pApp = reinterpret_cast(::GetWindowLong(hWnd, GWL_USERDATA));
}
pApp->WndProc(hWnd, message, wParam, lParam); // pApp = NULL, but it still works? I expected a exception of some sort.
}
But, when I change the class to something else I get the exception I was expecting.
What is going on here? Never in my 10+ years as an enthusiastic programmer have I ever came across something like this.
As long as WndProc is not virtual, the pointer technically doesn't need to be dereferenced at all in order to make the call. That's not to say it won't crash and burn when you try to use this (including calling any virtual function with an implicit this) inside WndProc, but non-virtual calls go by the type of the pointer, and don't need to touch the vtable (or any other instance member).
All you're doing is invoking undefined behaviour. That means that it can appear to work, it can crash, or whatever the compiler feels like making it do.