Archive for 7月 16th, 2012
-
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! | | | | | | | | | | | | | | | | | | | +------------------------------------------+