github.com/as/shiny@v0.8.2/driver/win32/screen.go (about) 1 // +build windows 2 3 package win32 4 5 import ( 6 "syscall" 7 "unsafe" 8 ) 9 10 // screenHWND is the handle to the "Screen window". 11 // The Screen window encapsulates all screen.Screen operations 12 // in an actual Windows window so they all run on the main thread. 13 // Since any messages sent to a window will be executed on the 14 // main thread, we can safely use the messages below. 15 var ( 16 screenHWND syscall.Handle 17 screenMsgs = map[uint32]func(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) (lResult uintptr){} 18 ) 19 20 func AddScreenMsg(fn func(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr)) uint32 { 21 uMsg := currentUserWM.next() 22 screenMsgs[uMsg] = func(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) uintptr { 23 fn(hwnd, uMsg, wParam, lParam) 24 return 0 25 } 26 return uMsg 27 } 28 29 func SendScreenMessage(uMsg uint32, wParam uintptr, lParam uintptr) (lResult uintptr) { 30 return SendMessage(screenHWND, uMsg, wParam, lParam) 31 } 32 33 func initScreenWindow() (err error) { 34 const screenWindowClass = "shiny_ScreenWindow" 35 swc, err := syscall.UTF16PtrFromString(screenWindowClass) 36 if err != nil { 37 return err 38 } 39 empty, err := syscall.UTF16PtrFromString("") 40 if err != nil { 41 return err 42 } 43 44 wc := WindowClass{ 45 LpszClassName: swc, 46 LpfnWndProc: syscall.NewCallback(screenWindowWndProc), 47 HIcon: hDefaultIcon, 48 HCursor: hDefaultCursor, 49 HInstance: hThisInstance, 50 HbrBackground: syscall.Handle(ColorBtnface + 1), 51 } 52 _, err = RegisterClass(&wc) 53 if err != nil { 54 return err 55 } 56 57 const ( 58 //style = WsOverlappedWindow | WsVisible | WsChild 59 style = WsOverlappedWindow 60 def = int32(CwUseDefault) 61 ) 62 //screenHWND, err = CreateWindowEx(0, swc, empty, style, def, def, def, def, GetConsoleWindow(), 0, hThisInstance, 0) 63 screenHWND, err = CreateWindowEx(0, swc, empty, style, def, def, def, def, HwndMessage, 0, hThisInstance, 0) 64 return err 65 } 66 67 func screenWindowWndProc(hwnd syscall.Handle, uMsg uint32, wParam uintptr, lParam uintptr) (lResult uintptr) { 68 switch uMsg { 69 case msgCreateWindow: 70 p := (*newWindowParams)(unsafe.Pointer(lParam)) 71 p.w, p.err = newWindow(p.opts) 72 case msgMainCallback: 73 go func() { 74 mainCallback() 75 SendScreenMessage(msgQuit, 0, 0) 76 }() 77 case msgQuit: 78 PostQuitMessage(0) 79 } 80 fn := screenMsgs[uMsg] 81 if fn != nil { 82 return fn(hwnd, uMsg, wParam, lParam) 83 } 84 return DefWindowProc(hwnd, uMsg, wParam, lParam) 85 }