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  }