func (w *Window) AddTrayIcon(ico Icon, tip string) { if w.trayIconData != nil { return } w.trayIconData = &w32.NOTIFYICONDATA{ /* Size */ uint32(unsafe.Sizeof(*w.trayIconData)), /* Wnd */ w.handle, /* ID */ 1, /* Flags */ w32.NIF_MESSAGE | w32.NIF_ICON | w32.NIF_TIP | w32.NIF_SHOWTIP, /* CallbackMessage */ WM_TRAYICON, /* Icon */ w32.HICON(ico), /* Tip */ [128]uint16{}, /* State */ 0, /* StateMask */ 0, /* Info */ [256]uint16{}, /* TimeoutOrVersion */ w32.NOTIFYICON_VERSION_4, /* InfoTitle */ [64]uint16{}, /* InfoFlags */ 0, /* Item */ w32.GUID{}, /* BalloonIcon */ 0, } tipbuf := syscall.StringToUTF16(tip) copy(w.trayIconData.Tip[:], tipbuf) w32.Shell_NotifyIcon(w32.NIM_ADD, w.trayIconData) }
func wndProc(hwnd w32.HWND, msg uint32, wParam, lParam uintptr) uintptr { wnd, err := findWndByHandle(hwnd) if err != nil { return w32.DefWindowProc(hwnd, msg, wParam, lParam) } switch msg { case w32.WM_SIZE: if wParam == w32.SIZE_MINIMIZED { if wnd.OnMinimize != nil { wnd.OnMinimize(wnd) } // We don't want to send OnSizeChanged notification then return 0 } else if wParam == w32.SIZE_MAXIMIZED { if wnd.OnMaximize != nil { wnd.OnMaximize(wnd) } } w := int(w32.LOWORD(uint32(lParam))) h := int(w32.HIWORD(uint32(lParam))) if wnd.OnSizeChanged != nil { wnd.OnSizeChanged(wnd, Vector{w, h}) } return 0 case w32.WM_KILLFOCUS: if wnd.OnBlur != nil { wnd.OnBlur(wnd) } return 0 case w32.WM_COMMAND: notifCode := int(w32.HIWORD(uint32(wParam))) controlId := uintptr(w32.LOWORD(uint32(wParam))) controlHandle := w32.HWND(lParam) if controlHandle == 0 { if notifCode != 0 { return 0 } // Menu item click mi, err := findMenuItemById(controlId) if err == nil && mi.OnClick != nil { mi.OnClick(mi) } } else { // Control notification dispatchControlEvent(controlHandle, notifCode) } return 0 case WM_TRAYICON: switch w32.LOWORD(uint32(lParam)) { case w32.WM_LBUTTONUP: if wnd.OnTrayClick != nil { wnd.OnTrayClick(wnd) } case w32.WM_RBUTTONUP: if wnd.OnTrayRightClick != nil { wnd.OnTrayRightClick(wnd) } } return 0 case w32.WM_CLOSE: if wnd.OnClose == nil || wnd.OnClose(wnd) { wnd.Destroy() } return 0 case w32.WM_DESTROY: if wnd.trayIconData != nil { w32.Shell_NotifyIcon(w32.NIM_DELETE, wnd.trayIconData) } if wnd.OnDestroy != nil { wnd.OnDestroy(wnd) } else { Exit() } return 0 default: return w32.DefWindowProc(hwnd, msg, wParam, lParam) } }