1. 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!              |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  2. 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!              |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  3. 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!             |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  4. 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!              |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  5. Hello, Win32 GUI(C++/CLI) World!

    Posted on 7月 5th, 2012 by cx20

    Win32 GUI(C++/CLI)

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

    ソースコード

    #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(C++/CLI) 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;
        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 hWnd = CreateWindow(
            lpszClassName,
            lpszWindowName,
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
            NULL, NULL, hInstance, NULL
        );
     
        ShowWindow(hWnd, SW_SHOWDEFAULT);
        UpdateWindow(hWnd);
     
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
     
        return (int)msg.wParam;
    }

    コンパイル方法

    C:¥> cl /clr hello.cpp /link user32.lib gdi32.lib /SUBSYSTEM:WINDOWS

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(C++/CLI) World!          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  6. Hello, Win32 GUI(WTL) World!

    Posted on 7月 4th, 2012 by cx20

    Win32 GUI(WTL)

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

    ソースコード

    #include <atlbase.h>
    #include <atlapp.h>
    #include <atlcrack.h>
     
    class CHelloWindow : public CWindowImpl<CHelloWindow>
    {
        BEGIN_MSG_MAP( CHelloWindow )
            MSG_WM_PAINT   ( OnPaint   )
            MSG_WM_DESTROY ( OnDestroy )
        END_MSG_MAP()
     
        void OnPaint( HDC hDC )
        {
            CPaintDC dc( m_hWnd );
            LPCTSTR lpszMessage = _T("Hello, Win32 GUI(WTL) World!");
            dc.TextOut( 0, 0, lpszMessage, lstrlen(lpszMessage) );
        }
        void OnDestroy()
        {
            PostQuitMessage( 0 );
        }
    };
     
    CAppModule _Module;
     
    int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
    {
        _Module.Init(NULL, hInstance);
     
        CMessageLoop theLoop;
        _Module.AddMessageLoop(&theLoop);
     
        CHelloWindow wnd;
        wnd.Create( NULL, CWindow::rcDefault, _T("Hello, World!"), WS_OVERLAPPEDWINDOW | WS_VISIBLE );
        wnd.ResizeClient( 640, 480 );
        int nRet = theLoop.Run();
     
        _Module.RemoveMessageLoop();
        _Module.Term();
     
        return nRet;
    }

    コンパイル方法

    C:¥> SET INCLUDE=<WTL>Include;%INCLUDE
    C:¥> cl hello.cpp

    実行結果

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

    Posted on 7月 3rd, 2012 by cx20

    Win32 GUI(ATL)

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

    ソースコード

    #include <atlbase.h>
    #include <atlwin.h> 
     
    class CHelloWindow : public CWindowImpl<CHelloWindow>
    {
        BEGIN_MSG_MAP( CHelloWindow )
            MESSAGE_HANDLER( WM_PAINT,   OnPaint   )
            MESSAGE_HANDLER( WM_DESTROY, OnDestroy )
        END_MSG_MAP()
     
        LRESULT OnPaint( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
        {
            PAINTSTRUCT ps;
            HDC hDC = GetDC();
            LPCTSTR lpszMessage = _T("Hello, Win32 GUI(C++) World!");
            BeginPaint( &ps );
            TextOut( hDC, 0, 0, lpszMessage, lstrlen(lpszMessage) );
            EndPaint( &ps );
            return 0;
        }
     
        LRESULT OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
        {
            PostQuitMessage( 0 );
            return 0;
        }
    };
     
    CComModule _Module;
     
    int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
    {
        _Module.Init(NULL, hInstance);
     
        CHelloWindow wnd;
        wnd.Create( NULL, CWindow::rcDefault, _T("Hello, World!"), WS_OVERLAPPEDWINDOW | WS_VISIBLE );
        wnd.ResizeClient( 640, 480 );
        MSG msg;
        while( GetMessage( &msg, NULL, 0, 0 ) ){
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
     
        _Module.Term();
     
        return msg.wParam;
    }

    コンパイル方法

    C:¥> cl hello.cpp

    実行結果

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

    Posted on 7月 2nd, 2012 by cx20

    Win32 GUI(C++)

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

    ソースコード

    #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(C++) 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;
        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 hWnd = CreateWindow(
            lpszClassName,
            lpszWindowName,
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
            NULL, NULL, hInstance, NULL
        );
     
        ShowWindow(hWnd, SW_SHOWDEFAULT);
        UpdateWindow(hWnd);
     
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
     
        return (int)msg.wParam;
    }

    コンパイル方法

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

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(C++) World!              |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  9. Hello, Win32 GUI(C言語) World!

    Posted on 7月 1st, 2012 by cx20

    Win32 GUI(C言語)

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

    ソースコード

    #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 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:¥> cl hello.c /link user32.lib gdi32.lib /SUBSYSTEM:WINDOWS

    実行結果

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

    Posted on 6月 30th, 2012 by cx20

    Win32 API(Ada)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は Ada による Win32 API の呼出し例である。

    ソースコード

    with Interfaces;    use Interfaces;
    with Interfaces.C;  use Interfaces.C;
    with System;        use System;
     
    with Ada.Unchecked_Conversion;
     
    procedure Hello is
       function LoadLibrary (lpFileName : char_array) return Unsigned_32;
       pragma Import (Stdcall, LoadLibrary, "LoadLibrary", "_LoadLibraryA@4");
     
       function GetProcAddress (hModule : Unsigned_32; lpProcName : char_array) return Address;
       pragma Import (Stdcall, GetProcAddress, "GetProcAddress", "_GetProcAddress@8");
     
       type MessageBox is access function (
          hWnd      : Address;
          lpText    : char_array;
          lpCaption : char_array;
          uType     : Unsigned_16
       ) return Integer_16;
       pragma Convention (Stdcall, MessageBox);
     
       function To_MessageBox is new Ada.Unchecked_Conversion (Address, MessageBox);
     
       Result : Integer_16;
       Library : Unsigned_32;
       Pointer : Address;
    begin
       Library := LoadLibrary (To_C ("user32.dll"));
       Pointer := GetProcAddress (Library, To_C ("MessageBoxA"));
       Result := To_MessageBox (Pointer) (
          Null_Address,
          To_C ("Hello, Win32 API(Ada) World!"),
          To_C ("Hello, World!"),
          0
       );
    end Hello;

    コンパイル方法(GNAT)

    C:¥> gnatmake hello.adb

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(Ada) World!
    ---------------------------
    OK   
    ---------------------------