Instantly share code, notes, and snippets.
Created
November 15, 2022 03:15
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save CarsonSlovoka/4752ddc18064000d05d19f93ad24f02c to your computer and use it in GitHub Desktop.
create popup menu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "github.com/CarsonSlovoka/go-pkg/v2/w32" | |
| "log" | |
| "syscall" | |
| "unsafe" | |
| ) | |
| func ExampleUser32DLL_CreatePopupMenu() { | |
| user32dll := w32.NewUser32DLL() | |
| gdi32dll := w32.NewGdi32DLL() | |
| kernel32dll := w32.NewKernel32DLL() | |
| var ( | |
| hIcon w32.HICON | |
| iInfo w32.ICONINFO | |
| ) | |
| { | |
| hIcon, _ = user32dll.LoadIcon(0, w32.MakeIntResource(w32.IDI_QUESTION)) | |
| /* | |
| hIcon = w32.HICON(user32dll.MustLoadImage( | |
| 0, | |
| "testdata/img/golang.ico", | |
| w32.IMAGE_ICON, | |
| 0, 0, | |
| w32.LR_LOADFROMFILE|w32.LR_DEFAULTSIZE|w32.LR_SHARED, | |
| )) | |
| */ | |
| if !user32dll.GetIconInfo(hIcon, &iInfo) { | |
| return | |
| } | |
| // Remember to release when you are not using the HBITMAP. | |
| defer func() { | |
| _ = gdi32dll.DeleteObject(w32.HGDIOBJ(iInfo.HbmColor)) | |
| _ = gdi32dll.DeleteObject(w32.HGDIOBJ(iInfo.HbmMask)) | |
| }() | |
| } | |
| // Create Menu | |
| var hMenu w32.HMENU | |
| { | |
| hMenu = user32dll.CreatePopupMenu() | |
| _, _ = user32dll.AppendMenu(hMenu, w32.MF_STRING, 1023, "Open") | |
| var menuItemInfo w32.MENUITEMINFO | |
| pMsg, _ := syscall.UTF16PtrFromString("Hello") | |
| menuItemInfo = w32.MENUITEMINFO{ | |
| CbSize: uint32(unsafe.Sizeof(menuItemInfo)), | |
| FMask: w32.MIIM_BITMAP | | |
| w32.MIIM_ID | | |
| w32.MIIM_STRING, | |
| WID: 1024, | |
| DwTypeData: pMsg, | |
| HbmpItem: iInfo.HbmColor, | |
| } | |
| _, _ = user32dll.SetMenuItemInfo(hMenu, 1024, false, &menuItemInfo) | |
| _, _ = user32dll.AppendMenu(hMenu, w32.MF_STRING, 1025, "Exit program") | |
| defer func() { | |
| if ok, errno := user32dll.DestroyMenu(hMenu); !ok { | |
| log.Printf("%s\n", errno) | |
| } | |
| }() | |
| } | |
| ch := make(chan w32.HWND) | |
| go func(chanWin chan<- w32.HWND) { | |
| // define WNDPROC | |
| wndProcFuncPtr := syscall.NewCallback(w32.WNDPROC(func(hwnd w32.HWND, uMsg w32.UINT, wParam w32.WPARAM, lParam w32.LPARAM) w32.LRESULT { | |
| switch uMsg { | |
| case w32.WM_DESTROY: | |
| log.Println("WM_DESTROY") | |
| user32dll.PostQuitMessage(0) | |
| return 0 | |
| case w32.WM_RBUTTONDOWN: | |
| log.Println("WM_RBUTTONDOWN") | |
| // Show the menu | |
| curHwnd := user32dll.GetForegroundWindow() | |
| user32dll.SetForegroundWindow(curHwnd) | |
| var pos w32.POINT | |
| if ok, errno := user32dll.GetCursorPos(&pos); !ok { | |
| fmt.Printf("%s", errno) | |
| } | |
| _, _ = user32dll.TrackPopupMenu(hMenu, w32.TPM_LEFTALIGN, pos.X, pos.Y, 0, curHwnd, nil) | |
| _, _ = user32dll.PostMessage(curHwnd, w32.WM_NULL, 0, 0) | |
| case w32.WM_COMMAND: | |
| id := w32.LOWORD(uint32(wParam)) | |
| switch id { | |
| case 1023: | |
| log.Println("open") | |
| case 1024: | |
| log.Println("hello") | |
| case 1025: | |
| log.Println("1025") | |
| _, _ = user32dll.PostMessage(hwnd, w32.WM_DESTROY, 0, 0) | |
| } | |
| } | |
| return user32dll.DefWindowProc(hwnd, uMsg, wParam, lParam) | |
| })) | |
| const ( | |
| wndClassName = "classCreatePopupMenu" | |
| wndWindowName = "windowCreatePopupMenu" | |
| ) | |
| // Register | |
| pUTF16ClassName, _ := syscall.UTF16PtrFromString(wndClassName) | |
| hInstance := w32.HINSTANCE(kernel32dll.GetModuleHandle("")) | |
| if atom, errno := user32dll.RegisterClass(&w32.WNDCLASS{ | |
| Style: w32.CS_HREDRAW | w32.CS_HREDRAW, | |
| HbrBackground: w32.COLOR_WINDOW, | |
| LpfnWndProc: wndProcFuncPtr, | |
| HInstance: hInstance, | |
| HIcon: hIcon, | |
| LpszClassName: pUTF16ClassName, | |
| }); atom == 0 { | |
| fmt.Printf("%s", errno) | |
| chanWin <- 0 | |
| return | |
| } | |
| // Create window | |
| hwnd, errno := user32dll.CreateWindowEx(0, | |
| wndClassName, | |
| wndWindowName, | |
| w32.WS_OVERLAPPEDWINDOW, | |
| // Size and position | |
| w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, | |
| 0, // Parent window | |
| 0, // Menu | |
| hInstance, | |
| 0, // Additional application data | |
| ) | |
| if hwnd == 0 { | |
| fmt.Printf("%s\n", errno) | |
| if ok, errno2 := user32dll.UnregisterClass(wndClassName, hInstance); !ok { | |
| fmt.Printf("Error UnregisterClass: %s", errno2) | |
| } | |
| chanWin <- hwnd | |
| return | |
| } | |
| // Make sure it can be unregistered when exiting. | |
| defer func() { | |
| if ok, errno2 := user32dll.UnregisterClass(wndClassName, hInstance); !ok { | |
| log.Printf("Error UnregisterClass: %s", errno2) | |
| } else { | |
| log.Println("OK UnregisterClass") | |
| } | |
| close(chanWin) | |
| }() | |
| chanWin <- hwnd | |
| var msg w32.MSG | |
| for { | |
| if status, _ := user32dll.GetMessage(&msg, 0, 0, 0); status <= 0 { | |
| break | |
| } | |
| user32dll.TranslateMessage(&msg) | |
| user32dll.DispatchMessage(&msg) | |
| } | |
| }(ch) | |
| hwnd := <-ch | |
| user32dll.ShowWindow(hwnd, w32.SW_SHOW) | |
| // wait user close the window | |
| <-ch | |
| // Output: | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment