Archive for the ‘Win32 GUI’ Category

  1. Hello, Win32 GUI(BeanShell) World!

    Posted on 3月 19th, 2013 by cx20

    Win32 GUI(BeanShell)

    Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
    以下は BeanShell にて Java の GUI ツールキット SWT の非公開 API を使用した Win32 GUI アプリケーション の例となっている。

    ソースコード

    import org.eclipse.swt.internal.Callback;
    import org.eclipse.swt.internal.win32.MSG;
    import org.eclipse.swt.internal.win32.OS;
    import org.eclipse.swt.internal.win32.PAINTSTRUCT;
    import org.eclipse.swt.internal.win32.RECT;
    import org.eclipse.swt.internal.win32.TCHAR;
    import org.eclipse.swt.internal.win32.WNDCLASS;
     
    public class Hello {
        public static int WndProc(int hWnd, int uMsg, int wParam, int lParam) {
            int hdc;
            PAINTSTRUCT lpPaint = new PAINTSTRUCT();
            String strMessage = "Hello, Win32 GUI(SWT) World!";
     
            switch (uMsg) {
            case OS.WM_PAINT:
                RECT rect = new RECT();
                hdc = OS.BeginPaint(hWnd, lpPaint);
                OS.GetClientRect(hWnd, rect);
                OS.DrawTextW(hdc, strMessage.toCharArray(), strMessage.length(), rect, OS.DT_SINGLELINE);
                OS.EndPaint(hWnd, lpPaint);
                return 0;
            case OS.WM_DESTROY:
                System.exit(wParam);
            default:
                return OS.DefWindowProc(hWnd, uMsg, wParam, lParam);
            }
        }
     
        public static void WinMain(String[] args) {
            int hInstance = OS.GetModuleHandle(null);
            TCHAR className  = new TCHAR(0, "helloWindow", true);
            TCHAR windowName = new TCHAR(0, "Hello, World", true);
     
            WNDCLASS wc      = new WNDCLASS();
            wc.style         = OS.CS_HREDRAW | OS.CS_VREDRAW;
            wc.lpfnWndProc   = new Callback(Hello.class, "WndProc", 4).getAddress();
            wc.hInstance     = hInstance;
            wc.hCursor       = OS.LoadCursor(0, OS.IDC_ARROW);
            wc.hbrBackground = OS.GetStockObject(OS.COLOR_WINDOW + 1 );
            wc.lpszClassName = OS.HeapAlloc(OS.GetProcessHeap(), OS.HEAP_ZERO_MEMORY, className.length() * 2);
            OS.MoveMemory(wc.lpszClassName, className, className.length() * 2);
     
            OS.RegisterClass(wc);
     
            int hWnd = OS.CreateWindowEx(
                0,
                className,
                windowName,
                OS.WS_OVERLAPPEDWINDOW,
                OS.CW_USEDEFAULT, 
                OS.CW_USEDEFAULT,
                640,
                480,
                0,
                0,
                hInstance,
                null);
     
            OS.ShowWindow(hWnd, OS.SW_SHOW);
            OS.UpdateWindow(hWnd);
     
            MSG lpMsg = new MSG();
            while (OS.GetMessage(lpMsg, 0, 0, 0)) {
                OS.TranslateMessage(lpMsg);
                OS.DispatchMessage(lpMsg);
            }
        }
     
        public static void main(String[] args) {
            WinMain( args );
        }
     
    }

    コンパイル&実行方法

    C:¥> SET CLASSPATH=bsh-2.0b4.jar;org.eclipse.swt.win32.win32.x86_3.6.1.v3655c.jar;%CLASSPATH%
    C:¥> java bsh.Interpreter Hello.bsh

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(SWT) World!              |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  2. 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!               |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  3. Hello, Win32 GUI(Delphi) World!

    Posted on 7月 20th, 2012 by cx20

    Win32 GUI(Delphi)

    Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
    以下は Delphi における Win32 GUI アプリケーション の例となっている。

    ソースコード

    program hello;
     
    uses
        Windows, Messages;
     
    function WndProc(hWindow:HWnd; message:Cardinal; wParam:Word; lParam:Longint):LongWord; stdcall;
    var
        hdc:        THandle;
        ps:         TPaintStruct;
    const
        strMessage = 'Hello, Win32 GUI(Delphi) World!';
    begin
        case message of
            WM_PAINT:
                begin
                    hdc := BeginPaint(hWindow, ps );
                    TextOut( hdc, 0, 0, strMessage, Length(strMessage) );
                    EndPaint( hWindow, ps );
                end;
     
            WM_DESTROY:
                PostQuitMessage(0);
        else
            Result := DefWindowProc(hWindow, message, wParam, lParam);
            exit;
        end;
        Result := 0;
    end;
     
    function WinMain(hInstance, hPrevInstance:THandle; lpCmdLine:PAnsiChar; nCmdShow:Integer):Integer; stdcall;
    var
        wcex:       TWndClassEx;
        hWindow:    HWnd;
        msg:        TMsg;
    const
        ClassName = 'helloWindow';
        WindowName = 'Hello, World!';
     
    begin
        wcex.cbSize         := SizeOf(TWndclassEx);
        wcex.style          := CS_HREDRAW or CS_VREDRAW;
        wcex.lpfnWndProc    := @WndProc;
        wcex.cbClsExtra     := 0;
        wcex.cbWndExtra     := 0;
        wcex.hInstance      := hInstance;
        wcex.hIcon          := LoadIcon(0, IDI_APPLICATION);
        wcex.hCursor        := LoadCursor(0, IDC_ARROW);
        wcex.hbrBackground  := COLOR_WINDOW +1;
        wcex.lpszMenuName   := nil;
        wcex.lpszClassName  := ClassName;
     
        RegisterClassEx(wcex);
        hWindow := CreateWindowEX(
            0,
            ClassName,
            WindowName,
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
            0, 0, hInstance, nil
        );
     
        ShowWindow(hWindow, SW_SHOWDEFAULT);
        UpdateWindow(hWindow);
     
        while GetMessage(msg, 0, 0, 0) do begin
            TranslateMessage(msg);
            DispatchMessage(msg);
        end;
     
        Result := msg.wParam;
    end;
     
    begin
        WinMain( hInstance, 0, nil, cmdShow );
    end.

    コンパイル方法

    C:¥> dcc32 hello.pas

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(Delphi) World!           |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  4. Hello, Win32 GUI(Pascal) World!

    Posted on 7月 20th, 2012 by cx20

    Win32 GUI(Pascal)

    Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
    以下は Free Pascal における Win32 GUI アプリケーション の例となっている。

    ソースコード

    {$APPTYPE GUI}
    {$MODE DELPHI}
    program hello;
     
    uses
        Windows, Messages;
     
    function WindowProc(hWindow:HWnd; message:Cardinal; wParam:Word; lParam:Longint):LongWord; stdcall;
    var
        hdc:        THandle;
        ps:         TPaintStruct;
    const
        strMessage = 'Hello, Win32 GUI(Pascal) World!';
    begin
        case message of
            WM_PAINT:
                begin
                    hdc := BeginPaint(hWindow, ps );
                    TextOut( hdc, 0, 0, strMessage, Length(strMessage) );
                    EndPaint( hWindow, ps );
                end;
     
            WM_DESTROY:
                PostQuitMessage(0);
        else
            WindowProc := DefWindowProc(hWindow, message, wParam, lParam);
            exit;
        end;
        WindowProc := 0;
    end;
     
    function WinMain(hInstance, hPrevInstance:THandle; lpCmdLine:PAnsiChar; nCmdShow:Integer):Integer; stdcall;
    var
        wcex:       TWndClassEx;
        hWindow:    HWnd;
        msg:        TMsg;
    const
        ClassName = 'helloWindow';
        WindowName = 'Hello, World!';
     
    begin
        wcex.cbSize         := SizeOf(TWndclassEx);
        wcex.style          := CS_HREDRAW or CS_VREDRAW;
        wcex.lpfnWndProc    := WndProc(@WindowProc);
        wcex.cbClsExtra     := 0;
        wcex.cbWndExtra     := 0;
        wcex.hInstance      := hInstance;
        wcex.hIcon          := LoadIcon(0, IDI_APPLICATION);
        wcex.hCursor        := LoadCursor(0, IDC_ARROW);
        wcex.hbrBackground  := COLOR_WINDOW +1;
        wcex.lpszMenuName   := nil;
        wcex.lpszClassName  := ClassName;
     
        RegisterClassEx(wcex);
        hWindow := CreateWindowEX(
            0,
            ClassName,
            WindowName,
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
            0, 0, hInstance, nil
        );
     
        ShowWindow(hWindow, SW_SHOWDEFAULT);
        UpdateWindow(hWindow);
     
        while GetMessage(msg, 0, 0, 0) do begin
            TranslateMessage(msg);
            DispatchMessage(msg);
        end;
     
        WinMain := msg.wParam;
    end;
     
    begin
        WinMain( hInstance, 0, nil, cmdShow );
    end.

    コンパイル方法

    C:¥> fpc hello.pas

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(Pascal) World!           |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  5. Hello, Win32 GUI(D言語) World!

    Posted on 7月 19th, 2012 by cx20

    Win32 GUI(D言語)

    Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
    以下は D言語 における Win32 GUI アプリケーション の例となっている。

    ソースコード

    import core.runtime;
    import std.c.windows.windows;
    import std.string;
     
    extern(Windows)
    LRESULT WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
        case WM_PAINT:
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint( hWnd, &ps );
            enum text = "Hello, Win32 GUI(D) World!";
            TextOutA( hdc, 0, 0, text, text.length );
            EndPaint( hWnd, &ps );
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProcA(hWnd, message, wParam, lParam);
            break;
        }
     
        return 0;
    }
     
    extern(Windows)
    int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        string className = "helloWindow";
        string windowName = "Hello, World!";
        HWND hWnd;
        MSG  msg;
        WNDCLASSA wc;
     
        wc.style         = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc   = &WndProc;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hInstance     = hInstance;
        wc.hIcon         = LoadIconA(null, IDI_APPLICATION);
        wc.hCursor       = LoadCursorA(null, IDC_ARROW);
        wc.hbrBackground = cast(HBRUSH)(COLOR_WINDOW+1);
        wc.lpszMenuName  = null;
        wc.lpszClassName = className.toStringz;
     
        RegisterClassA(&wc);
        hWnd = CreateWindowA(className.toStringz, 
                             windowName.toStringz,
                             WS_OVERLAPPEDWINDOW,
                             CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
                             null, null, hInstance, null);
     
        ShowWindow(hWnd, SW_SHOWDEFAULT);
        UpdateWindow(hWnd);
     
        while (GetMessageA(&msg, null, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessageA(&msg);
        }
     
        return msg.wParam;
    }

    コンパイル方法

    C:¥> dmd -L/subsystem:windows gdi32.lib hello.d

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(D) World!                |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  6. Hello, Win32 GUI(SWT) World!

    Posted on 7月 18th, 2012 by cx20

    Win32 GUI(Java)

    Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
    以下は Java の GUI ツールキット SWT の非公開 API を使用した Win32 GUI アプリケーション の例となっている。

    ソースコード

    import org.eclipse.swt.internal.Callback;
    import org.eclipse.swt.internal.win32.MSG;
    import org.eclipse.swt.internal.win32.OS;
    import org.eclipse.swt.internal.win32.PAINTSTRUCT;
    import org.eclipse.swt.internal.win32.RECT;
    import org.eclipse.swt.internal.win32.TCHAR;
    import org.eclipse.swt.internal.win32.WNDCLASS;
     
    public class Hello {
        public static int WndProc(int hWnd, int uMsg, int wParam, int lParam) {
            int hdc;
            PAINTSTRUCT lpPaint = new PAINTSTRUCT();
            String strMessage = "Hello, Win32 GUI(SWT) World!";
     
            switch (uMsg) {
            case OS.WM_PAINT:
                RECT rect = new RECT();
                hdc = OS.BeginPaint(hWnd, lpPaint);
                OS.GetClientRect(hWnd, rect);
                OS.DrawTextW(hdc, strMessage.toCharArray(), strMessage.length(), rect, OS.DT_SINGLELINE);
                OS.EndPaint(hWnd, lpPaint);
                return 0;
            case OS.WM_DESTROY:
                System.exit(wParam);
            default:
                return OS.DefWindowProc(hWnd, uMsg, wParam, lParam);
            }
        }
     
        public static void WinMain(String[] args) {
            int hInstance = OS.GetModuleHandle(null);
            TCHAR className  = new TCHAR(0, "helloWindow", true);
            TCHAR windowName = new TCHAR(0, "Hello, World", true);
     
            WNDCLASS wc      = new WNDCLASS();
            wc.style         = OS.CS_HREDRAW | OS.CS_VREDRAW;
            wc.lpfnWndProc   = new Callback(Hello.class, "WndProc", 4).getAddress();
            wc.hInstance     = hInstance;
            wc.hCursor       = OS.LoadCursor(0, OS.IDC_ARROW);
            wc.hbrBackground = OS.GetStockObject(OS.COLOR_WINDOW + 1 );
            wc.lpszClassName = OS.HeapAlloc(OS.GetProcessHeap(), OS.HEAP_ZERO_MEMORY, className.length() * 2);
            OS.MoveMemory(wc.lpszClassName, className, className.length() * 2);
     
            OS.RegisterClass(wc);
     
            int hWnd = OS.CreateWindowEx(
                0,
                className,
                windowName,
                OS.WS_OVERLAPPEDWINDOW,
                OS.CW_USEDEFAULT, 
                OS.CW_USEDEFAULT,
                640,
                480,
                0,
                0,
                hInstance,
                null);
     
            OS.ShowWindow(hWnd, OS.SW_SHOW);
            OS.UpdateWindow(hWnd);
     
            MSG lpMsg = new MSG();
            while (OS.GetMessage(lpMsg, 0, 0, 0)) {
                OS.TranslateMessage(lpMsg);
                OS.DispatchMessage(lpMsg);
            }
        }
     
        public static void main(String[] args) {
            WinMain( args );
        }
     
    }

    コンパイル&実行方法

    C:¥> javac -cp org.eclipse.swt.win32.win32.x86_3.6.1.v3655c.jar;. Hello.java
    C:¥> java -cp org.eclipse.swt.win32.win32.x86_3.6.1.v3655c.jar;. Hello

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(SWT) World!              |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  7. Hello, Win32 GUI(UWSC) World!

    Posted on 7月 17th, 2012 by cx20

    Win32 GUI(UWSC)

    Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
    以下は UWSC にて PowerShell を呼び出す機能により C# を使用した Win32 GUI アプリケーション の例となっている。

    ソースコード(UWSC + PowerShell + C# + Win32)

    Option Explicit
     
    Main()
     
    Procedure Main()
        PowerShell( helloBlock, True, True )
    FEnd
     
    TextBlock helloBlock
        $source = @"
    using System;
    using System.Runtime.InteropServices;
     
    public class Hello
    {
        [StructLayout(LayoutKind.Sequential)]
        struct POINT
        {
            public int x;
            public int y;
        }
     
        [StructLayout(LayoutKind.Sequential)]
        struct MSG
        {
            public IntPtr hwnd;
            public uint message;
            public IntPtr wParam;
            public IntPtr lParam;
            public uint time;
            public POINT pt;
        }
     
        delegate IntPtr WndProcDelgate(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        struct WNDCLASSEX
        {
            public uint cbSize;
            public uint style;
            public WndProcDelgate lpfnWndProc;
            public Int32 cbClsExtra;
            public Int32 cbWndExtra;
            public IntPtr hInstance;
            public IntPtr hIcon;
            public IntPtr hCursor;
            public IntPtr hbrBackground;
            public string lpszMenuName;
            public string lpszClassName;
            public IntPtr hIconSm;
        }
     
        [StructLayout(LayoutKind.Sequential)]
        struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }
     
        [StructLayout(LayoutKind.Sequential)]
        struct PAINTSTRUCT
        {
            public IntPtr hdc;
            public int fErase;
            public RECT rcPaint;
            public int fRestore;
            public int fIncUpdate;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
            public byte[] rgbReserved;
        }
     
        const uint WS_OVERLAPPED = 0x00000000;
        const uint WS_POPUP = 0x80000000;
        const uint WS_CHILD = 0x40000000;
        const uint WS_MINIMIZE = 0x20000000;
        const uint WS_VISIBLE = 0x10000000;
        const uint WS_DISABLED = 0x08000000;
        const uint WS_CLIPSIBLINGS = 0x04000000;
        const uint WS_CLIPCHILDREN = 0x02000000;
        const uint WS_MAXIMIZE = 0x01000000;
        const uint WS_CAPTION = 0x00C00000; // WS_BORDER | WS_DLGFRAME
        const uint WS_BORDER = 0x00800000;
        const uint WS_DLGFRAME = 0x00400000;
        const uint WS_VSCROLL = 0x00200000;
        const uint WS_HSCROLL = 0x00100000;
        const uint WS_SYSMENU = 0x00080000;
        const uint WS_THICKFRAME = 0x00040000;
        const uint WS_GROUP = 0x00020000;
        const uint WS_TABSTOP = 0x00010000;
     
        const uint WS_MINIMIZEBOX = 0x00020000;
        const uint WS_MAXIMIZEBOX = 0x00010000;
     
        const uint WS_TILED = WS_OVERLAPPED;
        const uint WS_ICONIC = WS_MINIMIZE;
        const uint WS_SIZEBOX = WS_THICKFRAME;
        const uint WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW;
     
        const uint WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
        const uint WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU;
        const uint WS_CHILDWINDOW = WS_CHILD;
     
        const uint WM_CREATE = 0x0001;
        const uint WM_DESTROY = 0x0002;
        const uint WM_PAINT = 0x000F;
        const uint WM_CLOSE = 0x0010;
        const uint WM_COMMAND = 0x0111;
     
        const uint COLOR_WINDOW = 5;
        const uint COLOR_BTNFACE = 15;
     
        const uint CS_VREDRAW = 0x0001;
        const uint CS_HREDRAW = 0x0002;
     
        const int CW_USEDEFAULT = -2147483648; // ((uint)0x80000000)
     
        const uint SW_SHOWDEFAULT = 10;
     
        const int IDI_APPLICATION = 32512;
        const int IDC_ARROW = 32512;
     
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr LoadCursor(IntPtr hInstance, IntPtr lpCursorName);
     
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr LoadIcon(IntPtr hInstance, IntPtr lpIconName);
     
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern short RegisterClassEx(ref WNDCLASSEX pcWndClassEx);
     
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr CreateWindowEx(uint dwExStyle, string lpClassName, string lpWindowName, uint dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
     
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
     
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern bool UpdateWindow(IntPtr hWnd);
     
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern int GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);
     
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern int TranslateMessage([In] ref MSG lpMsg);
     
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr DispatchMessage([In] ref MSG lpMsg);
     
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern void PostQuitMessage(int nExitCode);
     
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
     
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr BeginPaint(IntPtr hWnd, out PAINTSTRUCT lpPaint);
     
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr EndPaint(IntPtr hWnd, ref PAINTSTRUCT lpPaint);
     
        [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr TextOut( IntPtr hdc, int x, int y, string lpString, int nCount );
     
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr GetModuleHandle(string lpModuleName);
     
        static IntPtr WndProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam)
        {
            PAINTSTRUCT ps = new PAINTSTRUCT();
            IntPtr hdc;
            string strMessage = "Hello, Win32 GUI(UWSC) World!";
     
            switch (uMsg)
            {
                case WM_PAINT:
                    hdc = BeginPaint( hWnd, out ps );
                    TextOut( hdc, 0, 0, strMessage, strMessage.Length );
                    EndPaint( hWnd, ref ps );
                    break;
                case WM_DESTROY:
                    PostQuitMessage(0);
                    break;
                default:
                    return DefWindowProc(hWnd, uMsg, wParam, lParam);
            }
     
            return IntPtr.Zero;
        }
     
        static int WinMain()
        {
            IntPtr hInstance = Marshal.GetHINSTANCE(typeof(Hello).Module);
            const string CLASS_NAME = "helloWindow";
            const string WINDOW_NAME = "Hello, World!";
     
            WNDCLASSEX wcex = new WNDCLASSEX();
            wcex.cbSize = (uint)Marshal.SizeOf(wcex);
            wcex.style = CS_HREDRAW | CS_VREDRAW;
            wcex.lpfnWndProc = new WndProcDelgate(WndProc);
            wcex.cbClsExtra = 0;
            wcex.cbWndExtra = 0;
            wcex.hInstance = hInstance;
            wcex.hIcon = LoadIcon(hInstance, new IntPtr(IDI_APPLICATION));
            wcex.hCursor = LoadIcon(hInstance, new IntPtr(IDC_ARROW));
            wcex.hbrBackground = new IntPtr(COLOR_WINDOW + 1);
            wcex.lpszMenuName = "";
            wcex.lpszClassName = CLASS_NAME;
            wcex.hIconSm = IntPtr.Zero;
     
            RegisterClassEx(ref wcex);
     
            IntPtr hWnd = CreateWindowEx(
                0,
                wcex.lpszClassName,
                WINDOW_NAME,
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                640,
                480,
                IntPtr.Zero,
                IntPtr.Zero,
                wcex.hInstance,
                IntPtr.Zero);
     
            ShowWindow(hWnd, SW_SHOWDEFAULT);
            UpdateWindow(hWnd);
     
            MSG msg = new MSG();
            while (GetMessage(out msg, IntPtr.Zero, 0, 0) != 0)
            {
                TranslateMessage(ref msg);
                DispatchMessage(ref msg);
            }
     
            return (int)msg.wParam;
        }
     
        [STAThread]
        public static int Main()
        {
            return WinMain();
        }
    }
    "@
        Add-Type -Language CSharp -TypeDefinition $source -ReferencedAssemblies ("System.Drawing", "System.Windows.Forms" )
        [void][Hello]::Main()
    EndTextBlock

    実行方法

    C:¥> uwsc /K hello.uws

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(UWSC) World!             |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  8. Hello, Win32 GUI(Lua) World!

    Posted on 7月 16th, 2012 by cx20

    Win32 GUI(Lua)

    Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
    以下は Lua にて alien ライブラリを使用した Win32 GUI アプリケーション の例となっている。

    ソースコード

    require 'alien'
     
    WS_OVERLAPPED       = 0x00000000
    WS_CAPTION          = 0x00C00000
    WS_SYSMENU          = 0x00080000
    WS_THICKFRAME       = 0x00040000
    WS_MINIMIZEBOX      = 0x00020000
    WS_MAXIMIZEBOX      = 0x00010000 
    WS_OVERLAPPEDWINDOW = WS_OVERLAPPED + WS_CAPTION + WS_SYSMENU + WS_THICKFRAME + WS_MINIMIZEBOX + WS_MAXIMIZEBOX
     
    WM_DESTROY    = 0x0002
    WM_SIZE       = 0x0005
    WM_CLOSE      = 0x0010
    WM_PAINT      = 0x000F
     
    CW_USEDEFAULT = 0x80000000
    SW_SHOWNORMAL = 1
     
    BLACK_BRUSH   = 4
    COLOR_WINDOW  = 5
     
    POINTAPI = alien.defstruct{
        {"x", "long"};
        {"y", "long"};
    }
     
    MSG = alien.defstruct{
        {"hwnd", "pointer"};
        {"message", "uint"};
        {"wParam", "pointer"};
        {"lParam", "pointer"};
        {"time", "ulong"};
        {"x", "long"};
        {"y", "long"};
    }
     
    WNDCLASSEX = alien.defstruct{
        {"cbSize", "uint"};
        {"style", "uint"};
        {"lpfnWndProc", "callback"};
        {"cbClsExtra", "int"};
        {"cbWndExtra", "int"};
        {"hInstance", "pointer"};
        {"hIcon", "pointer"};
        {"hCursor", "pointer"};
        {"hbrBackground", "pointer"};
        {"lpszMenuName", "string"};
        {"lpszClassName", "string"};
        {"hIconSm", "pointer"};
    }
     
    RECT = alien.defstruct{
        {"Left", "long"};
        {"Top", "long"};
        {"Right", "long"};
        {"Bottom", "long"};
    }
     
    PAINTSTRUCT = alien.defstruct{
      {"hdc", "uint"};
      {"fErase", "int"};
      {"rcPaint_left", "long"};
      {"rcPaint_top", "long"};
      {"rcPaint_right", "long"};
      {"rcPaint_bottom", "long"};
      {"fRestore", "int"};
      {"fIncUpdate", "int"};
      --[[ {"rgbReserved", "byte[32]"}; ]]
    }
    PAINTSTRUCT.size = PAINTSTRUCT.size + 32
     
    RegisterClassEx  = alien.user32.RegisterClassExA; RegisterClassEx:types{ ret = "ushort", abi = "stdcall"; "pointer" }
    DestroyWindow    = alien.user32.DestroyWindow;    DestroyWindow:types{ ret = "int", abi = "stdcall"; "pointer" }
    PostQuitMessage  = alien.user32.PostQuitMessage;  PostQuitMessage:types{ ret = "void", abi = "stdcall"; "int" }
    DefWindowProc    = alien.user32.DefWindowProcA;   DefWindowProc:types{ ret = "long", abi = "stdcall"; "pointer", "uint", "uint", "long" }
    GetMessage       = alien.user32.GetMessageA;      GetMessage:types{ ret = "int", abi = "stdcall"; "pointer", "pointer", "uint", "uint" }
    TranslateMessage = alien.user32.TranslateMessage; TranslateMessage:types{ ret = "int", abi = "stdcall"; "pointer" }
    DispatchMessage  = alien.user32.DispatchMessageA; DispatchMessage:types{ ret = "int", abi = "stdcall"; "pointer" }
    CreateWindowEx   = alien.user32.CreateWindowExA;  CreateWindowEx:types{ ret = "pointer", abi = "stdcall"; "ulong", "string", "string", "ulong", "int", "int", "int", "int", "pointer", "pointer", "pointer" }
    ShowWindow       = alien.user32.ShowWindow;       ShowWindow:types{ ret = "int", abi = "stdcall"; "pointer", "int" }
    UpdateWindow     = alien.user32.UpdateWindow;     UpdateWindow:types{ ret = "int", abi = "stdcall"; "pointer" }
    BeginPaint       = alien.user32.BeginPaint;       BeginPaint:types{ ret = "pointer", abi = "stdcall"; "pointer", "pointer" }
    EndPaint         = alien.user32.EndPaint;         EndPaint:types{ ret = "int", abi = "stdcall"; "long", "pointer" }
    TextOut          = alien.gdi32.TextOutA;          TextOut:types{ ret = "int", abi = "stdcall"; "pointer", "int", "int", "string", "int" }
    GetStockObject   = alien.gdi32.GetStockObject;    GetStockObject:types{ ret = "pointer", abi = "stdcall"; "int" }
     
    CLASS_NAME = "helloWindow"
    WINDOW_NAME = "Hello, World"
     
    function WndProc(hwnd, uMsg, wParam, lParam)
        ps = PAINTSTRUCT:new()
        strMessage = string.format("Hello, Win32 GUI(Lua) World!")
        if (uMsg == WM_DESTROY) then
            PostQuitMessage(0)
        elseif (uMsg == WM_PAINT) then
            hdc = BeginPaint( hwnd, ps() )
            TextOut( hdc, 0, 0, strMessage, string.len(strMessage) )
            EndPaint( hwnd, ps() )
        else
            return DefWindowProc(hwnd, uMsg, wParam, lParam)
        end
        return nil
    end
     
    function WinMain()
        wcex = WNDCLASSEX:new()
        wcex.cbSize        = WNDCLASSEX.size
        wcex.style         = 0
        wcex.lpfnWndProc   = alien.callback(WndProc, { ret = "long", abi = "stdcall"; "pointer", "uint", "uint", "long" })
        wcex.cbClsExtra    = 0
        wcex.cbWndExtra    = 0
        wcex.hInstance     = nil
        wcex.hIcon         = nil
        wcex.hCursor       = nil
        wcex.hbrBackground = GetStockObject(COLOR_WINDOW+1)
        wcex.lpszMenuName  = nil
        wcex.lpszClassName = CLASS_NAME
        wcex.hIconSm       = nil
     
        RegisterClassEx(wcex())
     
        hwnd = CreateWindowEx(
            0,
            CLASS_NAME,
            WINDOW_NAME,
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            640,
            480,
            nil,
            nil,
            nil)
     
        ShowWindow(hwnd, SW_SHOWNORMAL)
        UpdateWindow(hwnd)
     
        msg = MSG:new()
        msg_ptr = msg()
     
        while (GetMessage(msg_ptr, nil, 0, 0) ~= 0) do
            TranslateMessage(msg_ptr)
            DispatchMessage(msg_ptr)
        end
    end
     
    function main()
        WinMain()
    end
     
    main()

    実行方法

    C:¥> wlua hello.lua

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(Lua) World!              |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  9. Hello, Win32 GUI(Python) World!

    Posted on 7月 15th, 2012 by cx20

    Win32 GUI(Python)

    Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
    以下は Python にて ctypes ライブラリを使用した Win32 GUI アプリケーション の例となっている。

    ソースコード

    import win32con
    import sys
    from ctypes import *
     
    WNDPROC = WINFUNCTYPE(c_long, c_int, c_uint, c_int, c_int)
     
    NULL            = c_int(0)
     
    WM_PAINT        = win32con.WM_PAINT
    WM_DESTROY      = win32con.WM_DESTROY
    CS_HREDRAW      = win32con.CS_HREDRAW
    CS_VREDRAW      = win32con.CS_VREDRAW
    IDI_APPLICATION = win32con.IDI_APPLICATION
    IDC_ARROW       = win32con.IDC_ARROW
    WHITE_BRUSH     = win32con.WHITE_BRUSH
    WS_OVERLAPPEDWINDOW = win32con.WS_OVERLAPPEDWINDOW
    CW_USEDEFAULT   = win32con.CW_USEDEFAULT
    SW_SHOWNORMAL   = win32con.SW_SHOWNORMAL
    SW_SHOW         = win32con.SW_SHOW
    SW_SHOWDEFAULT  = win32con.SW_SHOWDEFAULT
     
    GetModuleHandle = windll.kernel32.GetModuleHandleA
    BeginPaint      = windll.user32.BeginPaint
    EndPaint        = windll.user32.EndPaint
    PostQuitMessage = windll.user32.PostQuitMessage
    DefWindowProc   = windll.user32.DefWindowProcA
    CreateWindowEx  = windll.user32.CreateWindowExA
    CreateWindowEx.argtypes = [c_int, c_char_p, c_char_p, c_int, c_int, c_int, c_int, c_int, c_int, c_int, c_int, c_int]
    LoadIcon        = windll.user32.LoadIconA
    LoadCursor      = windll.user32.LoadCursorA
    RegisterClass   = windll.user32.RegisterClassA
    ShowWindow      = windll.user32.ShowWindow
    UpdateWindow    = windll.user32.UpdateWindow
    GetMessage      = windll.user32.GetMessageA
    TranslateMessage = windll.user32.TranslateMessage
    DispatchMessage = windll.user32.DispatchMessageA
    TextOut         = windll.gdi32.TextOutA
    GetStockObject  = windll.gdi32.GetStockObject
     
    class POINT(Structure):
        _fields_ = [('x', c_long),
                    ('y', c_long)]
     
    class MSG(Structure):
        _fields_ = [('hwnd', c_int),
                    ('message', c_uint),
                    ('wParam', c_int),
                    ('lParam', c_int),
                    ('time', c_int),
                    ('pt', POINT)]
     
    class WNDCLASS(Structure):
        _fields_ = [('style', c_uint),
                    ('lpfnWndProc', WNDPROC),
                    ('cbClsExtra', c_int),
                    ('cbWndExtra', c_int),
                    ('hInstance', c_int),
                    ('hIcon', c_int),
                    ('hCursor', c_int),
                    ('hbrBackground', c_int),
                    ('lpszMenuName', c_char_p),
                    ('lpszClassName', c_char_p)]
     
    class RECT(Structure):
        _fields_ = [('left', c_long),
                    ('top', c_long),
                    ('right', c_long),
                    ('bottom', c_long)]
     
    class PAINTSTRUCT(Structure):
        _fields_ = [('hdc', c_int),
                    ('fErase', c_int),
                    ('rcPaint', RECT),
                    ('fRestore', c_int),
                    ('fIncUpdate', c_int),
                    ('rgbReserved', c_char * 32)]
     
    def WndProc(hwnd, message, wParam, lParam):
        strMessage = "Hello, Win32 GUI(Python) World!"
        if message == WM_PAINT:
            ps = PAINTSTRUCT()
            hdc = BeginPaint( hwnd, byref(ps) )
            TextOut( hdc, 0, 0, strMessage, len(strMessage) )
            EndPaint( hwnd, byref(ps) )
            return 0
        elif message == WM_DESTROY:
            PostQuitMessage(0)
            return 0
     
        return DefWindowProc(hwnd, message, wParam, lParam)
     
    def WinMain():
        wndclass               = WNDCLASS()
        wndclass.style         = CS_HREDRAW | CS_VREDRAW
        wndclass.lpfnWndProc   = WNDPROC(WndProc)
        wndclass.cbClsExtra    = 0
        wndclass.cbWndExtra    = 0
        wndclass.hInstance     = GetModuleHandle(0)
        wndclass.hIcon         = LoadIcon(0, IDI_APPLICATION)
        wndclass.hCursor       = LoadCursor(0, IDC_ARROW)
        wndclass.hbrBackground = GetStockObject(WHITE_BRUSH)
        wndclass.lpszMenuName  = 0
        wndclass.lpszClassName = "helloWindow"
     
        RegisterClass(byref(wndclass))
     
        hwnd = CreateWindowEx(
            0,
            wndclass.lpszClassName,
            "Hello, World!",
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            640,
            480,
            0,
            0,
            wndclass.hInstance,
            0)
     
        ShowWindow(hwnd, SW_SHOWDEFAULT)
        UpdateWindow(hwnd)
     
        msg = MSG()
        pMsg = pointer(msg)
     
        while GetMessage( pMsg, NULL, 0, 0 ) != 0:
            TranslateMessage(pMsg)
            DispatchMessage(pMsg)
     
        return msg.wParam
     
    if __name__=='__main__':
        sys.exit(WinMain())

    実行方法

    C:¥> python hello.py

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(Python) World!           |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  10. Hello, Win32 GUI(Ruby) World!

    Posted on 7月 14th, 2012 by cx20

    Win32 GUI(Ruby)

    Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
    以下は Ruby による Win32 GUI アプリケーション の例となっている。
    なお、Win32 の構造体の定義に CStruct ライブラリを使用している。

    ソースコード

    require 'win32/api'
    require 'cstruct/win32struct'
     
    include Win32
     
    WS_VISIBLE      = 0x10000000
    WS_CAPTION      = 0x00C00000
    WS_SYSMENU      = 0x00080000
    WS_MINIMIZEBOX  = 0x00020000
    WS_MAXIMIZEBOX  = 0x00010000
    WS_THICKFRAME   = 0x00040000
    WS_OVERLAPPED   = 0x00000000
     
    WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
     
    WM_CREATE       = 0x0001
    WM_DESTROY      = 0x0002
    WM_PAINT        = 0x000F
    WM_CLOSE        = 0x0010
    WM_COMMAND      = 0x0111
     
    CS_VREDRAW      = 0x0001
    CS_HREDRAW      = 0x0002
    COLOR_WINDOW    = 5
     
    CW_USEDEFAULT   = -2147483648 #0x80000000
     
    SW_SHOW         = 5
    SW_SHOWDEFAULT  = 10
     
    Memset          = API.new('memset', 'PLL', 'L', 'msvcrt')
    LocalAlloc      = API.new('LocalAlloc', 'LL', 'L', 'kernel32')
    GetModuleHandle = API.new('GetModuleHandle', 'P', 'L', 'kernel32')
    RegisterClass   = API.new('RegisterClass', 'P', 'L', 'user32')
    RegisterClassEx = API.new('RegisterClassEx', 'P', 'L', 'user32')
    CloseWindow     = API.new('CloseWindow', 'L', 'B', 'user32')
    CreateWindowEx  = API.new('CreateWindowEx', 'LPPLIIIILLLL', 'L', 'user32')
    ShowWindow      = API.new('ShowWindow', 'LL', 'B', 'user32')
    UpdateWindow    = API.new('UpdateWindow', 'L', 'B', 'user32')
    BeginPaint      = API.new('BeginPaint', 'LP', 'L', 'user32')
    EndPaint        = API.new('EndPaint', 'LP', 'L', 'user32')
    PostQuitMessage = API.new('PostQuitMessage', 'I', 'V', 'user32')
    DefWindowProc   = API.new('DefWindowProc', 'LLLL', 'L', 'user32')
    GetMessage      = API.new('GetMessage', 'PLII', 'L', 'user32')
    DispatchMessage = API.new('DispatchMessage', 'P', 'L', 'user32')
    TranslateMessage = API.new('TranslateMessage', 'P', 'B', 'user32')
    TextOut         = API.new('TextOut', 'LLLPL', 'B', 'gdi32' );
     
    class POINT < Win32Struct
        LONG    :x
        LONG    :y
    end
     
    class MSG < Win32Struct
        uint32  :hwnd
        UINT    :message
        WPARAM  :wParam
        LPARAM  :lParam
        DWORD   :time
        POINT   :pt
    end
     
    class WNDCLASSA < Win32Struct
        UINT    :style
        uint32  :lpfnWndProc
        int32   :cbClsExtra
        int32   :cbWndExtra
        HINSTANCE   :hInstance
        HICON   :hIcon
        HCURSOR :hCursor
        HBRUSH  :hbrBackground
        LPCSTR  :lpszMenuName
        LPCSTR  :lpszClassName
    end
     
    class RECT < Win32Struct
        LONG    :left
        LONG    :top
        LONG    :right
        LONG    :bottom
    end
     
    class PAINTSTRUCT < Win32Struct
        HDC     :hdc
        BOOL    :fErase
        RECT    :rcPaint
        BOOL    :fRestore
        BOOL    :fIncUpdate
        BYTE    :rgbReserved,[32]
    end
     
    @window_proc = API::Callback.new('LLLL', 'I') do |hwnd, msg, wparam, lparam|
        ret = 0
        strMessage = "Hello, Win32 GUI(Ruby) World!"
        case msg
        when WM_PAINT
            ps  = PAINTSTRUCT.new
            hdc = BeginPaint.call(hwnd, ps.data)
            TextOut.call(hdc, 0, 0, strMessage, strMessage.length);
            EndPaint.call(hwnd, ps.data)
        when WM_DESTROY
            PostQuitMessage.call(0)
        else 
            ret = DefWindowProc.call(hwnd, msg, wparam, lparam)
        end
        ret
    end
     
    def alloc_string_buffer init_string, max_length
        buffer_pointer = LocalAlloc.call(0, max_length)
        buffer_addr = buffer_pointer
        Memset.call(buffer_addr, 0, max_length)
     
        init_string.each_byte do |byte|  
            Memset.call(buffer_pointer, byte, 1)
            buffer_pointer += 1
        end  
        buffer_addr
    end
     
    def WinMain instance, cmd_show
        msg = MSG.new
     
        wc = WNDCLASSA.new
        wc.style         = 0
        wc.lpfnWndProc   = @window_proc.address
        wc.cbClsExtra    = 0
        wc.cbWndExtra    = 0
        wc.hInstance     = instance
        wc.hIcon         = 0
        wc.hCursor       = 0
        wc.hbrBackground = (COLOR_WINDOW+1)
        wc.lpszMenuName  = 0
        wc.lpszClassName = alloc_string_buffer 'helloWindow', 256
     
        RegisterClass.call(wc.data)
     
        hwnd = CreateWindowEx.call(
            0,
            "helloWindow",
            "Hello, World!",
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            640,
            480,
            0,
            0,
            wc.hInstance,
            0
        )
     
        ShowWindow.call(hwnd, cmd_show)
        UpdateWindow.call(hwnd)
     
        while(GetMessage.call(msg.data, 0, 0, 0) > 0)
            TranslateMessage.call(msg.data)
            DispatchMessage.call(msg.data)
        end
     
    end
     
    def main
        instance = GetModuleHandle.call(0)
        WinMain instance, SW_SHOW
    end
     
    main

    ライブラリ導入方法

    C:¥> gem install cstruct

    実行方法

    C:¥> ruby hello.rb

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(Ruby) World!             |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+