I am working on an App which has Multiple Threads waiting for different inputs from DLLs and Serial Ports.
I want to add a functionality that before machine going to Sleep, I have to unload certain DLL and On waking up have to Re-load the DLL.
For this, I need to get notified on Sleep and Wake up.
I found many files about doing in C# but I want to do this in C++.
I tried using this code Project but could not capture any event. I removed everything related to Window Paint and All that as I do not need it's GUI and kept only main message loop (The While loop in the main)
EDIT:-
I am using this as my main loop:-
// Start the message loop.
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
To be frank I have copied this from CodeProject, and Made only one Modification i.e. Checked GetMessage(..) != 0 from a MSDN Article.
Am I missing something?
Or anyother Solution??
I am using VS2010 and programming in C++
Thanks in Advance!
Try handling the WM_POWERBROADCAST message
Here's sample code that should work. Apparently you do need to create a window otherwise you don't receive the messages. The sample creates a hidden window to achieve this.
static long FAR PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_POWERBROADCAST)
{
//Do something
return TRUE;
}
else
return DefWindowProc(hWnd, message, wParam, lParam);
}
int _tmain(int argc, _TCHAR* argv[])
{
WNDCLASS wc = {0};
// Set up and register window class
wc.lpfnWndProc = WindowProc;
wc.lpszClassName = _T("SomeNameYouInvented");
RegisterClass(&wc);
HWND hWin = CreateWindow(_T("SomeNameYouInvented"), _T(""), 0, 0, 0, 0, 0, NULL, NULL, NULL, 0);
BOOL bRet;
MSG msg;
while( (bRet = GetMessage( &msg, hWin, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
}
Related
I have a program (not a DLL) that creates a thread, and in this thread I create a hook using SetWindowsHookExW() to get keyboard events. I also have a global variable that I can use to turn off this thread.
The thing is that I don't know how to release the hooks and continue the function/thread, because it also does some cleanup. When I use UnhookWindowsHookEx() and place breakpoints in the following lines, the breakpoints are never reached.
The example on MSDN is "broken", because it needs an app.h; Also, every tutorial on the Internet, either input systems, keylogger, etc, they talk about DLLs, that I'm not using, and some of them implement a wrapper Unhook function but they never use it.
What I've been trying:
#include <Windows.h>
bool bContinue;
wchar_t vkTecla;
LRESULT CALLBACK KeyboardCallBack(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode >= 0)
{
vkTecla = ((KBDLLHOOKSTRUCT*)lParam)->vkCode;
if (wParam == WM_KEYDOWN)
{
// Do stuff here
}
// ...
}
if (bContinue)
{
UnhookWindowsHookEx(hHook);
return 0;
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
void MainThread(HANDLE hfile)
{
hHook = SetWindowsHookExW(WH_KEYBOARD_LL, KeyboardCallBack, 0, 0);
MSG msg;
// I tested these 3 cases
/*************/
while(GetMessageW(&msg, 0, 0, 0));
// Or
GetMessageW(&msg, 0, 0, 0);
/*************/
while(GetMessageW(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
/*************/
while (bContinue)
{
// PeekMessage(...);
GetMessageW(&msg, 0, 0, 0);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// In this example I would remove the other Unhook function
UnhookWindowsHookEx(hHook);
/*************/
CloseHandle(hfile);
}
If I do the first example, the:
while(GetMessageW(&msg, 0, 0, 0));
and check bContinue inside of the callback function;
or use the third one:
while (bContinue)
{
GetMessageW(&msg, 0, 0, 0);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWindowsHookEx(hHook);
And place a breakpoint in CloseHandle(hArquivo);, when I make the bContinue = false, this line never gets executed.
So the question is:
Where do I place UnhookWindowsHookEx()? Is it inside the Callback function, or somewhere else?
When I release the hook, will the thread continue? Because at the moment, I don't get the program to stop at breakpoints past the unhooking that have some cleanup.
GetMessage() is a blocking function. It will not exit until the message queue of the calling thread has a message available for the caller to process.
But, you are running this code in a worker thread that has no UI of its own. And, although hooks do use messaging internally, they are private to the hook implementation and the caller of (Peek|Get)Message() will never see them. So, unless the other threads in your app are posting messages to this worker thread via PostThreadMessage(), there are simply no messages for GetMessage() to return to your code. That is why your loop doesn't break.
So, you need to either:
use PeekMessage() instead of GetMessage() so you can monitor your bContinue variable in between polls of the message queue:
#include <Windows.h>
bool bContinue = TRUE;
LRESULT CALLBACK KeyboardCallBack(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode >= 0)
{
wchar_t vkTecla = ((KBDLLHOOKSTRUCT*)lParam)->vkCode;
if (wParam == WM_KEYDOWN)
{
// Do stuff here
}
// ...
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
void MainThread(HANDLE hfile)
{
HHOOK hHook = SetWindowsHookExW(WH_KEYBOARD_LL, KeyboardCallBack, 0, 0);
MSG msg;
while (bContinue)
{
if (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
Sleep(10);
}
UnhookWindowsHookEx(hHook);
CloseHandle(hfile);
}
...
// to stop the thread:
bContinue = FALSE;
change bContinue to be a HANDLE returned by CreateEvent(), and then use MsgWaitForMultipleObjects() in a loop to monitor that event and the message queue at the same time, calling (Get|Peek)Message() only when it reports the message queue has messages to process. Then you can use SetEvent() when you want to trigger the loop to end.
#include <Windows.h>
HANDLE hStop = CreateEvent(NULL, TRUE, FALSE, NULL);
LRESULT CALLBACK KeyboardCallBack(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode >= 0)
{
wchar_t vkTecla = ((KBDLLHOOKSTRUCT*)lParam)->vkCode;
if (wParam == WM_KEYDOWN)
{
// Do stuff here
}
// ...
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
void MainThread(HANDLE hfile)
{
HHOOK hHook = SetWindowsHookExW(WH_KEYBOARD_LL, KeyboardCallBack, 0, 0);
MSG msg;
while (MsgWaitForMultipleObjects(1, &hStop, FALSE, INFINITE, QS_ALLINPUT) == (WAIT_OBJECT_0 + 1))
{
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
UnhookWindowsHookEx(hHook);
CloseHandle(hfile);
}
...
// to stop the thread:
SetEvent(hStop);
I created a window with Win32s, I wish it could handle incoming messages from another thread in addition to typical windows messages.
I'm using this piece of code:
while (dataAvailable || GetMessage(&msg, nullptr, 0, 0))
{
// if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
if (dataAvailable == true)
{
cout << "My thread message/signal!" << endl;
dataAvailable = false;
}
else
{
//Windows message
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
the "DataAvailable" is an atomic bool that I set when I would like pass a my own message to win32 app/windows.
This don't work well.
It is possible to do this?
I suggest you to use standard messages. Register your own new message and use PostMessage from another thread to your main window thread.
I base my example code on standard windows sample code: https://github.com/microsoft/Windows-classic-samples/blob/main/Samples/Win7Samples/begin/LearnWin32/HelloWorld/cpp/main.cpp
In this code I add a standard std::thread :
// ...
auto th1 = std::thread([=] {
const UINT WM_EX_SOME_SPECIALINTERNALMESSAGE = ::RegisterWindowMessage(L"SomeSpecialInternalMessage");
for (int n = 0; n < 10; ++n) {
PostMessage(hwnd, WM_EX_SOME_SPECIALINTERNALMESSAGE, 0, 0);
Sleep(1000);
}
});
// Run the message loop.
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
th1.join();
As you see in this code, WM_EX_SOME_SPECIALINTERNALMESSAGE is a custom windows message. Its posted every second to you main window proc: WindowProc. To receive it modify WindowProc:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
const UINT WM_EX_SOME_SPECIALINTERNALMESSAGE = ::RegisterWindowMessage(L"SomeSpecialInternalMessage");
if(uMsg == WM_EX_SOME_SPECIALINTERNALMESSAGE) {
OutputDebugStringW(L"WM_EX_SOME_SPECIALINTERNALMESSAGE\n");
}
// ...
I'm realize the console win32 app does not quit cleanly so I'm trying to switch to message only windows instead. I'm starting the app from another process and trying to kill it cleanly.
This is the win32 app, it spawns a calc.exe on startup and on clean shutdown, it should kill the calc.exe
LRESULT CALLBACK WindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_USER: PostQuitMessage (0); break;
default: return DefWindowProc (hWnd, message, wParam, lParam);break;
}
return 0;
}
int CALLBACK WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int show)
{
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof (WNDCLASSEX);
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = L"WindowClass1";
RegisterClassEx (&wc);
HWND hWnd = CreateWindowEx (NULL,
L"WindowClass1", // name of the window class
L"Our First Windowed Program", // title of the window
0,
//WS_OVERLAPPEDWINDOW, // window style
300,300,500,400,
HWND_MESSAGE,
//NULL, // parent window, NULL
NULL, hInstance, NULL);
//ShowWindow (hWnd, SW_HIDE);
PROCESS_INFORMATION pi;
CreateWindowProcess (L"calc.exe", pi); // helper class to createprocess
MSG msg = { 0 };
while (true)
{
if (PeekMessage (&msg, 0, 0, 0, PM_REMOVE))
{
if (WM_QUIT == msg.message)
break;
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
// terminate the spawn process, this is not called cleanly
TerminateProcess (pi.hProcess, 0);
return (int)msg.wParam;
}
I made a c# program to start/kill the app cleanly (the calc.exe gets destroyed) by sending a WM_QUIT/WM_CLOSE/WM_USER message . The Win32 App does not receive messages unless the window is visible (WS_OVERLAPPED and ShowWindow true). PostMessage WM_QUIT is received but the calc.exe does not get destroyed, meaning it is not a clean exit.
How should I kill it cleanly from C# app?
class Program
{
[DllImport ("user32.dll")]
public static extern bool PostMessage (IntPtr hwnd, uint msg, int wparam, int lparam);
[DllImport ("User32.dll")]
public static extern int SendMessage (IntPtr hWnd, uint uMsg, int wParam, int lParam);
static void Main (string [] args)
{
try
{
Process myProcess;
myProcess = Process.Start ("My.exe");
// Display physical memory usage 5 times at intervals of 2 seconds.
for (int i = 0; i < 3; i++)
{
if (myProcess.HasExited) break;
else
{
// Discard cached information about the process.
myProcess.Refresh ();
Thread.Sleep (4000);
Console.WriteLine ("Sending Message");
const int WM_USER = 0x0400;
const int WM_CLOSE = 0xF060; // Command code for close window
const int WM_QUIT = 0x0012;
// Received only when windows is visible
//int result = SendMessage (myProcess.MainWindowHandle, WM_USER, 0, 0);
// not clean exit
PostMessage (myProcess.MainWindowHandle, WM_QUIT, 0, 0);
// doesn't receive
SendMessage (myProcess.MainWindowHandle, WM_QUIT, 0, 0);
}
}
}
}
}
Processes on Windows do not really have a "MainWindow". Process.MainWindowHandle is C# making a guess, and it guesses by looking to see if the process in question has a window with focus - which will only find visible windows. Use FindWindowEx to find the window handle you want to close.
Next, when a window closes, it does not automatically try to exit the current threads message loop. You need to handle WM_DESTROY to call PostQuitMessage.
In your message loop use GetMessage rather than PeekMessage if you are not doing any other work as PeekMessage returns immediately if there are no messages meaning the application thread will never have an opportunity to sleep.
With these changes in place you should be fine to simply post a WM_CLOSE to the valid window handle as it will be destroyed, post itself a WM-QUIT message to exit the message loop, and terminate the calc process properly.
For some reason after I close this window my program wont exit and goes into an infinite loop. The solution to this problem seems to be changing GetMessage(&message, handel, 0, 0) to GetMessage(&message, NULL, 0, 0). However I don't understand why this is. Can somebody please explain. Also I don't see why I call UpdateWindow(handel) since the window will show without it.
#include <iostream>
#include <Windows.h>
using namespace std;
LRESULT CALLBACK EventHandler(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, PSTR args, int cmd)
{
MSG message;
HWND handel;
WNDCLASS win_class;
win_class.style = CS_HREDRAW | CS_VREDRAW;
win_class.cbClsExtra = 0;
win_class.cbWndExtra = 0;
win_class.lpszClassName = "Window";
win_class.hInstance = inst;
win_class.hbrBackground = GetSysColorBrush(COLOR_3DDKSHADOW);
win_class.lpszMenuName = NULL;
win_class.lpfnWndProc = EventHandler;
win_class.hCursor = LoadCursor(NULL, IDC_ARROW);
win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
RegisterClass(&win_class);
handel = CreateWindow(win_class.lpszClassName, "Window", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 350, 250, NULL, NULL, inst, NULL);
ShowWindow(handel, cmd);
UpdateWindow(handel);
//Loop does not end.
while(GetMessage(&message, handel, 0, 0))
{
cout << "LOOP" << endl;
DispatchMessage(&message);
}
return WM_QUIT;
}
LRESULT CALLBACK EventHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static long long count = 0;
count++;
cout << "CALL #" << count << endl;
if(msg == WM_DESTROY)
{
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
WM_QUIT is not sent to any window, just placed in the thread's message queue with no HWND, that's why it doesn't match your filter.
Take a look at GetMessage and PostQuitMessage in MSDN
If the parameter hWnd of GetMessage function is NULL, GetMessage retrieves messages for any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL.
The PostQuitMessage function posts a WM_QUIT message to the thread's message queue, not to the current window.
Here's a good opportunity to exercise your "search-the-MSDN-documentation" abilities:
First, let's look up the documentation for WM_QUIT:
Indicates a request to terminate an application, and is generated when
the application calls the PostQuitMessage function. This message
causes the GetMessage function to return zero.
...
The WM_QUIT message is not associated with a window and therefore will
never be received through a window's window procedure. It is retrieved
only by the GetMessage or PeekMessage functions.
Then, let's look up the documentation for GetMessage():
Retrieves a message from the calling thread's message queue. The
function dispatches incoming sent messages until a posted message is
available for retrieval.
...
hWnd [in, optional] Type: HWND
A handle to the window whose messages are to be retrieved. The window
must belong to the current thread.
If hWnd is NULL, GetMessage retrieves messages for any window that
belongs to the current thread, and any messages on the current
thread's message queue whose hwnd value is NULL (see the MSG
structure). Therefore if hWnd is NULL, both window messages and thread
messages are processed.
Therefore, you want to use NULL as the window handle for GetMessage(), not handel, since WM_QUIT is not associated with any window.
There's plenty more information about how Windows programs typically handle messages also from MSDN.
As the side note, the message for window close events is WM_CLOSE, which in turn causes your window to be destroyed by default. WM_DESTROY means your window is already on it's way to being destroyed. So if you want to intercept the close event (say to ask your user to save any changes), you would handle the WM_CLOSE event.
Also, as shown in the GetMessage() documentation, you should actually have your GetMessage() loop look like this:
BOOL bRet;
while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Because GetMessage() can actually return 1, 0, or -1 (despite it returning a BOOL).
Recently I came about a strange difference between the two Win32 API calls "PostMessage" and "SendNotifyMessage" (at least noticed on Win7 64bit SP1):
An owned top-level window of another process seems not to receive messages broadcasted (HWND_BROADCAST) with "PostMessage" while it receives messages broadcasted with "SendNotifyMessage" in its WndProc.
The sent message have been registered with the help of a call to "RegisterWindowMessage".
Even using Spy++, I cannot see the message arriving when using "PostMessage". In addition, I want to mention, that if I send the message directly to the specific HWND with "PostMessage", it arrives as expected. So it looks like the windows-internal implementation of "PostMessage" just skips my window when iterating for execution of the broadcast.
Reading the respective MSDN documentation, I cannot see any statement about this difference and I am wondering if this is a bug in PostMessage or in SendNotifyMessage and if I can rely on SendNotifyMessage to continue to show this behavior in future versions of Windows.
So does someone have a plausible explanation why the both functions treat the broadcasts differently in this situation?
In addition, I would want to ask if there is any way to still use PostMessage to broadcast to an owned top-level window, because I would prefer to post the message because I would prefer to not skip the message queue (which is what SendNotifyMessage does).
In case you are curious why I want to reach a top-level owned window: in WPF, windows are hidden from the taskbar (Window.ShowInTaskbar property) by making them owned top-level windows with a hidden owner window.
Thanks a lot in advance for any ideas or comments on this topic.
Attachment: here a sample showing the behavior ... simply build it, and start it two times ... the second process should make a message show up in the first one.
Here is also a link to the complete solution including a build EXE: Link to the complete VS solution
#include <windows.h>
#include <stdio.h>
#include <string>
#include <vector>
HWND hwndMain = NULL;
HWND ownerHwnd = NULL;
std::vector<std::string> theOutput;
UINT MyRegisteredMessage1 = 0;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc = NULL;
if (message == MyRegisteredMessage1 && wParam != (WPARAM) hwndMain)
{
if (lParam == (LPARAM) 1)
theOutput.push_back("Got a 'MyRegisteredMessage1' via PostMessage");
if (lParam == (LPARAM) 2)
theOutput.push_back("Got a 'MyRegisteredMessage1' via SendNotifyMessage");
InvalidateRect(hwndMain, NULL, TRUE);
}
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
for(size_t i = 0, pos = 0; i < theOutput.size(); ++i, pos += 20)
TextOutA(hdc, 0, pos, theOutput[i].c_str(), theOutput[i].size());
EndPaint (hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK WndProcHidden(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg;
BOOL bRet;
WNDCLASSA wc;
UNREFERENCED_PARAMETER(lpszCmdLine);
if (!hPrevInstance)
{
wc.style = 0;
wc.lpfnWndProc = (WNDPROC) WndProcHidden;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon((HINSTANCE) NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);;
wc.lpszMenuName = "MainMenu";
wc.lpszClassName = "MyOwnerWindowClass";
if (!RegisterClassA(&wc))
return FALSE;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.lpszClassName = "MyOwnedWindowClass";
if (!RegisterClassA(&wc))
return FALSE;
}
ownerHwnd = CreateWindowA("MyOwnerWindowClass", "OwnerWindow",
WS_OVERLAPPEDWINDOW, 0, 0, 800, 400, (HWND) NULL,
(HMENU) NULL, hInstance, (LPVOID) NULL);
hwndMain = CreateWindowA("MyOwnedWindowClass", "OwnedWindow",
WS_OVERLAPPEDWINDOW, 0, 0, 800, 400, ownerHwnd,
(HMENU) NULL, hInstance, (LPVOID) NULL);
// only show the "real" window
ShowWindow(hwndMain, nCmdShow);
UpdateWindow(hwndMain);
MyRegisteredMessage1 = RegisterWindowMessageA("MyRegisteredMessage1");
char infoText[256];
_snprintf_s(infoText, 256,
"HWND = %X, registered message code for 'MyRegisteredMessage1' = %d",
hwndMain, MyRegisteredMessage1);
theOutput.push_back(infoText);
InvalidateRect(hwndMain, NULL, TRUE);
PostMessage(HWND_BROADCAST, MyRegisteredMessage1, (WPARAM) hwndMain, (LPARAM) 1);
Sleep(1000);
SendNotifyMessageA(HWND_BROADCAST, MyRegisteredMessage1, (WPARAM) hwndMain, (LPARAM) 2);
while( (bRet = ::GetMessage( &msg, NULL, 0, 0 )) != 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
You may need to register your message using RegisterWindowMessage() -- see the Remarks section of this MSDN article
Just adding this here for info..
I was able to get around this issue in c# by registering an IMessageFilter object on the Application level. PreFilterMessage on this object will receive the message and I can handle it from there.
public class FooMessageFilter : IMessageFilter
{
uint UM_FOO = 0;
public event EventHandler OnFoo;
public FooMessageFilter()
{
UM_FOO = Win32.RegisterWindowMessage("UM_FOO");
}
public bool PreFilterMessage(ref Message m)
{
if(m.Msg == UM_FOO)
{
if(OnFoo != null)
OnFoo(this, new EventArgs());
return true;
}
return false;
}
}
I then added this message filter to the Application context in my owned top-level form's constructor.
public partial class Form1 : Form
{
private FooMessageFilter fooFilter = new FooMessageFilter();
public Form1()
{
InitializeComponent();
// Register message filter
Application.AddMessageFilter(fooFilter);
// Subscribe to event
fooFilter.OnFoo += HandleFoo;
}
private void HandleFoo(object o, EventArgs e)
{
MessageBox.Show("Foo!");
}
}
From there it was just a matter of hooking up events in my top-level window to the message filter. This was necessary because of the need to adhere to current architecture, and the message originating from a third party process.
The documentation page(s) for PostMessage() mention that integrity level restrictions apply:
Starting with Windows Vista, message posting is subject to UIPI. The thread of a process can post messages only to message queues of threads in processes of lesser or equal integrity level.
There is no mention of such restrictions on SendNotifyMessage(). Since you don't check the return value of either, you could be running into that, and you wouldn't know it.