CreateWindow托盘图标

创建托盘图标是在Windows操作系统中常见的需求,它能使应用程序在后台运行,并通过系统托盘显示图标和提供相关功能。本文将介绍如何使用CreateWindow函数创建托盘图标,并提供相关的方法和案例说明。

一、CreateWindow函数

CreateWindow函数是Windows API中常用的窗口创建函数之一,它能创建一个新的顶级窗口,并返回该窗口的句柄。在创建托盘图标时,我们可以使用CreateWindow函数创建一个无窗口的窗口作为托盘图标的容器。

CreateWindow函数的原型如下:

HWND CreateWindow(

LPCTSTR lpClassName,

LPCTSTR lpWindowName,

DWORD dwStyle,

int x,

int y,

int nWidth,

int nHeight,

HWND hWndParent,

HMENU hMenu,

HINSTANCE hInstance,

LPVOID lpParam

);

其中,lpClassName参数指定了窗口类的名字,我们可以使用一个自定义的名字。dwStyle参数指定了窗口的样式,我们可以设置为WS_POPUP | WS_DISABLED,表示创建一个无边框且不可操作的窗口。x、y参数确定了窗口的位置,nWidth、nHeight参数确定了窗口的大小。hWndParent参数指定了窗口的父窗口,我们可以设为NULL,表示创建的窗口是顶级窗口。hMenu参数可以设为NULL,表示窗口没有菜单。hInstance参数指定了应用程序的实例句柄,我们可以通过GetModuleHandle(NULL)获取当前应用程序的实例句柄。lpParam参数可以设为NULL,表示没有额外的参数传递给窗口过程。

二、创建托盘图标的步骤

1. 创建一个无窗口的窗口

首先,我们需要使用CreateWindow函数创建一个无窗口的窗口作为托盘图标的容器。代码如下:

```cpp

HWND hWnd = CreateWindow(

_T("TrayIconClass"),

_T("TrayIcon"),

WS_POPUP | WS_DISABLED,

0,

0,

0,

0,

NULL,

NULL,

hInstance,

NULL

);

```

2. 设置窗口扩展样式

接下来,我们需要设置窗口的扩展样式,使窗口能够显示在系统托盘区域。代码如下:

```cpp

DWORD dwMessage;

NOTIFYICONDATA nid = {0};

nid.cbSize = sizeof(NOTIFYICONDATA);

nid.hWnd = hWnd;

nid.uID = 1;

nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;

nid.uCallbackMessage = WM_TRAYICON;

nid.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON));

lstrcpy(nid.szTip, _T("TrayIcon"));

dwMessage = RegisterWindowMessage(_T("TrayIconMessage"));

Shell_NotifyIcon(NIM_ADD, &nid);

```

在上述代码中,我们创建了一个NOTIFYICONDATA结构体,并设置了相应的字段。其中,cbSize字段指定了结构体的大小,hWnd字段是窗口的句柄,uID字段是托盘图标的ID,uFlags字段指定了需要显示的图标、消息和提示文字,uCallbackMessage字段指定了托盘图标消息的回调函数,hIcon字段是图标的句柄,szTip字段是提示文字。最后,我们使用Shell_NotifyIcon函数将托盘图标添加到系统托盘区域。

3. 处理托盘图标的消息

最后,我们需要在消息循环中处理托盘图标的消息,以响应用户的操作。代码如下:

```cpp

MSG msg;

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

if (msg.message == dwMessage)

{

if (msg.lParam == WM_LBUTTONUP)

{

// 左键单击托盘图标的处理代码

}

else if (msg.lParam == WM_RBUTTONUP)

{

// 右键单击托盘图标的处理代码

}

}

}

```

在上述代码中,我们使用GetMessage函数从消息队列中获取消息,然后使用TranslateMessage函数将消息翻译成相应的键盘消息,再使用DispatchMessage函数分发消息给相应的窗口过程进行处理。在处理托盘图标的消息时,我们通过判断消息的lParam参数来确定用户进行的是左键单击还是右键单击。

三、案例说明

下面以一个简单的计时器应用程序为例,演示如何创建托盘图标。

```cpp

#include

#define WM_TRAYICON (WM_USER + 1)

#define ID_TRAYICON 1

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

switch (uMsg)

{

case WM_CREATE:

{

// 创建托盘图标

NOTIFYICONDATA nid = {0};

nid.cbSize = sizeof(NOTIFYICONDATA);

nid.hWnd = hWnd;

nid.uID = ID_TRAYICON;

nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;

nid.uCallbackMessage = WM_TRAYICON;

nid.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON));

lstrcpy(nid.szTip, _T("计时器"));

Shell_NotifyIcon(NIM_ADD, &nid);

break;

}

case WM_TRAYICON:

{

if (lParam == WM_RBUTTONUP)

{

// 右键单击托盘图标弹出菜单

HMENU hMenu = CreatePopupMenu();

AppendMenu(hMenu, MF_STRING, ID_TRAYICON, _T("退出"));

POINT pt;

GetCursorPos(&pt);

SetForegroundWindow(hWnd);

TrackPopupMenu(hMenu, TPM_RIGHTALIGN | TPM_BOTTOMALIGN, pt.x, pt.y, 0, hWnd, NULL);

PostMessage(hWnd, WM_NULL, 0, 0);

DestroyMenu(hMenu);

}

break;

}

case WM_COMMAND:

{

if (LOWORD(wParam) == ID_TRAYICON)

{

// 退出程序

Shell_NotifyIcon(NIM_DELETE, &(NOTIFYICONDATA{sizeof(NOTIFYICONDATA), hWnd, ID_TRAYICON}));

PostQuitMessage(0);

}

break;

}

case WM_DESTROY:

{

// 销毁窗口

Shell_NotifyIcon(NIM_DELETE, &(NOTIFYICONDATA{sizeof(NOTIFYICONDATA), hWnd, ID_TRAYICON}));

PostQuitMessage(0);

break;

}

default:

return DefWindowProc(hWnd, uMsg, wParam, lParam);

}

return 0;

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)

{

// 注册窗口类

WNDCLASSEX wcex = {0};

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.lpfnWndProc = WindowProc;

wcex.hInstance = hInstance;

wcex.lpszClassName = _T("TrayIconClass");

ATOM atom = RegisterClassEx(&wcex);

// 创建窗口

HWND hWnd = CreateWindow(

_T("TrayIconClass"),

_T("TrayIcon"),

WS_POPUP | WS_DISABLED,

0,

0,

0,

0,

NULL,

NULL,

hInstance,

NULL

);

// 处理消息

MSG msg;

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return msg.wParam;

}

```

上述例子中,定义了一个TrayIconClass窗口类,并在主函数中注册窗口类并创建一个无窗口的窗口。在窗口过程中,当接收到WM_CREATE消息时,会创建一个托盘图标,并在接收到WM_TRAYICON消息时处理托盘图标的操作。当用户右键单击托盘图标时,会弹出一个菜单,点击菜单项“退出”时,程序会退出并销毁窗口。

总结

使用CreateWindow函数创建托盘图标需要创建一个无窗口的窗口,并设置相应的窗口扩展样式,然后通过Shell_NotifyIcon函数将窗口添加到系统托盘区域。同时,需要在消息循环中处理托盘图标的消息,以响应用户的操作。以上就是使用CreateWindow函数创建托盘图标的方法和案例说明,希望对您有所帮助。 如果你喜欢我们三七知识分享网站的文章, 欢迎您分享或收藏知识分享网站文章 欢迎您到我们的网站逛逛喔!https://www.ynyuzhu.com/

点赞(57) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部