除了Windows系统中的简单图标外,我还开发了一个没有UI的守护进程。
我希望不依赖任何其他软件包,因此我尝试使用syscall
软件包并自行实施必要的调用。
shell32.dll
中的Shell_NotifyIcon
函数。Shell_NotifyIconW
(Unicode declination),但实现是部分的。使用xilp/systray documentation构建。
type HANDLE uintptr
type HICON HANDLE
type HWND HANDLE
type GUID struct {
Data1 uint32
Data2 uint16
Data3 uint16
Data4 [8]byte
}
type NOTIFYICONDATA struct {
CbSize uint32
HWnd HWND
UID uint32
UFlags uint32
UCallbackMessage uint32
HIcon HICON
SzTip [128]uint16
DwState uint32
DwStateMask uint32
SzInfo [256]uint16
UVersion uint32
SzInfoTitle [64]uint16
DwInfoFlags uint32
GuidItem GUID
}
const (
NIM_ADD = 0x00000000
NIM_MODIFY = 0x00000001
NIM_DELETE = 0x00000002
NIM_SETVERSION = 0x00000004
NIF_MESSAGE = 0x00000001
NIF_ICON = 0x00000002
NIF_TIP = 0x00000004
NIF_STATE = 0x00000008
NIF_HIDDEN = 0x00000001
)
package main
import (
"log"
"syscall"
"unsafe"
)
func main() {
shell32 := syscall.MustLoadDLL("shell32.dll")
Shell_NotifyIcon := shell32.MustFindProc("Shell_NotifyIconW")
iconData := NOTIFYICONDATA{
HWnd: 0,
UFlags: NIF_MESSAGE | NIF_STATE,
DwState: NIF_HIDDEN,
DwStateMask: NIS_HIDDEN,
}
iconData.CbSize = uint32(unsafe.Sizeof(iconData))
ret, _, _ := Shell_NotifyIcon.Call(
NIM_ADD,
uintptr(unsafe.Pointer(&iconData)),
)
if ret == 0 {
log.Println("Failed")
return
}
// Do anything, like open a HTTP server to keep the program running
http.ListenAndServe(":8080", nil)
}
HWnd
中要提供哪些信息,但没有它,可执行文件会崩溃。UFlags
,DwState
和DwStateMask
包含我在不同项目中找到的值。我知道这是可能的; Golang WIKI提供了一个调用消息框的实现。
答案 0 :(得分:1)
NOTIFYICONDATA
hWnd
的 NOTIFYICONDATA
字段包含一个与notifyicon本身关联的窗口句柄:
hWnd
用于接收与通知区域中的图标相关联的通知的窗口的句柄。
我发现即使窗口不可见,也有必要关联一个窗口句柄。
uFlags
告诉NOTIFYICONDATA
的哪些字段在单个命令中有效。
如您所见,NOTIFYICONDATA
中有很多字段,如果您仅要更改notifyicon的图标,则可以保留其他字段不变,仅设置hIcon
字段,然后传递整个{{ 1}}至NOTIFYICONDATA
。
如果要同时更改图标和消息,只需将其设置为Shell_NotifyIcon
。
NIF_MESSAGE|NIF_ICON
可用于控制图标的可见性。如果为dwState
指定NIF_STATE
,为uFlags
和NIS_HIDDEN
指定dwState
,则会使notifyicon隐藏。
在大多数情况下,只需将dwStateMask
设置为与dwStateMask
相同。它只是告诉dwState
的哪一位对命令有效:
可能的值与dwState的值相同。
您可以在这里找到我写的完整示例:https://github.com/hallazzang/go-windows-programming/tree/master/example/gui/notifyicon