为什么GetMessage在不发送任何消息的情况下退出我的程序
Why is GetMessage exiting my program without sending any message?
这是我的问题。我正在尝试创建一个仍然使用trayCon和Hooks的无窗口程序,所以我需要使用消息(或者不使用?),但当我使用它们时,我不知道如何在杀死进程时释放内存。甚至类的析构函数也不会被调用。这是一个主要测试:
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;
}
正如我在文档中看到的,GetMessage()
调用应该返回0或更少才能退出,但当我运行它,然后关闭它时,我只得到"Start."日志,我不明白为什么。如果没有办法通过这个循环,那么我怎么能调用我的析构函数呢?我的trayCon确实有一个窗口,它没有接收到任何消息,也许我应该将其作为参数传递给GetMessage()
?
PS:我的项目使用trayCons和Hooks,当我用相同的调试打印运行它时,它只显示一次4个第一个字符串,但在关闭时什么都不显示,甚至连"end."字符串都不显示。
编辑:我的(可怕的)trayCon创作:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
OutputDebugStringW(L"Message!n");
switch (uMsg)
{
case WM_DESTROY:
OutputDebugStringW(L"Close message receivedn");
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 menun");
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 windown");
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 notifIconn");
return false;
}
return true;
}
GetMessage()
在收到窗口/线程消息或有消息要合成之前不会返回。在您显示的代码中,您没有创建任何窗口,也没有向自己发布任何线程消息,也没有创建任何需要消息循环的挂钩,所以GetMessage()
没有什么可做的。它被无限期地阻止了。这就是为什么你只看到你的启动消息,而在你强行终止程序之前,其他事情都不会发生。
由于您打算显示系统托盘图标,因此需要一个窗口,即使只是一个隐藏的窗口,也可以接收有关用户与该图标交互的通知。您的GetMessage()
循环将处理在与循环相同的线程中创建的所有窗口的消息,因为您将hWnd
参数设置为NULL,而不是特定的窗。一旦你创建了托盘图标窗口,循环就会收到相应的消息。然后,您可以为您的托盘图标提供一个弹出菜单,其中包含一个项目,该项目将在单击时退出您的消息循环,从而允许您优雅地退出WinMain()
,调用析构函数等。
GetMessage
在发生错误时返回-1。所以你一般应该做while != 0
。但如果您没有看到"结束",那么您的应用程序可能会崩溃。
https://msdn.microsoft.com/en-us/library/windows/desktop/ms644936(v=vs.85).aspx
- 在没有太多条件句的情况下,我如何避免被零除
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 在未初始化映射的情况下,将值插入到映射的映射中
- 是默认情况下分配给char数组常量的值
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在已经使用Git的情况下减少编译时间
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 如何在不返回 C++ 值的情况下退出 int 函数?
- 程序在没有输入的情况下退出,它有基本的,驱动的类属性初始化问题
- 如何在不退出和失去断点的情况下重新加载重新编译的二进制文件
- 为什么GetMessage在不发送任何消息的情况下退出我的程序
- 在另一个线程正在运行的情况下退出应用程序时出错
- getchar 有什么问题(因为程序在没有检查的情况下退出循环)
- 多线程服务器在不等待客户端连接的情况下退出
- 在没有goto的情况下退出嵌套循环
- 在没有c++11的情况下,使用boost标记线程退出的正确方法是什么
- 在不使用pkill的情况下优雅地退出程序的最佳方式
- 从vi运行各种c或cpp开发任务"就像在不退出vi的情况下运行cpp程序一样。
- 如何在没有输入的情况下退出c++程序