here is my problem. I'm trying to create a windowless program that still uses trayIcon and Hooks, so I need to use messages (or not?) but when I use them, I don't know how to free my memory when I kill my process. Even classes's destructors aren't called. Here is a test main:
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR pCmdLine, int nCmdShow)
{
MSG msg;
OutputDebugStringW(L"Start.\n");
while (GetMessageW(&msg, NULL, NULL, NULL) > 0)
{
OutputDebugStringW(L"one.\n");
TranslateMessage(&msg);
OutputDebugStringW(L"two.\n");
DispatchMessage(&msg);
OutputDebugStringW(L"three.\n");
}
OutputDebugStringW(L"end.\n");
return 0;
}
As I saw in the doc, the GetMessage()
call should return 0 or less to exit, but when I run it, and then shut it down, I get only the "Start." log, and I don't understand why. And if there is no way to get through this loop, then how can i call my destructors? I do have a window for my trayIcon that doesn't receive any message, maybe i should pass it as parameter to GetMessage()
?
PS: my project uses trayIcons and Hooks, and when I run it with the same debug prints, it display once the 4 first strings, but nothing at shutdown, not even the "end." string.
EDIT: my (terrible) trayIcon creation:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
OutputDebugStringW(L"Message!\n");
switch (uMsg)
{
case WM_DESTROY:
OutputDebugStringW(L"Close message received\n");
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
EndPaint(hwnd, &ps);
}
case WM_RBUTTONUP:
{
OutputDebugStringW(L"Trying to open Context menu\n");
POINT const pt = { LOWORD(wParam), HIWORD(wParam) };
break;
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
bool CreateNotifyIcon(HINSTANCE& hInstance)
{
NOTIFYICONDATA notif = {};
static const wchar_t class_name[] = L"ExtendClass";
WNDCLASSEX wx = {};
wx.cbSize = sizeof(WNDCLASSEX);
wx.lpfnWndProc = WindowProc;
wx.hInstance = hInstance;
wx.lpszClassName = class_name;
RegisterClassEx(&wx);
HWND win = CreateWindowEx(0, class_name, L"Windows Extend", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (win == NULL)
OutputDebugStringW(L"failed to create window\n");
ZeroMemory(¬if, sizeof(NOTIFYICONDATA));
notif.cbSize = sizeof(NOTIFYICONDATA);
notif.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
// Need to find a non-busy uID
notif.uID = 44421;
notif.hWnd = win;
StringCchCopy(notif.szTip, ARRAYSIZE(notif.szTip), L"Access Windows Extend options.");
StringCchCopy(notif.szInfo, ARRAYSIZE(notif.szInfo), L"Access Windows Extend options.");
StringCchCopy(notif.szInfoTitle, ARRAYSIZE(notif.szInfoTitle), L"Windows Extend");
notif.hIcon = (HICON)LoadImage(NULL, L"./Luma.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);
if (!Shell_NotifyIcon(NIM_ADD, ¬if))
{
OutputDebugStringW(L"failed to create notifIcon\n");
return false;
}
return true;
}