Ответ 1
Вот полный рабочий пример: https://github.com/hallazzang/go-windows-programming/tree/master/example/gui/notifyicon
Я занимаюсь разработкой демона без пользовательского интерфейса, кроме простого значка в системном окне Windows.
Я не хотел бы иметь никаких зависимостей от каких-либо других пакетов, поэтому я пытаюсь использовать пакет syscall
и самостоятельно выполнять необходимые вызовы.
Shell_NotifyIcon
в shell32.dll
.Shell_NotifyIconW
(склонение Unicode), но реализация является частичной.Построен с помощью документации xilp/systray.
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 дает реализацию для вызова окна сообщения.
Вот полный рабочий пример: https://github.com/hallazzang/go-windows-programming/tree/master/example/gui/notifyicon
NOTIFYICONDATA
Поле hWnd
в NOTIFYICONDATA
содержит дескриптор окна, связанный с самим уведомлением, как указано в MSDN:
HWND
Дескриптор окна, которое получает уведомления, связанные со значком в области уведомлений.
Я обнаружил, что необходимо связать дескриптор окна, даже если окно не видно.
uFlags
сообщает, какие поля NOTIFYICONDATA
действительны в одной команде.
Как вы видите, в NOTIFYICONDATA
много полей, и если вы собираетесь изменить только значок уведомления, вы можете оставить другие поля без изменений и установить только поле hIcon
, а затем передать весь NOTIFYICONDATA
в Shell_NotifyIcon
. ].
Если вы хотите изменить значок и сообщение, просто установите для него значение NIF_MESSAGE|NIF_ICON
.
dwState
можно использовать для управления видимостью значков. Если вы укажете NIF_STATE
для uFlags
и NIS_HIDDEN
для dwState
и dwStateMask
, уведомление будет скрыто.
И в большинстве случаев просто установите dwStateMask
так же, как dwState
. Он просто сообщает, какой бит dwState
действителен для команды:
Возможные значения такие же, как для dwState.
Вы можете найти полный пример, который я написал здесь: https://github.com/hallazzang/go-windows-programming/tree/master/example/gui/notifyicon