package main import ( "syscall" "unsafe" ) const ( WS_OVERLAPPED = 0x00000000 WS_POPUP = 0x80000000 WS_CHILD = 0x40000000 WS_MINIMIZE = 0x20000000 WS_VISIBLE = 0x10000000 WS_DISABLED = 0x08000000 WS_CLIPSIBLINGS = 0x04000000 WS_CLIPCHILDREN = 0x02000000 WS_MAXIMIZE = 0x01000000 WS_CAPTION = 0x00C00000 // WS_BORDER | WS_DLGFRAME WS_BORDER = 0x00800000 WS_DLGFRAME = 0x00400000 WS_VSCROLL = 0x00200000 WS_HSCROLL = 0x00100000 WS_SYSMENU = 0x00080000 WS_THICKFRAME = 0x00040000 WS_GROUP = 0x00020000 WS_TABSTOP = 0x00010000 WS_MINIMIZEBOX = 0x00020000 WS_MAXIMIZEBOX = 0x00010000 WS_TILED = WS_OVERLAPPED WS_ICONIC = WS_MINIMIZE WS_SIZEBOX = WS_THICKFRAME WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU WS_CHILDWINDOW = WS_CHILD WM_CREATE = 0x0001 WM_DESTROY = 0x0002 WM_PAINT = 0x000F WM_CLOSE = 0x0010 WM_COMMAND = 0x0111 COLOR_WINDOW = 5 COLOR_BTNFACE = 15 CS_VREDRAW = 0x0001 CS_HREDRAW = 0x0002 CW_USEDEFAULT = -2147483648 // ((int)0x80000000) SW_SHOWDEFAULT = 10 ) type WNDCLASSEX struct { cbSize uint32 style uint32 lpfnWndProc uintptr cbClsExtra int32 cbWndExtra int32 hInstance syscall.Handle hIcon syscall.Handle hCursor syscall.Handle hbrBackground syscall.Handle lpszMenuName *uint16 lpszClassName *uint16 hIconSm syscall.Handle } type POINT struct { x uintptr y uintptr } type MSG struct { hWnd syscall.Handle message uint32 wParam uintptr lParam uintptr time uint32 pt POINT } type RECT struct { Left int32 Top int32 Right int32 Bottom int32 } type PAINTSTRUCT struct { hdc syscall.Handle fErace uint32 rcPaint RECT fRestore uint32 fIncUpdate uint32 rgbReserved byte } var ( kernel32, _ = syscall.LoadLibrary("kernel32.dll") user32, _ = syscall.LoadLibrary("user32.dll") gdi32, _ = syscall.LoadLibrary("gdi32.dll") procGetModuleHandleW, _ = syscall.GetProcAddress(kernel32, "GetModuleHandleW") procLoadIconW, _ = syscall.GetProcAddress(user32, "LoadIconW") procLoadCursorW, _ = syscall.GetProcAddress(user32, "LoadCursorW") procRegisterClassExW, _ = syscall.GetProcAddress(user32, "RegisterClassExW") procCreateWindowExW, _ = syscall.GetProcAddress(user32, "CreateWindowExW") procDefWindowProcW, _ = syscall.GetProcAddress(user32, "DefWindowProcW") procDestroyWindow, _ = syscall.GetProcAddress(user32, "DestroyWindow") procPostQuitMessage, _ = syscall.GetProcAddress(user32, "PostQuitMessage") procShowWindow, _ = syscall.GetProcAddress(user32, "ShowWindow") procUpdateWindow, _ = syscall.GetProcAddress(user32, "UpdateWindow") procGetMessageW, _ = syscall.GetProcAddress(user32, "GetMessageW") procTranslateMessage, _ = syscall.GetProcAddress(user32, "TranslateMessage") procDispatchMessageW, _ = syscall.GetProcAddress(user32, "DispatchMessageW") procSendMessageW, _ = syscall.GetProcAddress(user32, "SendMessageW") procPostMessageW, _ = syscall.GetProcAddress(user32, "PostMessageW") procBeginPaint, _ = syscall.GetProcAddress(user32, "BeginPaint") procEndPaint, _ = syscall.GetProcAddress(user32, "EndPaint") procTextOutW, _ = syscall.GetProcAddress(gdi32, "TextOutW") IDC_ARROW = MakeIntResource(32512) IDI_APPLICATION = MakeIntResource(32512) ) func GetModuleHandle(lpModuleName *uint16) (syscall.Handle) { ret, _, _ := syscall.Syscall(uintptr(procGetModuleHandleW), 1, uintptr(unsafe.Pointer(lpModuleName)), 0, 0) return syscall.Handle(ret) } func LoadIcon(instance syscall.Handle, iconname *uint16) (syscall.Handle) { ret, _, _ := syscall.Syscall(uintptr(procLoadIconW), 2, uintptr(instance), uintptr(unsafe.Pointer(iconname)), 0) return syscall.Handle(ret) } func LoadCursor(instance syscall.Handle, cursorname *uint16) (syscall.Handle) { ret, _, _ := syscall.Syscall(uintptr(procLoadCursorW), 2, uintptr(instance), uintptr(unsafe.Pointer(cursorname)), 0) return syscall.Handle(ret) } func RegisterClassEx(lpwcx *WNDCLASSEX) (uint16) { ret, _, _ := syscall.Syscall(uintptr(procRegisterClassExW), 1, uintptr(unsafe.Pointer(lpwcx)), 0, 0) return uint16(ret) } func CreateWindowEx(dwExStyle uint32, lpClassName *uint16, lpWindowName *uint16, dwStyle uint32, x int32, y int32, nWidth int32, nHeight int32, hWndParent syscall.Handle, hMenu syscall.Handle, hInstance syscall.Handle, lpParam uintptr) (syscall.Handle) { ret, _, _ := syscall.Syscall12(uintptr(procCreateWindowExW), 12, uintptr(dwExStyle), uintptr(unsafe.Pointer(lpClassName)), uintptr(unsafe.Pointer(lpWindowName)), uintptr(dwStyle), uintptr(x), uintptr(y), uintptr(nWidth), uintptr(nHeight), uintptr(hWndParent), uintptr(hMenu), uintptr(hInstance), uintptr(lpParam)) return syscall.Handle(ret) } func DefWindowProc(hWnd syscall.Handle, Msg uint32, wParam uintptr, lParam uintptr) (uintptr) { ret, _, _ := syscall.Syscall6(uintptr(procDefWindowProcW), 4, uintptr(hWnd), uintptr(Msg), uintptr(wParam), uintptr(lParam), 0, 0) return uintptr(ret) } func DestroyWindow(hWnd syscall.Handle) { syscall.Syscall(uintptr(procDestroyWindow), 1, uintptr(hWnd), 0, 0) return } func PostQuitMessage(nExitCode int32) { syscall.Syscall(uintptr(procPostQuitMessage), 1, uintptr(nExitCode), 0, 0) return } func ShowWindow(hWnd syscall.Handle, nCmdShow int32) (bool) { ret, _, _ := syscall.Syscall(uintptr(procShowWindow), 2, uintptr(hWnd), uintptr(nCmdShow), 0) return bool(ret != 0) } func UpdateWindow(hWnd syscall.Handle) { syscall.Syscall(uintptr(procUpdateWindow), 1, uintptr(hWnd), 0, 0) return } func GetMessage(lpMsg *MSG, hWnd syscall.Handle, wMsgFilterMin uint32, wMsgFilterMax uint32) (int32) { ret, _, _ := syscall.Syscall6(uintptr(procGetMessageW), 4, uintptr(unsafe.Pointer(lpMsg)), uintptr(hWnd), uintptr(wMsgFilterMin), uintptr(wMsgFilterMax), 0, 0) return int32(ret) } func TranslateMessage(lpMsg *MSG) (bool) { r, _, _ := syscall.Syscall(uintptr(procTranslateMessage), 1, uintptr(unsafe.Pointer(lpMsg)), 0, 0) return bool(r != 0) } func DispatchMessage(lpMsg *MSG) (int32) { ret, _, _ := syscall.Syscall(uintptr(procDispatchMessageW), 1, uintptr(unsafe.Pointer(lpMsg)), 0, 0) return int32(ret) } func SendMessage(hWnd syscall.Handle, Msg uint32, wParam uintptr, lParam uintptr) (uintptr) { ret, _, _ := syscall.Syscall6(uintptr(procSendMessageW), 4, uintptr(hWnd), uintptr(Msg), uintptr(wParam), uintptr(lParam), 0, 0) return uintptr(ret) } func PostMessage(hWnd syscall.Handle, Msg uint32, wParam uintptr, lParam uintptr) { syscall.Syscall6(uintptr(procPostMessageW), 4, uintptr(hWnd), uintptr(Msg), uintptr(wParam), uintptr(lParam), 0, 0) return } func BeginPaint(hDC syscall.Handle, lpPaint *PAINTSTRUCT ) (syscall.Handle) { ret, _, _ := syscall.Syscall(uintptr(procBeginPaint), 2, uintptr(hDC), uintptr(unsafe.Pointer(lpPaint)), 0) return syscall.Handle(ret) } func EndPaint(hDC syscall.Handle, lpPaint *PAINTSTRUCT ) (syscall.Handle) { ret, _, _ := syscall.Syscall(uintptr(procEndPaint), 2, uintptr(hDC), uintptr(unsafe.Pointer(lpPaint)), 0) return syscall.Handle(ret) } func TextOut(hDC syscall.Handle, x int32, y int32, text string, cbString int32 ) (bool) { ret, _, _ := syscall.Syscall6(uintptr(procTextOutW), 5, uintptr(hDC), uintptr(x), uintptr(y), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))), uintptr(cbString), 0) return bool(ret != 0) } func MakeIntResource(id uint16) (*uint16) { return (*uint16)(unsafe.Pointer(uintptr(id))) } func WndProc(hWnd syscall.Handle, msg uint32, wParam, lParam uintptr) (uintptr) { switch msg { case WM_PAINT: var strMessage = "Hello, Win32 GUI(Go) World!" var ps PAINTSTRUCT hdc := BeginPaint(hWnd, &ps) TextOut( hdc, 0, 0, strMessage, int32(len(strMessage)) ) EndPaint( hWnd, &ps ) case WM_DESTROY: PostQuitMessage(0) default: return DefWindowProc(hWnd, msg, wParam, lParam) } return 0 } func WinMain() int { hInstance := GetModuleHandle(nil) lpszClassName := syscall.StringToUTF16Ptr("helloWindow") lpszWindowName := syscall.StringToUTF16Ptr("Hello, World!") var wcex WNDCLASSEX wcex.cbSize = uint32(unsafe.Sizeof(wcex)) wcex.style = CS_HREDRAW | CS_VREDRAW wcex.lpfnWndProc = syscall.NewCallback(WndProc) wcex.cbClsExtra = 0 wcex.cbWndExtra = 0 wcex.hInstance = hInstance wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION) wcex.hCursor = LoadCursor(0, IDC_ARROW) wcex.hbrBackground = COLOR_WINDOW + 1 wcex.lpszMenuName = nil wcex.lpszClassName = lpszClassName wcex.hIconSm = LoadIcon(hInstance, IDI_APPLICATION) RegisterClassEx(&wcex) hWnd := CreateWindowEx( 0, lpszClassName, lpszWindowName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 0, 0, hInstance, 0) ShowWindow(hWnd, SW_SHOWDEFAULT) UpdateWindow(hWnd) var msg MSG for { if GetMessage(&msg, 0, 0, 0) == 0 { break } TranslateMessage(&msg) DispatchMessage(&msg) } return int(msg.wParam) } func main() { WinMain() return }