web-dev-qa-db-ja.com

ネイティブのGolangAPIを使用してWindowsにアイコントレイを追加する

Windowsシステムトレイの単純なアイコン以外にUIのない​​デーモンを開発しています。

他のパッケージに依存しないようにしたいので、syscallパッケージを使用して、必要な呼び出しを自分で実装しようとしています。

ドキュメンテーション

ライブラリ

実装

構造

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でどのような情報を提供するかわかりませんが、それがないと、実行可能ファイルがクラッシュします。
  • UFlagsDwState、およびDwStateMaskには、さまざまなプロジェクトで見つけた値があります。

私はそれが可能であることを知っています。 Golang WIKI は、メッセージボックスを呼び出すための実装を提供します。

14
Baptiste Donaux

NOTIFYICONDATAのフィールド

hWnd

hWndNOTIFYICONDATAフィールドは、MSDNで説明されているように、notifyicon自体に関連付けられたウィンドウハンドルを保持します。

hWnd

通知領域のアイコンに関連付けられた通知を受信するウィンドウへのハンドル。

ウィンドウが表示されていなくても、ウィンドウハンドルを関連付ける必要があることがわかりました。

uFlagsは、NOTIFYICONDATAのどのフィールドが単一のコマンドで有効かを示します。ご覧のとおり、NOTIFYICONDATAには多くのフィールドがあり、notifyiconのアイコンだけを変更する場合は、他のフィールドを変更せずにhIconフィールドのみを設定してから全体を渡すことができます。 NOTIFYICONDATAからShell_NotifyIcon。アイコンとメッセージの両方を変更したい場合は、NIF_MESSAGE|NIF_ICONに設定してください。

dwState

dwStateは、アイコンの表示を制御するために使用できます。 uFlagsNIF_STATEを指定し、dwStatedwStateMaskNIS_HIDDENを指定すると、notifyiconが非表示になります。

dwStateMask

そして、ほとんどの場合、dwStateMaskdwStateと同じに設定するだけです。 dwStateのどのビットがコマンドに有効であるかを示すだけです。

可能な値は、dwStateの値と同じです。

私が書いた完全な例はここにあります: https://github.com/hallazzang/go-windows-programming/tree/master/example/gui/notifyicon

1
hallazzang