控制台程序无法收到Windows消息

狐帝 2018-12-28 11:34:47
最近在编一个程序,主要功能如下:
1. 程序启动后,会在右下角通知区域显示一个图标;
2. 鼠标点击或右击通知区域的图标能弹出菜单。
现在在通知区域添加图标已经做到了,但是鼠标右击通知区域图标却没有反应。我的程序如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <shellapi.h>
#include "resource.h"

#define NM_NOTIFYICON_CLICKED 100

extern WINBASEAPI HWND WINAPI GetConsoleWindow();

HINSTANCE hInst;

BOOL addNotifyIcon(HWND hWnd)
{
BOOL result;
NOTIFYICONDATA nid;

nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uFlags = NIF_ICON | NIF_MESSAGE;
nid.uCallbackMessage = NM_NOTIFYICON_CLICKED;
hInst = (HINSTANCE)GetModuleHandle(NULL);
nid.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_NOTIFY_ICON));
result = Shell_NotifyIcon(NIM_ADD, &nid);

return result;
}

int main()
{
HWND hWnd;
MSG msg;
int wmId;
BOOL shouldExit = FALSE;

printf("Hello world!\n");
hWnd = GetConsoleWindow();
addNotifyIcon(hWnd);

while(!shouldExit)
{
// if (GetMessage(&msg, NULL, 0, 0) != 0)
if (PeekMessage(&msg, hWnd, 0, 0, PM_NOREMOVE))
{
printf("message peeked.\n");
switch(msg.message)
{
case WM_COMMAND:
wmId = LOWORD(msg.wParam);
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
shouldExit = TRUE;
break;

default:
return DefWindowProc(hWnd, msg.message, msg.wParam, msg.lParam);
}
break;

case NM_NOTIFYICON_CLICKED:
switch (LOWORD(msg.lParam))
{
case WM_CONTEXTMENU:
{

POINT const pt = { LOWORD(msg.wParam), HIWORD(msg.wParam) };
HMENU hMenu = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(IDR_POPUP_MENU)), 0);
// our window must be foreground before calling TrackPopupMenu or the menu will not disappear when the user clicks away
SetForegroundWindow(hWnd);
// respect menu drop alignment
UINT uFlags = TPM_RIGHTBUTTON;
if (GetSystemMetrics(SM_MENUDROPALIGNMENT) != 0)
{
uFlags |= TPM_RIGHTALIGN;
}
else
{
uFlags |= TPM_LEFTALIGN;
}

TrackPopupMenuEx(hMenu, uFlags, pt.x, pt.y, hWnd, NULL);
DestroyMenu(hMenu);

break;
}

case WM_LBUTTONDBLCLK:
ShowWindow(hWnd, SW_RESTORE);
SetForegroundWindow(hWnd);
break;

default:
break;
}
break;
}
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}

system("pause");

return 0;
}

程序运行时发现收不到任何消息,按理应该收到“NM_NOTIFYICON_CLICKED”消息才对。请各位大能帮忙解惑。万分感谢!
以下是资源文件的代码:
resource.h:
#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif

#define IDI_NOTIFY_ICON 101
#define IDR_POPUP_MENU 103
#define IDM_EXIT 40000


resource.rc:
// Generated by ResEdit 1.6.6
// Copyright (C) 2006-2015
// http://www.resedit.net

#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"

//
// Menu resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDR_POPUP_MENU MENU
{
POPUP "TrayMenu"
{
MENUITEM "E&xit", IDM_EXIT
}
}

//
// Icon resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDI_NOTIFY_ICON ICON "studyNotifyArea.ico"
...全文
154 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
狐帝 2019-01-03
  • 打赏
  • 举报
回复
引用 2 楼 metohang 的回复:
控制台程序应该是没有窗口句柄的,你获取的那个句柄本身是控制台窗口程序的,和你的程序貌似没多大关连。
还是去创建一个带窗口的程序,把窗口隐藏起来就行。

控制台程序也是有窗口的,可以通过窗口句柄获得窗口类名(ConsoleWindowClass),只不过是特殊的窗口,消息处理的方法大概跟GUI式程序大不一样,所以用常规的方法获取消息肯定不行。看来要想达到我的目的,只能用你提出的“创建一个带窗口的程序,把窗口隐藏起来”的方法。
metohang 2018-12-29
  • 打赏
  • 举报
回复
控制台程序应该是没有窗口句柄的,你获取的那个句柄本身是控制台窗口程序的,和你的程序貌似没多大关连。
还是去创建一个带窗口的程序,把窗口隐藏起来就行。
aabbabababaa 2018-12-29
  • 打赏
  • 举报
回复
C++么?没用过,来学习下。。。

18,124

社区成员

发帖
与我相关
我的任务
社区描述
Windows客户端使用相关问题交流社区
社区管理员
  • Windows客户端使用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧