github.com/ebitengine/purego@v0.8.0-alpha.2.0.20240512170805-6cd12240d332/examples/window/main_windows.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // SPDX-FileCopyrightText: 2024 The Ebitengine Authors
     3  
     4  package main
     5  
     6  import (
     7  	"runtime"
     8  	"unsafe"
     9  
    10  	"golang.org/x/sys/windows"
    11  
    12  	"github.com/ebitengine/purego"
    13  )
    14  
    15  const (
    16  	WS_OVERLAPPEDWINDOW = 0x00000000 | 0x00C00000 | 0x00080000 | 0x00040000 | 0x00020000 | 0x00010000
    17  	CW_USEDEFAULT       = ^0x7fffffff
    18  	SW_SHOW             = 5
    19  	WM_DESTROY          = 2
    20  )
    21  
    22  type (
    23  	ATOM      uint16
    24  	HANDLE    uintptr
    25  	HINSTANCE HANDLE
    26  	HICON     HANDLE
    27  	HCURSOR   HANDLE
    28  	HBRUSH    HANDLE
    29  	HWND      HANDLE
    30  	HMENU     HANDLE
    31  )
    32  
    33  type WNDCLASSEX struct {
    34  	Size       uint32
    35  	Style      uint32
    36  	WndProc    uintptr
    37  	ClsExtra   int32
    38  	WndExtra   int32
    39  	Instance   HINSTANCE
    40  	Icon       HICON
    41  	Cursor     HCURSOR
    42  	Background HBRUSH
    43  	MenuName   *uint16
    44  	ClassName  *uint16
    45  	IconSm     HICON
    46  }
    47  
    48  type RECT struct {
    49  	Left, Top, Right, Bottom int32
    50  }
    51  
    52  type POINT struct {
    53  	X, Y int32
    54  }
    55  
    56  type MSG struct {
    57  	Hwnd    HWND
    58  	Message uint32
    59  	WParam  uintptr
    60  	LParam  uintptr
    61  	Time    uint32
    62  	Pt      POINT
    63  }
    64  
    65  var (
    66  	GetModuleHandle func(modulename *uint16) HINSTANCE
    67  	RegisterClassEx func(w *WNDCLASSEX) ATOM
    68  	CreateWindowEx  func(exStyle uint, className, windowName *uint16,
    69  		style uint, x, y, width, height int, parent HWND, menu HMENU,
    70  		instance HINSTANCE, param unsafe.Pointer) HWND
    71  	AdjustWindowRect func(rect *RECT, style uint, menu bool) bool
    72  	ShowWindow       func(hwnd HWND, cmdshow int) bool
    73  	GetMessage       func(msg *MSG, hwnd HWND, msgFilterMin, msgFilterMax uint32) int
    74  	TranslateMessage func(msg *MSG) bool
    75  	DispatchMessage  func(msg *MSG) uintptr
    76  	DefWindowProc    func(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr
    77  	PostQuitMessage  func(exitCode int)
    78  )
    79  
    80  func init() {
    81  	kernel32 := windows.NewLazySystemDLL("kernel32.dll").Handle()
    82  	purego.RegisterLibFunc(&GetModuleHandle, kernel32, "GetModuleHandleW")
    83  
    84  	user32 := windows.NewLazySystemDLL("user32.dll").Handle()
    85  	purego.RegisterLibFunc(&RegisterClassEx, user32, "RegisterClassExW")
    86  	purego.RegisterLibFunc(&CreateWindowEx, user32, "CreateWindowExW")
    87  	purego.RegisterLibFunc(&AdjustWindowRect, user32, "AdjustWindowRect")
    88  	purego.RegisterLibFunc(&ShowWindow, user32, "ShowWindow")
    89  	purego.RegisterLibFunc(&GetMessage, user32, "GetMessageW")
    90  	purego.RegisterLibFunc(&TranslateMessage, user32, "TranslateMessage")
    91  	purego.RegisterLibFunc(&DispatchMessage, user32, "DispatchMessageW")
    92  	purego.RegisterLibFunc(&DefWindowProc, user32, "DefWindowProcW")
    93  	purego.RegisterLibFunc(&PostQuitMessage, user32, "PostQuitMessage")
    94  
    95  	runtime.LockOSThread()
    96  }
    97  
    98  func main() {
    99  	className := windows.StringToUTF16Ptr("Sample Window Class")
   100  	inst := GetModuleHandle(className)
   101  
   102  	wc := WNDCLASSEX{
   103  		Size:      uint32(unsafe.Sizeof(WNDCLASSEX{})),
   104  		WndProc:   windows.NewCallback(wndProc),
   105  		Instance:  inst,
   106  		ClassName: className,
   107  	}
   108  
   109  	RegisterClassEx(&wc)
   110  
   111  	wr := RECT{
   112  		Left:   0,
   113  		Top:    0,
   114  		Right:  320,
   115  		Bottom: 240,
   116  	}
   117  	AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, false)
   118  	hwnd := CreateWindowEx(
   119  		0, className,
   120  		windows.StringToUTF16Ptr("My Title"),
   121  		WS_OVERLAPPEDWINDOW,
   122  		CW_USEDEFAULT, CW_USEDEFAULT, int(wr.Right-wr.Left), int(wr.Bottom-wr.Top),
   123  		0, 0, inst, nil,
   124  	)
   125  	if hwnd == 0 {
   126  		panic(windows.GetLastError())
   127  	}
   128  
   129  	ShowWindow(hwnd, SW_SHOW)
   130  
   131  	var msg MSG
   132  	for GetMessage(&msg, 0, 0, 0) != 0 {
   133  		TranslateMessage(&msg)
   134  		DispatchMessage(&msg)
   135  	}
   136  }
   137  
   138  func wndProc(hwnd HWND, msg uint32, wparam, lparam uintptr) uintptr {
   139  	switch msg {
   140  	case WM_DESTROY:
   141  		PostQuitMessage(0)
   142  	}
   143  	return DefWindowProc(hwnd, msg, wparam, lparam)
   144  }