• win32进阶之路:程序托盘图标+右键弹出菜单


       开场白

        本次介绍两个非常棒且实用的技巧:程序托盘图标和右键弹出菜单,效果如下图。

        程序托盘图标用了迅雷的图标,右键点击时候会弹出三个选项的菜单。

        程序托盘图标设置

        我会用尽可能清晰明了的步骤介绍方式来讲述,我假设大家已经动手写了属于自己的windows窗体,刚学习win32的朋友可以看一下我之前的博客,有介绍如何从头创建属于自己的第一个windows窗口,也可以直接参照本文末尾贴出的完整代码做一些参考。如果大家觉得其他方式更好或者对讲述不理解的可以评论或者发送给我的邮箱believing_dan@hotmail.com,QQ382128698. 

            步骤1:声明托盘图标对象并给关键成员赋值。

            步骤2:通知windows在右下角区域添加图标。

            步骤3:处理托盘图标的左键点击和右键点击消息。

            步骤1/2的代码: 

            void NotifySwitch(HWND hWND,TCHAR operation[4])
    {
    if(!strncmp(operation, TEXT("MIN"), 3))
    {
                    //声明变量并初始化
    NOTIFYICONDATA nID = {};
                    //关联的托盘图标资源,图标需要是16*16或者32*32像素的                                                       
    nID.hIcon = (HICON)LoadImage(NULL, TEXT("notify.ico"), IMAGE_ICON, 0, 0, LR_LOADFROMFILE);     
    //托盘图标的提示语,即鼠标放在上面会弹出的提示
                    strncpy_s(nID.szTip, TEXT("自制锁屏软件卖萌中"), sizeof(TEXT("自制锁屏软件卖萌中")));          
    //托盘图标关联的窗口
                    nID.hWnd = hWND;                                                                               
    //应用程序只有一个托盘图标的话可以随便设
                    nID.uID = 1;                                                                                     
    //托盘图标的类型,详解见MSDN 
                    nID.uFlags = NIF_GUID | NIF_ICON | NIF_MESSAGE | NIF_TIP;                                         
    //托盘图标关联的消息ID,托盘的左击和右击消息的消息ID就是它
                    nID.uCallbackMessage = WM_MINMAXNotify;                                                            
    //通知windows添加一个托盘图标,看参数就知道啦
                    Shell_NotifyIcon(NIM_ADD, &nID);                                                               
    }

            步骤3的代码,即如何处理托盘关联的消息。

            再次假设大家已经有了自己的windows窗体,完整代码参考本文最后贴出的代码。    

    case WM_MINMAXNotify:
    switch(lparam)
    {
    case WM_LBUTTONDOWN:
    MessageBox(NULL, TEXT("Recv notify icon message"), TEXT("notify"), MB_ICONHAND);
    break;
    case WM_RBUTTONDOWN:
    POINT pt;
    GetCursorPos(&pt);
    HMENU hMenu;
    hMenu = CreatePopupMenu();
    AppendMenu(hMenu, MF_STRING , IDM_FIR, "秘籍");
    AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
    AppendMenu(hMenu, MF_STRING, IDM_SEC, TEXT("打怪"));
    AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
    AppendMenu(hMenu, MF_STRING, IDM_THI, TEXT("补给"));
    AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
    TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, pt.x, pt.y, NULL, hwnd, NULL);
    break;
    }
    break;

      是不是太简单了!呵呵,就这么简单,在windows的窗体处理函数中增加一个case处理托盘关联的消息,鼠标对托盘的动作可以通过lparam参数来获取,这里我处理了左键和右键的单击消息,左键单击弹出一个提示框,右键单击托盘......好嘛,我已经漏题了,没错,右键的处理就是添加一个弹出菜单。

        增加右键弹出菜单 

    步骤1:创建一个PopMenu对象。

            步骤2:为新增加的弹出菜单增加菜单项。

        步骤3:显示新增加的菜单。

    步骤4:处理菜单项的消息。 

    又用4步就搞定了这么实用的技巧,是不是小激动呢?尽管前面已经漏题了,还是讲一下代码吧。

             创建一个弹出菜单的HMENU句柄,菜单分很多种,需要用对应的创建API

    HMENU hMenu = CreatePopupMenu();

       插入一个菜单项,并给菜单项起一个字符名称,这里必须设置菜单项的类型是MF_STRING,并给菜单项关联一个ID

    AppendMenu(hMenu, MF_STRING , IDM_FIR, "秘籍");

    插入一个分隔符,让菜单更好看,啥?没错,就是更好看一点

     AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);

     

    对比一下前面的截图,不一样的地方就是分隔符在搞鬼了。

    获取到当前的鼠标位置并显示刚创建的弹出菜单,这里有一个小技巧,为什么不把弹出菜单和当前窗口关联起来呢,这样点选菜单后就会自动销毁菜单了。 

    POINT pt;

    GetCursorPos(&pt);  

    TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, pt.x, pt.y, NULL, hwnd, NULL);

    弹出菜单的响应消息属于WM_COMMAND命令系列,通过wparam可以区分点击的菜单项。

    case WM_COMMAND:

    switch (wparam)

    {

    case IDM_FIR:

    MessageBox(NULL, TEXT("Recv popup menu idm_fir message"), TEXT("Popup"), MB_ICONINFORMATION);

    break;

    case IDM_SEC:

    MessageBox(NULL, TEXT("Recv popup menu idm_sec message"), TEXT("Popup"), MB_ICONASTERISK);

    break;

    case IDM_THI:

    MessageBox(NULL, TEXT("Recv popup menu idm_thi message"), TEXT("Popup"), MB_ICONEXCLAMATION);

    break;

    default:

    break;

    }

    break;

      源代码链接说明:完整代码是还在完善中的一个锁屏软件代码,可能要费些功夫去寻找一下本文介绍的功能,当然也可能会对大家有一些额外的帮助,下面是锁屏软件的截图,中间的妹子可是会眨眼卖萌的哟,子窗口会逐渐漂移,碰到屏幕边缘会反弹回来。

     

    锁屏软件持续更新中,欢迎大家关注我的博客。

    代码及示例 http://download.csdn.net/detail/hd770c/6920757   

  • 相关阅读:
    按ECS退出全屏模式
    【转】vux (scroller)上拉刷新、下拉加载更多
    vux组件样式大合集
    【转】vue+axios 前端实现登录拦截(路由拦截、http拦截)
    可拖动元素拖动到另外一个元素位置的时候,互相交换位置
    优秀文章链接
    获取kendoDatePicker里的正确日期格式
    给kendo ui 里的控件绑定事件的方法
    有人物联网调试过程
    开源cms系统siteServer的使用记录
  • 原文地址:https://www.cnblogs.com/learn-my-life/p/3548722.html
Copyright © 2020-2023  润新知