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:

Categories: Go, Win32 API, Win32 GUI

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

WP-SpamFree by Pole Position Marketing