社区应用 最新帖子 精华区 社区服务 会员列表 统计排行 道具中心
主题 : 这个。。我做的托盘有问题啊!!!
secondsen 离线
级别: 总版主
显示用户信息 
0  发表于: 2012-10-07   
来源于 通用编程 分类

这个。。我做的托盘有问题啊!!!

是这样。。
问题1:当前焦点在窗口上,右键托盘图标,托盘的菜单晃了一下(或者没反应),窗口的焦点失去了,(XP下)标题栏由天蓝色变成蓝灰色。。。。。再次右键托盘,菜单成功出现。。。
问题2:右键的托盘菜单出现之后,菜单不消失,除非(1)选择一个选项(2)单击窗口,使窗口获得焦点,无论是单击其他程序窗口还是桌面,无论左键还是右键,统统不好用,菜单就是不消失。。。

请问这两个问题怎么解决??

我用结果。。。代码显示出来不换行。。。只好不用那玩意排版了。。。

上代码。。就是以前WY发的程序代码改的。。封了个类。。


.h


复制代码
  1. #ifndef _MainWindow_H_
  2. #define _MainWindow_H_
  3. #include <Windows.h>
  4. #include "resource.h"
  5. // 系统托盘相关
  6. #define WM_USER_TRAY WM_USER+1
  7. #define IDM_OPEN 1
  8. #define IDM_HIDE 2
  9. #define IDM_SETUP 3
  10. #define IDM_EXIT 4
  11. class MainWindow
  12. {
  13. private:
  14. HWND hWnd;
  15. HINSTANCE hInstance;
  16. char cClassName[32];
  17. char cTitleName[32];
  18. int iWidth;
  19. int iHeight;
  20. NOTIFYICONDATAA sIconData;
  21. HMENU hPopupMenu;
  22. static MainWindow* pThis;
  23. public:
  24. MainWindow();
  25. ~MainWindow();
  26. bool Init(HINSTANCE hInst);
  27. bool Render();
  28. bool Update();
  29. bool Release();
  30. bool SetClassName(const char* cpcName);
  31. bool SetTitleName(const char* cpcName);
  32. bool SetWidgetSize(int width, int height);
  33. HMENU GetPopupMenu() {return hPopupMenu;}
  34. static LRESULT CALLBACK MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  35. };
  36. #endif




[ 此帖被secondsen在2014-05-19 10:54重新编辑 ]
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
相关话题
我就是你们的神,庶民们,追随我吧!跟着我一起拖后腿!
拖后腿的人发勋章!
secondsen 离线
级别: 总版主
显示用户信息 
1  发表于: 2012-10-07   
.cpp



复制代码
  1. #include "MainWindow.h"
  2. MainWindow::MainWindow():hWnd(0), hInstance(0), iWidth(0), iHeight(0), hPopupMenu(0)
  3. {
  4.     memset(cClassName, 0, 32);
  5.     memset(cTitleName, 0, 32);
  6.     memset(&sIconData, 0, sizeof(NOTIFYICONDATAA));
  7. }
  8. MainWindow::~MainWindow()
  9. {
  10.     Release();
  11. }
  12. bool MainWindow::Init(HINSTANCE hInst)
  13. {
  14.     if (hInst == 0) return false;
  15.     hInstance = hInst;
  16.     pThis = this;
  17.     // 创建窗口
  18.     WNDCLASSEXA wndClass;
  19.     wndClass.cbSize            = sizeof(wndClass);
  20.     wndClass.style            = CS_HREDRAW | CS_VREDRAW;
  21.     wndClass.lpfnWndProc    = &MainWindow::MsgProc;
  22.     wndClass.cbClsExtra        = 0;
  23.     wndClass.cbWndExtra        = 0;
  24.     wndClass.hInstance        = hInstance;
  25.     wndClass.hIcon            = NULL;//LoadIcon(hInstance, MAKEINTRESOURCE(IDI_NORMAL));
  26.     wndClass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  27.     wndClass.hbrBackground    = (HBRUSH)GetStockObject(WHITE_BRUSH);
  28.     wndClass.lpszMenuName    = NULL;//MAKEINTRESOURCE(IDC_DAHUAXY2);
  29.     wndClass.lpszClassName    = cClassName;
  30.     wndClass.hIconSm        = NULL;//LoadIcon(wndClass.hInstance, MAKEINTRESOURCE(IDI_SMALL));
  31.     RegisterClassExA(&wndClass);
  32.     RECT rcWnd = { 0, 0, iWidth, iHeight};
  33.     hWnd = CreateWindowExA(0,
  34.         cClassName,
  35.         cTitleName,//WND_TITLENAME
  36.         WS_OVERLAPPEDWINDOW,
  37.         (GetSystemMetrics(SM_CXSCREEN)-iWidth)/2,    // SM_CXSCREEN:以像素为单位的屏幕的宽度
  38.         (GetSystemMetrics(SM_CYSCREEN)-iHeight)/2,    // SM_CYSCREEN:以像素为单位的屏幕的高度
  39.         (rcWnd.right-rcWnd.left), (rcWnd.bottom-rcWnd.top),
  40.         NULL,
  41.         NULL,
  42.         hInstance,
  43.         NULL);
  44.     if (hWnd == 0)
  45.     {
  46.         UnregisterClassA(cClassName, hInst);
  47.         return false;
  48.     }
  49.     ShowWindow(hWnd, SW_NORMAL);
  50.     //ShowWindow(hWnd, SW_HIDE);
  51.     UpdateWindow(hWnd);
  52.     sIconData.cbSize = sizeof(NOTIFYICONDATAA);
  53.     sIconData.hWnd = hWnd;
  54.     sIconData.uID = IDI_ICON1;
  55.     sIconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
  56.     sIconData.uCallbackMessage = WM_USER_TRAY;
  57.     sIconData.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  58.     lstrcpyA(sIconData.szTip, "Desktop Widget made by secondsen / 2nDs");
  59.     Shell_NotifyIconA(NIM_ADD, &sIconData);
  60.     // 创建系统托盘右键弹出菜单
  61.     hPopupMenu = CreatePopupMenu();
  62.     AppendMenuA(hPopupMenu, MF_STRING, IDM_OPEN, "打开");
  63.     AppendMenuA(hPopupMenu, MF_STRING, IDM_HIDE, "隐藏");
  64.     AppendMenuA(hPopupMenu, MF_STRING, IDM_SETUP, "设置");
  65.     AppendMenuA(hPopupMenu, MF_STRING, IDM_EXIT, "退出");
  66.     return true;
  67. }
  68. bool MainWindow::Release()
  69. {
  70.     UnregisterClassA(cClassName, hInstance);
  71.     return true;
  72. }
  73. bool MainWindow::Render()
  74. {
  75. }
  76. bool MainWindow::Update()
  77. {
  78. }
  79. bool MainWindow::SetClassName(const char* cpcName)
  80. {
  81.     if (cpcName)
  82.     {
  83.         strcpy(cClassName, cpcName);
  84.         return true;
  85.     }
  86.     return false;
  87. }
  88. bool MainWindow::SetTitleName(const char* cpcName)
  89. {
  90.     if (cpcName)
  91.     {
  92.         strcpy(cTitleName, cpcName);
  93.         return true;
  94.     }
  95.     return false;
  96. }
  97. bool MainWindow::SetWidgetSize(int width, int height)
  98. {
  99.     if (width <= 1 || height <= 1) return false;
  100.     iWidth = width;
  101.     iHeight = height;
  102.     return true;
  103. }
  104. LRESULT MainWindow::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  105. {
  106.     switch (uMsg)
  107.     {
  108.     case WM_SIZE:
  109.         if (wParam == SIZE_MINIMIZED) ShowWindow(hWnd, SW_HIDE);
  110.         break;
  111.     case WM_COMMAND:
  112.         {
  113.             WORD hWord = HIWORD(wParam);
  114.             WORD lWord = LOWORD(wParam);
  115.             switch(lWord)
  116.             {
  117.             case IDM_OPEN:
  118.                 {
  119.                     // 隐藏系统托盘
  120.                     //SetSystemTray(&g_IconData, false);
  121.                     ShowWindow(hWnd, SW_SHOW);
  122.                     SendMessageA(hWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
  123.                 }
  124.                 break;
  125.             case IDM_EXIT:
  126.                 Shell_NotifyIconA(NIM_DELETE, &(pThis->sIconData));
  127.                 ShowWindow(hWnd, SW_HIDE);
  128.                 PostQuitMessage(0);
  129.                 break;
  130.             case IDM_HIDE:
  131.                 SendMessage(hWnd,WM_SYSCOMMAND,SC_MINIMIZE,0);
  132.                 break;
  133.             }
  134.         }
  135.         break;
  136.     case WM_USER_TRAY:
  137.         {
  138.             UINT msg = (UINT)lParam;
  139.             UINT id = (UINT)wParam;
  140.             if (id == IDI_ICON1)
  141.             {
  142.                 if (msg == WM_LBUTTONDOWN)
  143.                 {
  144.                     ShowWindow(hWnd, SW_SHOW);
  145.                     SendMessageA(hWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
  146.                 }
  147.                 // 当用户在气球提示上或托盘图标上单击鼠标(此时气球处于显示状态)时
  148.                 if (msg == NIN_BALLOONUSERCLICK)
  149.                 {
  150.                 }
  151.                 if (msg == WM_RBUTTONDOWN)
  152.                 {
  153.                     POINT pos;
  154.                     ::GetCursorPos(&pos);
  155.                     TrackPopupMenu(pThis->hPopupMenu, TPM_RIGHTALIGN, pos.x, pos.y, NULL, hWnd, NULL);
  156.                 }
  157.             }
  158.         }
  159.         break;
  160.     case WM_DESTROY:
  161.         Shell_NotifyIconA(NIM_DELETE, &(pThis->sIconData));
  162.         PostQuitMessage(0);
  163.         break;
  164.     }
  165.     return DefWindowProc(hWnd, uMsg, wParam, lParam);
  166. }
[ 此帖被secondsen在2014-05-19 10:54重新编辑 ]
我就是你们的神,庶民们,追随我吧!跟着我一起拖后腿!
拖后腿的人发勋章!
secondsen 离线
级别: 总版主
显示用户信息 
2  发表于: 2012-10-07   
main.cpp



复制代码
  1. #include "MainWindow.h"
  2. #include <malloc.h>
  3. MainWindow* MainWindow::pThis = 0;
  4. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int nCmdShow)
  5. {
  6.     MainWindow* pMainWindow = new MainWindow ;
  7.     pMainWindow->SetClassName("SetupWindow");
  8.     pMainWindow->SetTitleName("DesktopWidget");
  9.     pMainWindow->SetWidgetSize(800,600);
  10.     pMainWindow->Init(hInstance);
  11.     MSG msg;
  12.     memset(&msg, 0, sizeof(msg));
  13.     while (msg.message != WM_QUIT)
  14.     {
  15.         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  16.         {
  17.             TranslateMessage(&msg);
  18.             DispatchMessage(&msg);
  19.         }
  20.         else
  21.         {
  22.             // 帧开始
  23.             float timeInOneFps = 1000.0f/60.0f;    // 每秒60帧,则1帧就是约16毫秒
  24.             DWORD timeBegin = GetTickCount();
  25.             //MainLoop();
  26.             // 限帧
  27.             DWORD timeTotal = GetTickCount() - timeBegin;
  28.             if (timeTotal < timeInOneFps)
  29.             {
  30.                 Sleep(DWORD(timeInOneFps-timeTotal));
  31.             }
  32.         }
  33.     }
  34.     delete pMainWindow ;
  35.     return 1;
  36. }
[ 此帖被secondsen在2014-05-19 10:54重新编辑 ]
我就是你们的神,庶民们,追随我吧!跟着我一起拖后腿!
拖后腿的人发勋章!
secondsen 离线
级别: 总版主
显示用户信息 
3  发表于: 2012-10-07   
以上,完毕
我就是你们的神,庶民们,追随我吧!跟着我一起拖后腿!
拖后腿的人发勋章!
shawind 离线
级别: 分版主
显示用户信息 
4  发表于: 2012-10-10   
代码太多,不知道是怎么回事,还有我的系统是win7,没法判断。
所以重写了个小例子,随便看看吧。
用gcc 4.7.2编译的,不知到怎么回事,这个4.7.2中使用GetSystemMetrics总取不到正确的值,所以就显示在左上角了。

图片:gp.jpg
え~え~お!!!
shawind 离线
级别: 分版主
显示用户信息 
5  发表于: 2012-10-10   
代码就一个文件
复制代码
  1. #include <windows.h>
  2. #include <gdiplus.h>
  3. unsigned int iconmessage = RegisterWindowMessage("IconNotify");
  4. #define MYWM_ICON (WM_APP+100)
  5. HMENU popMenu;
  6. NOTIFYICONDATA nid;
  7. struct YY
  8. {
  9.     const char* szClassName;
  10.     HWND hwnd;
  11.     MSG messages;
  12.     WNDCLASSEX wincl;
  13.     ULONG_PTR gdiplusStartupToken;
  14.     YY() :szClassName("YY")
  15.     {}
  16.     ~YY()
  17.     {
  18.         Gdiplus::GdiplusShutdown(gdiplusStartupToken); //消毁gdi+
  19.     }
  20.     void InitWin(HINSTANCE hThisInstance)
  21.     {
  22.         //初始化gdi+
  23.         Gdiplus::GdiplusStartupInput gdiInput;
  24.         Gdiplus::GdiplusStartup(&gdiplusStartupToken,&gdiInput,NULL);
  25.         wincl.hInstance = hThisInstance;
  26.         wincl.lpszClassName = szClassName;
  27.         wincl.lpfnWndProc = WindowProcedure;
  28.         wincl.style = CS_DBLCLKS;
  29.         wincl.cbSize = sizeof (WNDCLASSEX);
  30.         wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  31.         wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
  32.         wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
  33.         wincl.lpszMenuName = NULL;
  34.         wincl.cbClsExtra = 0;
  35.         wincl.cbWndExtra = 0;
  36.         wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
  37.         if (!RegisterClassEx (&wincl))
  38.             return;
  39.         hwnd = CreateWindowEx (
  40.                    WS_EX_LAYERED|WS_EX_TOOLWINDOW|WS_EX_TOPMOST,
  41.                    szClassName,
  42.                    "YY Test",
  43.                    WS_OVERLAPPEDWINDOW,
  44.                    0,
  45.                    0,
  46.                    450,
  47.                    600,
  48.                    NULL,
  49.                    NULL,
  50.                    hThisInstance,
  51.                    NULL
  52.                );
  53.         ShowWindow (hwnd, SW_SHOWNORMAL);
  54.         MoveWindow(hwnd, 0, 0, 450, 600, TRUE);
  55.         SetPic(L"alice.png");
  56.         nid.cbSize = sizeof(NOTIFYICONDATA);
  57.         nid.hWnd = hwnd;
  58.         nid.uID = iconmessage;
  59.         nid.uFlags = NIF_ICON|NIF_MESSAGE;
  60.         nid.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  61.         nid.uCallbackMessage = MYWM_ICON;
  62.     }
  63.     int Run()
  64.     {
  65.         while (GetMessage (&messages, NULL, 0, 0))
  66.         {
  67.             TranslateMessage(&messages);
  68.             DispatchMessage(&messages);
  69.         }
  70.         return messages.wParam;
  71.     }
  72.     void SetPic(const wchar_t* fn)
  73.     {
  74.         RECT wndRect;
  75.         GetWindowRect(hwnd,&wndRect);
  76.         SIZE wndSize = {wndRect.right-wndRect.left, wndRect.bottom-wndRect.top};
  77.         HDC hdc = GetDC(hwnd);
  78.         HDC memDC = CreateCompatibleDC(hdc);
  79.         HBITMAP memBitmap = CreateCompatibleBitmap(hdc, wndSize.cx, wndSize.cy);
  80.         SelectObject(memDC,memBitmap);
  81.         Gdiplus::Image image(fn);
  82.         Gdiplus::Graphics graphics(memDC);
  83.         graphics.DrawImage(&image, 0, 0, wndSize.cx,wndSize.cy);
  84.         HDC screenDC = GetDC(NULL);
  85.         POINT ptSrc = {0,0};
  86.         BLENDFUNCTION blendFunction;
  87.         blendFunction.AlphaFormat = AC_SRC_ALPHA;
  88.         blendFunction.BlendFlags = 0;
  89.         blendFunction.BlendOp = AC_SRC_OVER;
  90.         blendFunction.SourceConstantAlpha = 255;
  91.         UpdateLayeredWindow(hwnd,screenDC,&ptSrc,&wndSize,memDC,&ptSrc,0,&blendFunction,2);
  92.         DeleteDC(memDC);
  93.         DeleteObject(memBitmap);
  94.         ReleaseDC(hwnd, hdc);
  95.         ReleaseDC(0, screenDC);
  96.     }
  97.     static LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  98.     {
  99.         switch (message)
  100.         {
  101.         case WM_CREATE:
  102.             popMenu = CreatePopupMenu();
  103.             AppendMenu(popMenu, MF_STRING, 1, "隐藏");
  104.             AppendMenu(popMenu, MF_STRING, 2, "恢复");
  105.             AppendMenu(popMenu, MF_STRING, 3, "关于");
  106.             AppendMenu(popMenu, MF_STRING, 4, "退出");
  107.             break;
  108.         case WM_RBUTTONDOWN:
  109.             POINT pt;
  110.             pt.x = LOWORD(lParam);
  111.             pt.y = HIWORD(lParam);
  112.             ClientToScreen(hwnd, &pt);
  113.             TrackPopupMenu(popMenu, TPM_RIGHTALIGN, pt.x, pt.y, 0, hwnd, NULL);
  114.             break;
  115.         case MYWM_ICON:
  116.             if(wParam == iconmessage)
  117.             {
  118.                 switch(lParam)
  119.                 {
  120.                 case WM_LBUTTONDBLCLK: //左双击
  121.                     ShowWindow(hwnd, SW_SHOWNORMAL);
  122.                     Shell_NotifyIcon(NIM_DELETE, &nid);
  123.                     break;
  124.                 case WM_RBUTTONDOWN: //右单击
  125.                     POINT pt;
  126.                     GetCursorPos(&pt);
  127.                     SetForegroundWindow(hwnd);
  128.                     TrackPopupMenu(popMenu, TPM_RIGHTALIGN, pt.x, pt.y, 0, hwnd, NULL);
  129.                     break;
  130.                 case WM_MOUSEMOVE: //悬停
  131.                     break;
  132.                 }
  133.             }
  134.             break;
  135.         case WM_COMMAND:
  136.             switch(LOWORD(wParam))
  137.             {
  138.             case 1:
  139.                 ShowWindow(hwnd, SW_HIDE);
  140.                 Shell_NotifyIcon(NIM_ADD, &nid);
  141.                 break;
  142.             case 2:
  143.                 ShowWindow(hwnd, SW_SHOWNORMAL);
  144.                 Shell_NotifyIcon(NIM_DELETE, &nid);
  145.                 break;
  146.             case 3:
  147.                 MessageBox(hwnd, "用gdi+实现透明不规则界面", "关于", MB_OK);
  148.                 break;
  149.             case 4:
  150.                 PostQuitMessage(0);
  151.                 break;
  152.             }
  153.             break;
  154.         case WM_DESTROY:
  155.             DestroyMenu(popMenu);
  156.             PostQuitMessage (0);
  157.             break;
  158.         default:
  159.             return DefWindowProc (hwnd, message, wParam, lParam);
  160.         }
  161.         return 0;
  162.     }
  163. };
  164. int WINAPI WinMain (HINSTANCE hThisInstance,
  165.                     HINSTANCE hPrevInstance,
  166.                     LPSTR lpszArgument,
  167.                     int nCmdShow)
  168. {
  169.     YY yy;
  170.     yy.InitWin(hThisInstance);
  171.     return yy.Run();
  172. }
附件: gp.zip (260 K) 下载次数:2
え~え~お!!!
shawind 离线
级别: 分版主
显示用户信息 
6  发表于: 2012-10-11   
原来不是GetSystemMetrics失灵,而是描画半透明窗口时由UpdateLayeredWindow 的第3个参数指定位置。前面的CreateWindowEx MoveWindow都没有作用了。
え~え~お!!!
secondsen 离线
级别: 总版主
显示用户信息 
7  发表于: 2012-10-11   
总之,我的问题解决了shawind大真实可靠的人哇
我就是你们的神,庶民们,追随我吧!跟着我一起拖后腿!
拖后腿的人发勋章!
描述
快速回复

认证码:

验证问题:
12-5=?,答案:7 正确答案:7
按"Ctrl+Enter"直接提交