none
控制台程序无法收到窗口消息 RRS feed

  • 问题

  • 最近在编一个程序,主要功能如下:
    1. 程序启动后,会在右下角通知区域显示一个图标;
    2. 鼠标点击或右击通知区域的图标使得窗口在最大化、最小化、常规大小之间切换。
    现在在通知区域添加图标已经做到了,但是鼠标右击通知区域图标却没有反应。我的程序如下所示:

    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <shellapi.h>
    #include "resource.h"
    
    #define NM_NOTIFYICON_CLICKED 100
    #define WST_MAXIMIZE 2
    #define WST_MINIMIZE 1
    #define WST_NORMAL 0
    
    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;
       BOOL shouldExit = FALSE;
       unsigned int windowStatus = WST_NORMAL;
    
       hWnd = GetConsoleWindow();
       addNotifyIcon(hWnd);
    
       while(!shouldExit)
       {
          GetMessage(&msg, NULL, 0, 0);
          printf("message peeked.\n");
          printf("%d\n", msg.message);
          switch (msg.message)
          {
             case NM_NOTIFYICON_CLICKED:
                printf("icon clicked.\n");
                switch(windowStatus)
                {
                   case WST_NORMAL:
                      ShowWindow(hWnd, SW_MAXIMIZE);
                      break;
    
                   case WST_MAXIMIZE:
                      ShowWindow(hWnd, SW_MINIMIZE);
                      break;
    
                   case WST_MINIMIZE:
                      ShowWindow(hWnd, SW_NORMAL);
                      break;
                }
                break;
          }
          DefWindowProc(hWnd, msg.message, msg.wParam, msg.lParam);
       }
    
       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"
    

    2019年1月1日 9:38

答案

  • 你好,

    感谢在微软论坛发帖提问。

    >>程序运行时发现收不到任何消息

    控制台程序往往是“线性的”,程序按特定顺序执行。 就程序而言,控制台管理器将处理显示,并且任何输入通常是同步的,程序停止并等待直到给出必要的输入。
    想要控制台程序接收消息,程序将需要有一个消息泵。 默认情况下,控制台应用程序没有消息泵。 您可以做的是在控制台应用程序内创建第二个工作线程,通过调用PostThreadMessage函数在此线程中抽取消息。 当然,您需要同步主控制台应用程序线程和工作线程之间共享的任何数据。

    或者你可以尝试使用Win32程序来实现这个功能。建议你可以参考下这个链接:https://blog.csdn.net/mycwq/article/details/14169991

    Best wishes,

    Jeanine Zhang


    • 已标记为答案 kingfoxy 2019年1月3日 11:06
    2019年1月2日 8:31
    版主

全部回复

  • 你好,

    感谢在微软论坛发帖提问。

    >>程序运行时发现收不到任何消息

    控制台程序往往是“线性的”,程序按特定顺序执行。 就程序而言,控制台管理器将处理显示,并且任何输入通常是同步的,程序停止并等待直到给出必要的输入。
    想要控制台程序接收消息,程序将需要有一个消息泵。 默认情况下,控制台应用程序没有消息泵。 您可以做的是在控制台应用程序内创建第二个工作线程,通过调用PostThreadMessage函数在此线程中抽取消息。 当然,您需要同步主控制台应用程序线程和工作线程之间共享的任何数据。

    或者你可以尝试使用Win32程序来实现这个功能。建议你可以参考下这个链接:https://blog.csdn.net/mycwq/article/details/14169991

    Best wishes,

    Jeanine Zhang


    • 已标记为答案 kingfoxy 2019年1月3日 11:06
    2019年1月2日 8:31
    版主
  • 谢谢你的回答,看来控制台程序实在太特殊,只能用在控制台程序中新建子窗口或者干脆用GUI程序才能实现我要的功能。这两种方法我都已经试成了。
    2019年1月3日 11:16