Archive for the ‘Win32 API’ Category

  1. Hello, Win32 API(SWT) World!

    Posted on 1月 6th, 2013 by cx20

    Win32 API(SWT)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は Java の GUI ツールキット SWT の非公開 API を使用した Win32 API 呼出しの例となっている。

    ソースコード

    import org.eclipse.swt.internal.win32.OS;
    import org.eclipse.swt.internal.win32.TCHAR;
     
    public class Hello {
        public static void main(String[] args) {
            TCHAR lpText = new TCHAR(0, "Hello, Win32 API World!", true);
            TCHAR lpCaption = new TCHAR(0, "Hello, World", true);
            OS.MessageBox(0, lpText, lpCaption, OS.MB_OK );
        }
    }

    コンパイル&実行方法

    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!
    ---------------------------
    Hello, Win32 API World!
    ---------------------------
    OK   
    ---------------------------
  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(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!                |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  5. Hello, Win32 GUI(VB.NET) World!

    Posted on 7月 10th, 2012 by cx20

    Win32 GUI(VB.NET)

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

    ソースコード

    Imports System.Runtime.InteropServices
     
    Public Class HelloWindow
        Const WS_CAPTION As Integer = &HC00000
        Const WS_MAXIMIZEBOX As Integer = &H10000
        Const WS_MINIMIZEBOX As Integer = &H20000
        Const WS_OVERLAPPED As Integer = &H0
        Const WS_SYSMENU As Integer = &H80000
        Const WS_THICKFRAME As Integer = &H40000
        Const WS_OVERLAPPEDWINDOW As Integer = ( _
            WS_OVERLAPPED Or _
            WS_CAPTION Or _
            WS_SYSMENU Or _
            WS_THICKFRAME Or _
            WS_MINIMIZEBOX Or _
            WS_MAXIMIZEBOX)
     
        Const COLOR_WINDOW As Integer = 5
        Const COLOR_BTNFACE As Integer = 15
     
        Const CS_VREDRAW As Integer = &H1
        Const CS_HREDRAW As Integer = &H2
        Const CW_USEDEFAULT As Integer = &H80000000
     
        Const IDI_APPLICATION As Integer = 32512
        Const IDC_ARROW As Integer = 32512
     
        Const LTGRAY_BRUSH As Integer = 1
     
        Const SW_SHOWNORMAL As Integer = 1
        Const SW_SHOWDEFAULT As Integer = 10
     
        Const WM_DESTROY As Integer = &H2
        Const WM_PAINT As Integer = &HF
     
        Delegate Function WndProcDelgate( _
            ByVal hWnd As IntPtr, _
            ByVal Message As Integer, _
            ByVal wParam As IntPtr, _
            ByVal lParam As IntPtr _
        ) As IntPtr
     
        <StructLayout(LayoutKind.Sequential)> _
        Structure POINTAPI
            Public x As Integer
            Public y As Integer
        End Structure
     
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
        Structure MSG
            Public hWnd As IntPtr
            Public Message As Integer
            Public wParam As IntPtr
            Public lParam As IntPtr
            Public time As Integer
            Public pt As POINTAPI
        End Structure
     
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
        Structure WNDCLASSEX
            Public cbSize As Integer
            Public style As Integer
            Public lpfnWndProc As WndProcDelgate
            Public cbClsExtra As Integer
            Public cbWndExtra As Integer
            Public hInstance As IntPtr
            Public hIcon As IntPtr
            Public hCursor As IntPtr
            Public hbrBackground As IntPtr
            Public lpszMenuName As String
            Public lpszClassName As String
            Public hIconSm As IntPtr
        End Structure
     
        <StructLayout(LayoutKind.Sequential)> _
        Structure RECT
            Public Left As Integer
            Public Top As Integer
            Public Right As Integer
            Public Bottom As Integer
        End Structure
     
        <StructLayout(LayoutKind.Sequential)> _
        Structure PAINTSTRUCT
            Public hdc As IntPtr
            Public fErase As Integer
            Public rcPaint As RECT
            Public fRestore As Integer
            Public fIncUpdate As Integer
            <MarshalAs(UnmanagedType.ByValArray, SizeConst := 32)> _
            Public rgbReserved As Byte()
        End Structure
     
        Declare Auto Function LoadCursor Lib "user32" ( _
            ByVal hInstance As IntPtr, _
            ByVal lpCursorName As IntPtr _
        ) As IntPtr
     
        Declare Auto Function LoadIcon Lib "user32" ( _
            ByVal hInstance As IntPtr, _
            ByVal lpIconName As IntPtr _
        ) As IntPtr
     
        Declare Auto Function RegisterClassEx Lib "user32" ( _
            ByRef pcWndClassEx As WNDCLASSEX _
        ) As Integer
     
        Declare Auto Function CreateWindowEx Lib "user32" ( _
            ByVal dwExStyle As Integer, _
            ByVal lpClassName As String, _
            ByVal lpWindowName As String, _
            ByVal dwStyle As Integer, _
            ByVal x As Integer, _
            ByVal y As Integer, _
            ByVal nWidth As Integer, _
            ByVal nHeight As Integer, _
            ByVal hWndParent As IntPtr, _
            ByVal hMenu As IntPtr, _
            ByVal hInstance As IntPtr, _
            ByVal lpParam As IntPtr _
        ) As IntPtr
     
        Declare Function ShowWindow Lib "user32" ( _
            ByVal hWnd As IntPtr, _
            ByVal nCmdShow As Integer _
        ) As Boolean
     
        Declare Function UpdateWindow Lib "user32" (ByVal hWnd As IntPtr) As Boolean
     
        Declare Auto Function GetMessage Lib "user32" ( _
            ByRef lpMsg As MSG, _
            ByVal hWnd As IntPtr, _
            ByVal wMsgFilterMin As Integer, _
            ByVal wMsgFilterMax As Integer _
         ) As Boolean
     
        Declare Function TranslateMessage Lib "user32" ( _
            ByRef lpMsg As MSG _
        ) As Boolean
     
        Declare Auto Function DispatchMessage Lib "user32" ( _
            ByRef lpMsg As MSG _
        ) As IntPtr
     
        Declare Sub PostQuitMessage Lib "user32" ( _
            ByVal nExitCode As Integer _
        )
     
        Declare Function BeginPaint Lib "user32" ( _
            ByVal hwnd As IntPtr, _
            ByRef lpPaint As PAINTSTRUCT _
        ) As IntPtr
     
        Declare Function EndPaint Lib "user32" ( _
            ByVal hwnd As IntPtr, _
            ByRef lpPaint As PAINTSTRUCT _
        ) As IntPtr
     
        Declare Auto Function TextOut Lib "gdi32" ( _
            ByVal hdc As IntPtr, _
            ByVal x As Integer, _
            ByVal y As Integer, _
            ByVal lpString As String, _
            ByVal nCount As Integer _
        ) As Integer
     
        Declare Function GetStockObject Lib "gdi32" ( _
            ByVal nIndex As Integer _
        ) As IntPtr
     
        Declare Auto Function DefWindowProc Lib "user32" ( _
            ByVal hWnd As IntPtr, _
            ByVal wMsg As Integer, _
            ByVal wParam As IntPtr, _
            ByVal lParam As IntPtr _
        ) As IntPtr
     
        Function WndProc( _
            ByVal hWnd As IntPtr, _
            ByVal msg As Integer, _
            ByVal wParam As IntPtr, _
            ByVal lParam As IntPtr _
        ) As IntPtr
     
            Dim ps As New PAINTSTRUCT
            Dim hdc As IntPtr
            Dim strMessage As String
            strMessage = "Hello, Win32 GUI(VB.NET) World!"
     
            Select Case msg
                Case WM_PAINT
                    hdc = BeginPaint(hwnd, ps)
                    TextOut( hdc, 0, 0, strMessage, Len(strMessage) )
                    EndPaint( hwnd, ps )
                Case WM_DESTROY
                    PostQuitMessage(0)
                Case Else
                    Return DefWindowProc(hWnd, msg, wParam, lParam)
            End Select
     
            Return IntPtr.Zero
        End Function
     
        Public Function WinMain() As Integer
            Const CLASS_NAME As String = "helloWindow"
            Const WINDOW_NAME As String = "Hello, World!"
     
            Dim hInstance As IntPtr = Marshal.GetHINSTANCE(GetType(HelloWindow).Module)
            Dim hWnd As IntPtr
            Dim msg As MSG
     
            Dim wcex As New WNDCLASSEX
            With wcex
                .cbSize = Marshal.SizeOf(wcex)
                .style = CS_HREDRAW Or CS_VREDRAW
                .lpfnWndProc = New WndProcDelgate(AddressOf WndProc)
                .cbClsExtra = 0
                .cbWndExtra = 0
                .hInstance = hInstance
                .hIcon = LoadIcon(hInstance, New IntPtr(IDI_APPLICATION))
                .hCursor = LoadCursor(hInstance, New IntPtr(IDC_ARROW))
                .hbrBackground = New IntPtr(COLOR_WINDOW + 1)
                .lpszMenuName = Nothing
                .lpszClassName = CLASS_NAME
                .hIconSm = LoadIcon(hInstance, New IntPtr(IDI_APPLICATION))
            End With
     
            RegisterClassEx(wcex)
     
            hWnd = CreateWindowEx( _
                0, _
                CLASS_NAME, _
                WINDOW_NAME, _
                WS_OVERLAPPEDWINDOW, _
                CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, _
                IntPtr.Zero, IntPtr.Zero, hInstance, IntPtr.Zero)
     
            ShowWindow(hWnd, SW_SHOWDEFAULT)
            UpdateWindow(hWnd)
     
            Do While GetMessage(msg, IntPtr.Zero, 0, 0)
                TranslateMessage(msg)
                DispatchMessage(msg)
            Loop
     
            Return CType(msg.wParam, Integer)
        End Function
     
        Public Shared Sub Main()
            Dim hello As New HelloWindow
            hello.WinMain()
        End Sub
    End Class

    コンパイル方法

    C:¥> vbc /target:winexe Hello.vb

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(VB.NET) World!           |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  6. Hello, Win32 GUI(C#) World!

    Posted on 7月 9th, 2012 by cx20

    Win32 GUI(C#)

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

    ソースコード

    using System;
    using System.Runtime.InteropServices;
     
    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(C#) 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(string[] args)
        {
            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]
        static int Main(string[] args)
        {
            return WinMain( args );
        }
    }

    コンパイル方法

    C:¥> csc /target:winexe Hello.cs

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(C#) World!               |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  7. Hello, Win32 GUI(VBA) World!

    Posted on 7月 8th, 2012 by cx20

    Win32 GUI(VBA)

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

    ソースコード

    Private Const WS_OVERLAPPED As Long = &H0
    Private Const WS_MAXIMIZEBOX As Long = &H10000
    Private Const WS_MINIMIZEBOX As Long = &H20000
    Private Const WS_THICKFRAME As Long = &H40000
    Private Const WS_SYSMENU As Long = &H80000
    Private Const WS_CAPTION As Long = &HC00000
    Private Const WS_EX_APPWINDOW As Long = &H40000
    Private Const WS_OVERLAPPEDWINDOW As Long = (WS_OVERLAPPED Or WS_CAPTION Or WS_SYSMENU Or WS_THICKFRAME Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX)
     
    Private Const CS_VREDRAW As Long = &H1
    Private Const CS_HREDRAW As Long = &H2
     
    Private Const IDI_APPLICATION As Long = 32512
    Private Const IDC_ARROW As Long = 32512
     
    Private Const COLOR_WINDOW As Long = 5
    Private Const COLOR_BTNFACE As Long = 15
     
    Private Const WHITE_BRUSH As Long = 0
     
    Private Const CW_USEDEFAULT As Long = &H80000000
     
    Private Const SW_SHOWNORMAL As Long = 1
    Private Const SW_SHOW As Long = 5
    Private Const SW_SHOWDEFAULT As Long = 10
     
    Private Const WM_DESTROY As Long = &H2
    Private Const WM_PAINT As Long = &HF
     
    Private Const CLASS_NAME As String = "helloWindow"
    Private Const WINDOW_NAME As String = "Hello, World!"
     
    Private Type POINTAPI
        x As Long
        y As Long
    End Type
     
    Private Type MSG
        hwnd As Long
        message As Long
        wParam As Long
        lParam As Long
        time As Long
        pt As POINTAPI
    End Type
     
    Private Type WNDCLASSEX
        cbSize As Long
        style As Long
        lpfnWndProc As Long
        cbClsExtra As Long
        cbWndExtra As Long
        hInstance As Long
        hIcon As Long
        hCursor As Long
        hbrBackground As Long
        lpszMenuName As String
        lpszClassName As String
        hIconSm As Long
    End Type
     
    Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
     
    Type PAINTSTRUCT
        hdc As Long
        fErase As Long
        rcPaint As RECT
        fRestore As Long
        fIncUpdate As Long
        rgbReserved As Byte
    End Type
     
    Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As Long) As Long
    Private Declare Function LoadIcon Lib "user32" Alias "LoadIconA" (ByVal hInstance As Long, ByVal lpIconName As Long) As Long
    Private Declare Function LoadCursor Lib "user32" Alias "LoadCursorA" (ByVal hInstance As Long, ByVal lpCursorName As Long) As Long
    Private Declare Function GetStockObject Lib "gdi32" (ByVal fnObject As Long) As Long
    Private Declare Function RegisterClassEx Lib "user32" Alias "RegisterClassExA" (lpwcx As WNDCLASSEX) As Long
    Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long
    Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
    Private Declare Function UpdateWindow Lib "user32" (ByVal lhwnd As Long) As Long
    Private Declare Function GetMessage Lib "user32" Alias "GetMessageA" (lpMsg As MSG, ByVal hwnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long) As Long
    Private Declare Function TranslateMessage Lib "user32" (lpMsg As MSG) As Long
    Private Declare Function DispatchMessage Lib "user32" Alias "DispatchMessageA" (lpMsg As MSG) As Long
    Private Declare Sub PostQuitMessage Lib "user32" (ByVal nExitCode As Long)
    Private Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Function BeginPaint Lib "user32" (ByVal hwnd As Long, lpPaint As PAINTSTRUCT) As Long
    Private Declare Function EndPaint Lib "user32" (ByVal hwnd As Long, lpPaint As PAINTSTRUCT) As Long
    Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
     
    Private Function FuncPtr(ByVal p As Long) As Long
        FuncPtr = p
    End Function
     
    Private Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        Dim ps As PAINTSTRUCT
        Dim hdc As Long
        Dim strMessage As String
        strMessage = "Hello, Win32 GUI(VBA) World!"
     
        Select Case uMsg
        Case WM_PAINT
            hdc = BeginPaint(hwnd, ps)
            TextOut hdc, 0, 0, strMessage, Len(strMessage)
            EndPaint hwnd, ps
        Case WM_DESTROY
            Call PostQuitMessage(0)
        Case Else
            WindowProc = DefWindowProc(hwnd, uMsg, wParam, lParam)
            Exit Function
        End Select
        WindowProc = 0
    End Function
     
    Public Function WinMain() As Integer
        Dim wcex As WNDCLASSEX
        Dim hwnd As Long
        Dim message As MSG
        Dim pfnc As Long
        wcex.cbSize = Len(wcex)
        wcex.style = CS_HREDRAW Or CS_VREDRAW
        wcex.lpfnWndProc = FuncPtr(AddressOf WindowProc)
        wcex.cbClsExtra = 0
        wcex.cbWndExtra = 0
        wcex.hInstance = GetModuleHandle(0)
        wcex.hIcon = LoadIcon(0, IDI_APPLICATION)
        wcex.hCursor = LoadCursor(0, IDC_ARROW)
        wcex.hbrBackground = COLOR_WINDOW + 1
        wcex.lpszMenuName = vbNullString
        wcex.lpszClassName = CLASS_NAME
        wcex.hIconSm = LoadIcon(0, IDI_APPLICATION)
     
        Call RegisterClassEx(wcex)
     
        hwnd = CreateWindowEx( _
            0, _
            CLASS_NAME, _
            WINDOW_NAME, _
            WS_OVERLAPPEDWINDOW, _
            CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, _
            0, 0, wcex.hInstance, 0)
     
        Call ShowWindow(hwnd, SW_SHOWDEFAULT)
        Call UpdateWindow(hwnd)
     
        Do While (GetMessage(message, 0, 0, 0))
            Call TranslateMessage(message)
            Call DispatchMessage(message)
        Loop
     
        WinMain = message.wParam
    End Function
     
    Public Sub Main()
        Call WinMain
    End Sub

    なお、Office 2010 では AddressOf 演算子が使えなくなっている為、動作確認をすることができなかった。

    実行結果

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

    Posted on 7月 7th, 2012 by cx20

    Win32 GUI(VB6)

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

    ソースコード

    Private Const WS_OVERLAPPED As Long = &H0
    Private Const WS_MAXIMIZEBOX As Long = &H10000
    Private Const WS_MINIMIZEBOX As Long = &H20000
    Private Const WS_THICKFRAME As Long = &H40000
    Private Const WS_SYSMENU As Long = &H80000
    Private Const WS_CAPTION As Long = &HC00000
    Private Const WS_EX_APPWINDOW As Long = &H40000
    Private Const WS_OVERLAPPEDWINDOW As Long = (WS_OVERLAPPED Or WS_CAPTION Or WS_SYSMENU Or WS_THICKFRAME Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX)
     
    Private Const CS_VREDRAW As Long = &H1
    Private Const CS_HREDRAW As Long = &H2
     
    Private Const IDI_APPLICATION As Long = 32512
    Private Const IDC_ARROW As Long = 32512
     
    Private Const COLOR_WINDOW As Long = 5
    Private Const COLOR_BTNFACE As Long = 15
     
    Private Const WHITE_BRUSH As Long = 0
     
    Private Const CW_USEDEFAULT As Long = &H80000000
     
    Private Const SW_SHOWNORMAL As Long = 1
    Private Const SW_SHOW As Long = 5
    Private Const SW_SHOWDEFAULT As Long = 10
     
    Private Const WM_DESTROY As Long = &H2
    Private Const WM_PAINT As Long = &HF
     
    Private Const CLASS_NAME As String = "helloWindow"
    Private Const WINDOW_NAME As String = "Hello, World!"
     
    Private Type POINTAPI
        x As Long
        y As Long
    End Type
     
    Private Type MSG
        hwnd As Long
        message As Long
        wParam As Long
        lParam As Long
        time As Long
        pt As POINTAPI
    End Type
     
    Private Type WNDCLASSEX
        cbSize As Long
        style As Long
        lpfnWndProc As Long
        cbClsExtra As Long
        cbWndExtra As Long
        hInstance As Long
        hIcon As Long
        hCursor As Long
        hbrBackground As Long
        lpszMenuName As String
        lpszClassName As String
        hIconSm As Long
    End Type
     
    Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
     
    Type PAINTSTRUCT
        hdc As Long
        fErase As Long
        rcPaint As RECT
        fRestore As Long
        fIncUpdate As Long
        rgbReserved As Byte
    End Type
     
    Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As Long) As Long
    Private Declare Function LoadIcon Lib "user32" Alias "LoadIconA" (ByVal hInstance As Long, ByVal lpIconName As Long) As Long
    Private Declare Function LoadCursor Lib "user32" Alias "LoadCursorA" (ByVal hInstance As Long, ByVal lpCursorName As Long) As Long
    Private Declare Function GetStockObject Lib "gdi32" (ByVal fnObject As Long) As Long
    Private Declare Function RegisterClassEx Lib "user32" Alias "RegisterClassExA" (lpwcx As WNDCLASSEX) As Long
    Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long
    Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
    Private Declare Function UpdateWindow Lib "user32" (ByVal lhwnd As Long) As Long
    Private Declare Function GetMessage Lib "user32" Alias "GetMessageA" (lpMsg As MSG, ByVal hwnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long) As Long
    Private Declare Function TranslateMessage Lib "user32" (lpMsg As MSG) As Long
    Private Declare Function DispatchMessage Lib "user32" Alias "DispatchMessageA" (lpMsg As MSG) As Long
    Private Declare Sub PostQuitMessage Lib "user32" (ByVal nExitCode As Long)
    Private Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Function BeginPaint Lib "user32" (ByVal hwnd As Long, lpPaint As PAINTSTRUCT) As Long
    Private Declare Function EndPaint Lib "user32" (ByVal hwnd As Long, lpPaint As PAINTSTRUCT) As Long
    Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
     
    Private Function FuncPtr(ByVal p As Long) As Long
        FuncPtr = p
    End Function
     
    Private Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        Dim ps As PAINTSTRUCT
        Dim hdc As Long
        Dim strMessage As String
        strMessage = "Hello, Win32 GUI(VB6) World!"
     
        Select Case uMsg
        Case WM_PAINT
            hdc = BeginPaint(hwnd, ps)
            TextOut hdc, 0, 0, strMessage, Len(strMessage)
            EndPaint hwnd, ps
        Case WM_DESTROY
            Call PostQuitMessage(0)
        Case Else
            WindowProc = DefWindowProc(hwnd, uMsg, wParam, lParam)
            Exit Function
        End Select
        WindowProc = 0
    End Function
     
    Public Function WinMain() As Integer
        Dim wcex As WNDCLASSEX
        Dim hwnd As Long
        Dim message As MSG
        Dim pfnc As Long
        wcex.cbSize = Len(wcex)
        wcex.style = CS_HREDRAW Or CS_VREDRAW
        wcex.lpfnWndProc = FuncPtr(AddressOf WindowProc)
        wcex.cbClsExtra = 0
        wcex.cbWndExtra = 0
        wcex.hInstance = GetModuleHandle(0)
        wcex.hIcon = LoadIcon(0, IDI_APPLICATION)
        wcex.hCursor = LoadCursor(0, IDC_ARROW)
        wcex.hbrBackground = COLOR_WINDOW + 1
        wcex.lpszMenuName = vbNullString
        wcex.lpszClassName = CLASS_NAME
        wcex.hIconSm = LoadIcon(0, IDI_APPLICATION)
     
        Call RegisterClassEx(wcex)
     
        hwnd = CreateWindowEx( _
            0, _
            CLASS_NAME, _
            WINDOW_NAME, _
            WS_OVERLAPPEDWINDOW, _
            CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, _
            0, 0, wcex.hInstance, 0)
     
        Call ShowWindow(hwnd, SW_SHOWDEFAULT)
        Call UpdateWindow(hwnd)
     
        Do While (GetMessage(message, 0, 0, 0))
            Call TranslateMessage(message)
            Call DispatchMessage(message)
        Loop
     
        WinMain = message.wParam
    End Function
     
    Public Sub Main()
        Call WinMain
    End Sub

    コンパイル方法

    C:¥> vb6 /make hello.vbp

    実行結果

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

    Posted on 7月 6th, 2012 by cx20

    Win32 GUI(MASM)

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

    ソースコード

    ; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.40219.01 
     
            TITLE   hello.c
            .686P
            .XMM
            include listing.inc
            .model  flat
     
    INCLUDELIB LIBCMT
    INCLUDELIB OLDNAMES
     
    _DATA   SEGMENT
    $SG79977 DB     'Hello, Win32 GUI(MASM) World!', 00H
            ORG $+2
    $SG79995 DB     'helloWindow', 00H
    $SG79997 DB     'Hello, World!', 00H
    _DATA   ENDS
    PUBLIC  __$ArrayPad$
    PUBLIC  _WndProc@16
    EXTRN   __imp__DefWindowProcA@16:PROC
    EXTRN   __imp__PostQuitMessage@4:PROC
    EXTRN   __imp__EndPaint@8:PROC
    EXTRN   __imp__TextOutA@20:PROC
    EXTRN   __imp__lstrlenA@4:PROC
    EXTRN   __imp__BeginPaint@8:PROC
    EXTRN   ___security_cookie:DWORD
    EXTRN   @__security_check_cookie@4:PROC
    ; Function compile flags: /Odtp
    _TEXT   SEGMENT
    tv64 = -84                                              ; size = 4
    _hdc$ = -80                                             ; size = 4
    _lpszMessage$ = -76                                     ; size = 4
    _ps$ = -72                                              ; size = 64
    __$ArrayPad$ = -4                                       ; size = 4
    _hWnd$ = 8                                              ; size = 4
    _message$ = 12                                          ; size = 4
    _wParam$ = 16                                           ; size = 4
    _lParam$ = 20                                           ; size = 4
    _WndProc@16 PROC
    ; File hello.c
    ; Line 5
            push    ebp
            mov     ebp, esp
            sub     esp, 84                                 ; 00000054H
            mov     eax, DWORD PTR ___security_cookie
            xor     eax, ebp
            mov     DWORD PTR __$ArrayPad$[ebp], eax
    ; Line 8
            mov     DWORD PTR _lpszMessage$[ebp], OFFSET $SG79977
    ; Line 10
            mov     eax, DWORD PTR _message$[ebp]
            mov     DWORD PTR tv64[ebp], eax
            cmp     DWORD PTR tv64[ebp], 2
            je      SHORT $LN2@WndProc
            cmp     DWORD PTR tv64[ebp], 15                 ; 0000000fH
            je      SHORT $LN3@WndProc
            jmp     SHORT $LN1@WndProc
    $LN3@WndProc:
    ; Line 13
            lea     ecx, DWORD PTR _ps$[ebp]
            push    ecx
            mov     edx, DWORD PTR _hWnd$[ebp]
            push    edx
            call    DWORD PTR __imp__BeginPaint@8
            mov     DWORD PTR _hdc$[ebp], eax
    ; Line 14
            mov     eax, DWORD PTR _lpszMessage$[ebp]
            push    eax
            call    DWORD PTR __imp__lstrlenA@4
            push    eax
            mov     ecx, DWORD PTR _lpszMessage$[ebp]
            push    ecx
            push    0
            push    0
            mov     edx, DWORD PTR _hdc$[ebp]
            push    edx
            call    DWORD PTR __imp__TextOutA@20
    ; Line 15
            lea     eax, DWORD PTR _ps$[ebp]
            push    eax
            mov     ecx, DWORD PTR _hWnd$[ebp]
            push    ecx
            call    DWORD PTR __imp__EndPaint@8
    ; Line 16
            jmp     SHORT $LN4@WndProc
    $LN2@WndProc:
    ; Line 18
            push    0
            call    DWORD PTR __imp__PostQuitMessage@4
    ; Line 19
            jmp     SHORT $LN4@WndProc
    $LN1@WndProc:
    ; Line 21
            mov     edx, DWORD PTR _lParam$[ebp]
            push    edx
            mov     eax, DWORD PTR _wParam$[ebp]
            push    eax
            mov     ecx, DWORD PTR _message$[ebp]
            push    ecx
            mov     edx, DWORD PTR _hWnd$[ebp]
            push    edx
            call    DWORD PTR __imp__DefWindowProcA@16
            jmp     SHORT $LN6@WndProc
    $LN4@WndProc:
    ; Line 25
            xor     eax, eax
    $LN6@WndProc:
    ; Line 26
            mov     ecx, DWORD PTR __$ArrayPad$[ebp]
            xor     ecx, ebp
            call    @__security_check_cookie@4
            mov     esp, ebp
            pop     ebp
            ret     16                                      ; 00000010H
    _WndProc@16 ENDP
    _TEXT   ENDS
    PUBLIC  _WinMain@16
    EXTRN   __imp__DispatchMessageA@4:PROC
    EXTRN   __imp__TranslateMessage@4:PROC
    EXTRN   __imp__GetMessageA@16:PROC
    EXTRN   __imp__UpdateWindow@4:PROC
    EXTRN   __imp__ShowWindow@8:PROC
    EXTRN   __imp__CreateWindowExA@48:PROC
    EXTRN   __imp__RegisterClassExA@4:PROC
    EXTRN   __imp__LoadCursorA@8:PROC
    EXTRN   __imp__LoadIconA@8:PROC
    ; Function compile flags: /Odtp
    _TEXT   SEGMENT
    _lpszClassName$ = -88                                   ; size = 4
    _msg$ = -84                                             ; size = 28
    _wcex$ = -56                                            ; size = 48
    _hWnd$ = -8                                             ; size = 4
    _lpszWindowName$ = -4                                   ; size = 4
    _hInstance$ = 8                                         ; size = 4
    _hPrevInstance$ = 12                                    ; size = 4
    _lpCmdLine$ = 16                                        ; size = 4
    _nCmdShow$ = 20                                         ; size = 4
    _WinMain@16 PROC
    ; Line 29
            push    ebp
            mov     ebp, esp
            sub     esp, 88                                 ; 00000058H
    ; Line 30
            mov     DWORD PTR _lpszClassName$[ebp], OFFSET $SG79995
    ; Line 31
            mov     DWORD PTR _lpszWindowName$[ebp], OFFSET $SG79997
    ; Line 36
            mov     DWORD PTR _wcex$[ebp], 48               ; 00000030H
    ; Line 37
            mov     DWORD PTR _wcex$[ebp+4], 3
    ; Line 38
            mov     DWORD PTR _wcex$[ebp+8], OFFSET _WndProc@16
    ; Line 39
            mov     DWORD PTR _wcex$[ebp+12], 0
    ; Line 40
            mov     DWORD PTR _wcex$[ebp+16], 0
    ; Line 41
            mov     eax, DWORD PTR _hInstance$[ebp]
            mov     DWORD PTR _wcex$[ebp+20], eax
    ; Line 42
            push    32512                                   ; 00007f00H
            mov     ecx, DWORD PTR _hInstance$[ebp]
            push    ecx
            call    DWORD PTR __imp__LoadIconA@8
            mov     DWORD PTR _wcex$[ebp+24], eax
    ; Line 43
            push    32512                                   ; 00007f00H
            push    0
            call    DWORD PTR __imp__LoadCursorA@8
            mov     DWORD PTR _wcex$[ebp+28], eax
    ; Line 44
            mov     DWORD PTR _wcex$[ebp+32], 6
    ; Line 45
            mov     DWORD PTR _wcex$[ebp+36], 0
    ; Line 46
            mov     edx, DWORD PTR _lpszClassName$[ebp]
            mov     DWORD PTR _wcex$[ebp+40], edx
    ; Line 47
            push    32512                                   ; 00007f00H
            mov     eax, DWORD PTR _wcex$[ebp+20]
            push    eax
            call    DWORD PTR __imp__LoadIconA@8
            mov     DWORD PTR _wcex$[ebp+44], eax
    ; Line 49
            lea     ecx, DWORD PTR _wcex$[ebp]
            push    ecx
            call    DWORD PTR __imp__RegisterClassExA@4
    ; Line 56
            push    0
            mov     edx, DWORD PTR _hInstance$[ebp]
            push    edx
            push    0
            push    0
            push    480                                     ; 000001e0H
            push    640                                     ; 00000280H
            push    -2147483648                             ; 80000000H
            push    -2147483648                             ; 80000000H
            push    13565952                                ; 00cf0000H
            mov     eax, DWORD PTR _lpszWindowName$[ebp]
            push    eax
            mov     ecx, DWORD PTR _lpszClassName$[ebp]
            push    ecx
            push    0
            call    DWORD PTR __imp__CreateWindowExA@48
            mov     DWORD PTR _hWnd$[ebp], eax
    ; Line 58
            push    10                                      ; 0000000aH
            mov     edx, DWORD PTR _hWnd$[ebp]
            push    edx
            call    DWORD PTR __imp__ShowWindow@8
    ; Line 59
            mov     eax, DWORD PTR _hWnd$[ebp]
            push    eax
            call    DWORD PTR __imp__UpdateWindow@4
    $LN2@WinMain:
    ; Line 61
            push    0
            push    0
            push    0
            lea     ecx, DWORD PTR _msg$[ebp]
            push    ecx
            call    DWORD PTR __imp__GetMessageA@16
            test    eax, eax
            je      SHORT $LN1@WinMain
    ; Line 63
            lea     edx, DWORD PTR _msg$[ebp]
            push    edx
            call    DWORD PTR __imp__TranslateMessage@4
    ; Line 64
            lea     eax, DWORD PTR _msg$[ebp]
            push    eax
            call    DWORD PTR __imp__DispatchMessageA@4
    ; Line 65
            jmp     SHORT $LN2@WinMain
    $LN1@WinMain:
    ; Line 67
            mov     eax, DWORD PTR _msg$[ebp+8]
    ; Line 68
            mov     esp, ebp
            pop     ebp
            ret     16                                      ; 00000010H
    _WinMain@16 ENDP
    _TEXT   ENDS
    END

    上記コードは以下のC言語のソースを VC++ でアセンブリコード出力(cl /FA hello.c)したものに相当する。

    #include <windows.h>
    #include <tchar.h>
     
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        PAINTSTRUCT ps;
        HDC hdc;
        LPCTSTR lpszMessage = _T("Hello, Win32 GUI(MASM) World!");
     
        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint( hWnd, &ps );
            TextOut( hdc, 0, 0, lpszMessage, lstrlen(lpszMessage) );
            EndPaint( hWnd, &ps );
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
            break;
        }
     
        return 0;
    }
     
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        LPCTSTR lpszClassName = _T("helloWindow");
        LPCTSTR lpszWindowName = _T("Hello, World!");
        WNDCLASSEX wcex;
        HWND hWnd;
        MSG msg;
     
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style          = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = WndProc;
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = hInstance;
        wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName   = NULL;
        wcex.lpszClassName  = lpszClassName;
        wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
     
        RegisterClassEx(&wcex);
        hWnd = CreateWindow(
            lpszClassName,
            lpszWindowName,
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
            NULL, NULL, hInstance, NULL
        );
     
        ShowWindow(hWnd, SW_SHOWDEFAULT);
        UpdateWindow(hWnd);
     
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
     
        return (int)msg.wParam;
    }

    コンパイル方法

    C:¥> ml hello.asm /link user32.lib gdi32.lib /SUBSYSTEM:WINDOWS

    実行結果

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

    Posted on 7月 5th, 2012 by cx20

    Win32 GUI(MFC)

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

    ソースコード

    #include <afxwin.h>
    #include <tchar.h>
     
    class CMainFrame : public CFrameWnd
    {
    public:
        CMainFrame();
        BOOL PreCreateWindow(CREATESTRUCT& cs);
    protected:
        afx_msg void OnPaint();
        DECLARE_MESSAGE_MAP()
    };
     
    class CHelloApp : public CWinApp
    {
    public:
        BOOL InitInstance();
    };
     
    BOOL CHelloApp::InitInstance()
    {
        m_pMainWnd = new CMainFrame;
        m_pMainWnd->ShowWindow(m_nCmdShow);
        m_pMainWnd->UpdateWindow();
        return TRUE;
    }
     
    CHelloApp App;
     
    BEGIN_MESSAGE_MAP( CMainFrame, CFrameWnd )
        ON_WM_PAINT()
    END_MESSAGE_MAP()
     
    CMainFrame::CMainFrame()
    {
        Create( NULL, _T("Hello, World!") );
    }
     
    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
        CFrameWnd::PreCreateWindow(cs);
        cs.cx = 640;
        cs.cy = 480;
        return TRUE;
    }
     
    void CMainFrame::OnPaint()
    {
        CPaintDC dc(this);
        dc.TextOut( 0, 0, _T("Hello, Win32 GUI(MFC) World!") );
    }

    コンパイル方法

    C:¥> cl hello.cpp /link /SUBSYSTEM:WINDOWS

    実行結果

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