我正在尝试使用Rust的winapi包制作一个简单的托盘图标。之前我在C中做过,但是我不能让Rust满意。稍后我将包含C代码以展示我想要使用的
超级基础目标:
- 让它说话 - 将其设置为默认图标,如下所示
。这是最简单的;我可以以后弄清其他内置图标。
- 更新文字
- 程序完成时删除它
链接到Rust的winapi库(带搜索功能!)
Cargo.toml需要这个:
NOTIFYICONDATA
部分的内容。超级基础目标:
- 让它说话 - 将其设置为默认图标,如下所示
![default icon](https://i.imgur.com/1ZgDiXU.png)
链接到Rust的winapi库(带搜索功能!)
https://docs.rs/winapi/*/x86_64-pc-windows-msvc/winapi/um/wincon/fn.GetConsoleWindow.html
我不太了解Windows API,所以对我来说是一种陌生的语言,我只能根据其他示例中找到的语法进行匹配。请不要省略任何内容,因为我可能不知道隐含的内容(例如使用std::或其他内容)!Rust版本1.3.1
winapi包版本0.3.6
Windows 10
这是我目前编写的Rust代码(但无法正常工作!):
//-----Import Libraries (called crates)-----
extern crate winapi;
//-----Import Built-in Libraries (not called crates)-----
use std::process::Command; //use cmd.exe
use std::mem::size_of; //get size of stuff
fn main()
{
// to navigate calling with the winapi "crate" use the search function at link
// https://docs.rs/winapi/*/x86_64-pc-windows-msvc/winapi/um/wincon/fn.GetConsoleWindow.html
let hWnd = unsafe { winapi::um::wincon::GetConsoleWindow }; //gets the current console window handle
//System Tray Icon support - here it is
let WM_MYMESSAGE = winapi::um::winuser::WM_APP + 100; //prep WM_MYMESSAGE
let mut trayToolTip = "Tool tip words here"; //record tooltip words for the icon
let nid = winapi::um::shellapi::NOTIFYICONDATAA //thing that has info on window and system tray stuff in it
{
cbSize: size_of::<winapi::um::shellapi::NOTIFYICONDATAA>() as u32, //prep
hWnd: hWnd(), //links the console window
uID: 1001, //it's a number
uCallbackMessage: WM_MYMESSAGE, //whoknows should be related to click capture but doesn't so
//Couldn't find anything for WM_MYMESSAGE at all
hIcon: winapi::um::winuser::LoadIconA(winapi::shared::ntdef::NULL, winapi::um::winuser::IDI_APPLICATION), //icon idk
szTip: trayToolTip, //tooltip for the icon
uFlags: winapi::um::shellapi::NIF_MESSAGE | winapi::um::shellapi::NIF_ICON | winapi::um::shellapi::NIF_TIP, //who knows
};
let nidszTipLength: u64 = szTip.chars().count(); //gets the size of nid.szTip (tooltip length)
winapi::um::shellapi::Shell_NotifyIconA(winapi::um::shellapi::NIM_ADD, &nid); //shows the icon
let _ = Command::new("cmd.exe").arg("/c").arg("pause").status();
nid.szTip: "An updated tooltip is now here!"; //tooltip for the icon
//abs total guess hoping some Python . stuff that I see sometimes in Rust works here and maybe it gets a : instead of a = too
winapi::um::shellapi::Shell_NotifyIconA(winapi::um::shellapi::NIM_MODIFY, &nid); //updates system tray icon
let _ = Command::new("cmd.exe").arg("/c").arg("pause").status();
winapi::um::shellapi::Shell_NotifyIconA(winapi::um::shellapi::NIM_DELETE, &nid); //deletes system tray icon when done
let _ = Command::new("cmd.exe").arg("/c").arg("pause").status();
}
Cargo.toml需要这个:
[target.'cfg(windows)'.dependencies]
winapi = { version = "*", features = ["wincon","shellapi","ntdef"] }
以下是我试图模仿的 C 代码功能(不确定哪些库在哪里需要,因此我将大多数库都包含进去):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#define _WIN32_WINNT 0x0500 //must be before windows.h for mystical reasons such as widnows.h overwrites it with not right thing
#include <windows.h>
#include <shellapi.h> // make some system tray stuff go on
#define WM_MYMESSAGE (WM_USER + 1) //for that tray icon
int main()
{
HWND hWnd = GetConsoleWindow(); // from https://dev59.com/Fmgt5IYBdhLWcg3wygeb via Anthropos
NOTIFYICONDATA nid; //thing that has info on window and system tray stuff in it
nid.cbSize = sizeof(NOTIFYICONDATA); //prep
nid.hWnd = hWnd; //links the console window
nid.uID = 1001; //it's a number
nid.uCallbackMessage = WM_MYMESSAGE; //whoknows should be related to click capture but doesn't so
nid.hIcon = LoadIcon(NULL, IDI_APPLICATION); //icon idk
strcpy(nid.szTip, "Tool tip words here"); //tooltip for the icon
nid.szTip[19] = '\0'; //null at the end of it
nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; //who knows
size_t nidszTipLength = sizeof(nid.szTip) / sizeof(nid.szTip[0]); //gets the size of nid.szTip (tooltip length)
Shell_NotifyIcon(NIM_ADD, &nid); //shows the icon
system("pause");
strcpy(nid.szTip, "An updated tooltip is now here!"); //tooltip for the icon
Shell_NotifyIcon(NIM_MODIFY, &nid); //updates system tray icon
nid.szTip[31] = '\0'; //null at the end of it
system("pause");
Shell_NotifyIcon(NIM_DELETE, &nid); //deletes system tray icon when done
system("pause");
return 0;
}
uCallbackMessage = WM_MYMESSAGE
是怎么样的呢?从下面的 C 代码中可以看出,它只是WM_USER + 1
。考虑到窗口是一个控制台,WM_USER + X
应该由窗口类的创建者定义,这可能不是一个明智的选择,但嘿,这只是一个测试,不是吗? - rodrigoWM_MYMESSAGE
,所以这是计划中的额外问题。似乎WM_USER + X
只是一系列私有消息值 - 是否最好将其扔到WM_USER + 10000并避免未来千年的冲突(我看到最大值为7FFF == 32767)?当然,如果我正确理解了模糊的文档。 - user2403531WM_USER + X
。如果您使用别人的窗口类,则最好使用WM_APP + X
或甚至更好的是RegisterWindowMessage()
。 - rodrigoWM_APP
!从文档中可以看出,RegisterWindowMessage() 用于处理相同消息的2个或更多应用程序,因此我会避免使用 - 这里只有一个简单的应用程序。@Shepmaster 它对于请求范围来说是最小的。但是,我要和你说实话,它不会是 语法上有效 的,因为我不知道如何做到这一点。因此,我们在这里。Rust 中的'NOTIFYICONDATAA
需要提供我不想提供的输入 - 这是许多 语法奇妙 的障碍之一! - user2403531