Archive for 7月 16th, 2012

  1. Hello, Win32 GUI(Lua) World!

    Posted on 7月 16th, 2012 by cx20

    Win32 GUI(Lua)

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

    ソースコード

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

    実行方法

    C:¥> wlua hello.lua

    実行結果

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