Windowsシステムトレイの単純なアイコン以外にUIのないデーモンを開発しています。
他のパッケージに依存しないようにしたいので、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 は、メッセージボックスを呼び出すための実装を提供します。
NOTIFYICONDATA
のフィールドhWnd
のNOTIFYICONDATA
フィールドは、MSDNで説明されているように、notifyicon自体に関連付けられたウィンドウハンドルを保持します。
hWnd
通知領域のアイコンに関連付けられた通知を受信するウィンドウへのハンドル。
ウィンドウが表示されていなくても、ウィンドウハンドルを関連付ける必要があることがわかりました。
uFlags
は、NOTIFYICONDATA
のどのフィールドが単一のコマンドで有効かを示します。ご覧のとおり、NOTIFYICONDATA
には多くのフィールドがあり、notifyiconのアイコンだけを変更する場合は、他のフィールドを変更せずにhIcon
フィールドのみを設定してから全体を渡すことができます。 NOTIFYICONDATA
からShell_NotifyIcon
。アイコンとメッセージの両方を変更したい場合は、NIF_MESSAGE|NIF_ICON
に設定してください。
dwState
は、アイコンの表示を制御するために使用できます。 uFlags
にNIF_STATE
を指定し、dwState
とdwStateMask
にNIS_HIDDEN
を指定すると、notifyiconが非表示になります。
そして、ほとんどの場合、dwStateMask
をdwState
と同じに設定するだけです。 dwState
のどのビットがコマンドに有効であるかを示すだけです。
可能な値は、dwStateの値と同じです。
私が書いた完全な例はここにあります: https://github.com/hallazzang/go-windows-programming/tree/master/example/gui/notifyicon