github.com/AlpineAIO/wails/v2@v2.0.0-beta.32.0.20240505041856-1047a8fa5fef/internal/platform/win32/window.go (about)

     1  //go:build windows
     2  
     3  package win32
     4  
     5  import (
     6  	"fmt"
     7  	"github.com/samber/lo"
     8  	"golang.org/x/sys/windows"
     9  	"syscall"
    10  	"unsafe"
    11  )
    12  
    13  func LoadIconWithResourceID(instance HINSTANCE, res uintptr) HICON {
    14  	ret, _, _ := procLoadIcon.Call(
    15  		uintptr(instance),
    16  		res)
    17  
    18  	return HICON(ret)
    19  }
    20  
    21  func LoadCursorWithResourceID(instance HINSTANCE, res uintptr) HCURSOR {
    22  	ret, _, _ := procLoadCursor.Call(
    23  		uintptr(instance),
    24  		res)
    25  
    26  	return HCURSOR(ret)
    27  }
    28  
    29  func RegisterClassEx(wndClassEx *WNDCLASSEX) ATOM {
    30  	ret, _, _ := procRegisterClassEx.Call(uintptr(unsafe.Pointer(wndClassEx)))
    31  	return ATOM(ret)
    32  }
    33  
    34  func RegisterClass(className string, wndproc uintptr, instance HINSTANCE) error {
    35  	classNamePtr, err := syscall.UTF16PtrFromString(className)
    36  	if err != nil {
    37  		return err
    38  	}
    39  	icon := LoadIconWithResourceID(instance, IDI_APPLICATION)
    40  
    41  	var wc WNDCLASSEX
    42  	wc.CbSize = uint32(unsafe.Sizeof(wc))
    43  	wc.Style = CS_HREDRAW | CS_VREDRAW
    44  	wc.LpfnWndProc = wndproc
    45  	wc.HInstance = instance
    46  	wc.HbrBackground = COLOR_WINDOW + 1
    47  	wc.HIcon = icon
    48  	wc.HCursor = LoadCursorWithResourceID(0, IDC_ARROW)
    49  	wc.LpszClassName = classNamePtr
    50  	wc.LpszMenuName = nil
    51  	wc.HIconSm = icon
    52  
    53  	if ret := RegisterClassEx(&wc); ret == 0 {
    54  		return syscall.GetLastError()
    55  	}
    56  
    57  	return nil
    58  }
    59  
    60  func CreateWindow(className string, instance HINSTANCE, parent HWND, exStyle, style uint) HWND {
    61  
    62  	classNamePtr := lo.Must(syscall.UTF16PtrFromString(className))
    63  
    64  	result := CreateWindowEx(
    65  		exStyle,
    66  		classNamePtr,
    67  		nil,
    68  		style,
    69  		CW_USEDEFAULT,
    70  		CW_USEDEFAULT,
    71  		CW_USEDEFAULT,
    72  		CW_USEDEFAULT,
    73  		parent,
    74  		0,
    75  		instance,
    76  		nil)
    77  
    78  	if result == 0 {
    79  		errStr := fmt.Sprintf("Error occurred in CreateWindow(%s, %v, %d, %d)", className, parent, exStyle, style)
    80  		panic(errStr)
    81  	}
    82  
    83  	return result
    84  }
    85  
    86  func CreateWindowEx(exStyle uint, className, windowName *uint16,
    87  	style uint, x, y, width, height int, parent HWND, menu HMENU,
    88  	instance HINSTANCE, param unsafe.Pointer) HWND {
    89  	ret, _, _ := procCreateWindowEx.Call(
    90  		uintptr(exStyle),
    91  		uintptr(unsafe.Pointer(className)),
    92  		uintptr(unsafe.Pointer(windowName)),
    93  		uintptr(style),
    94  		uintptr(x),
    95  		uintptr(y),
    96  		uintptr(width),
    97  		uintptr(height),
    98  		uintptr(parent),
    99  		uintptr(menu),
   100  		uintptr(instance),
   101  		uintptr(param))
   102  
   103  	return HWND(ret)
   104  }
   105  
   106  func MustStringToUTF16Ptr(input string) *uint16 {
   107  	ret, err := syscall.UTF16PtrFromString(input)
   108  	if err != nil {
   109  		panic(err)
   110  	}
   111  	return ret
   112  }
   113  
   114  func MustStringToUTF16uintptr(input string) uintptr {
   115  	ret, err := syscall.UTF16PtrFromString(input)
   116  	if err != nil {
   117  		panic(err)
   118  	}
   119  	return uintptr(unsafe.Pointer(ret))
   120  }
   121  
   122  func MustUTF16FromString(input string) []uint16 {
   123  	ret, err := syscall.UTF16FromString(input)
   124  	if err != nil {
   125  		panic(err)
   126  	}
   127  	return ret
   128  }
   129  
   130  func UTF16PtrToString(input uintptr) string {
   131  	return windows.UTF16PtrToString((*uint16)(unsafe.Pointer(input)))
   132  }
   133  
   134  func SetForegroundWindow(wnd HWND) bool {
   135  	ret, _, _ := procSetForegroundWindow.Call(
   136  		uintptr(wnd),
   137  	)
   138  	return ret != 0
   139  }