Hello, Win32 GUI(Go) World!
Posted on 7月 21st, 2012 by cx20
Win32 GUI(Go)
Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
以下は Go言語 における Win32 GUI アプリケーション の例となっている。
ソースコード
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 } |
コンパイル方法
C:¥> SET GOROOT=C:go C:¥> go build -ldflags -Hwindowsgui hello.go |
実行結果
+------------------------------------------+ |Hello, World! [_][~][X]| +------------------------------------------+ |Hello, Win32 GUI(Go) World! | | | | | | | | | | | | | | | | | | | +------------------------------------------+ |
Tags: Win32 GUI