Archive for 7月 14th, 2012
-
Hello, Win32 GUI(Ruby) World!
Posted on 7月 14th, 2012 by cx20
Win32 GUI(Ruby)
Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
以下は Ruby による Win32 GUI アプリケーション の例となっている。
なお、Win32 の構造体の定義に CStruct ライブラリを使用している。ソースコード
require 'win32/api' require 'cstruct/win32struct' include Win32 WS_VISIBLE = 0x10000000 WS_CAPTION = 0x00C00000 WS_SYSMENU = 0x00080000 WS_MINIMIZEBOX = 0x00020000 WS_MAXIMIZEBOX = 0x00010000 WS_THICKFRAME = 0x00040000 WS_OVERLAPPED = 0x00000000 WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) WM_CREATE = 0x0001 WM_DESTROY = 0x0002 WM_PAINT = 0x000F WM_CLOSE = 0x0010 WM_COMMAND = 0x0111 CS_VREDRAW = 0x0001 CS_HREDRAW = 0x0002 COLOR_WINDOW = 5 CW_USEDEFAULT = -2147483648 #0x80000000 SW_SHOW = 5 SW_SHOWDEFAULT = 10 Memset = API.new('memset', 'PLL', 'L', 'msvcrt') LocalAlloc = API.new('LocalAlloc', 'LL', 'L', 'kernel32') GetModuleHandle = API.new('GetModuleHandle', 'P', 'L', 'kernel32') RegisterClass = API.new('RegisterClass', 'P', 'L', 'user32') RegisterClassEx = API.new('RegisterClassEx', 'P', 'L', 'user32') CloseWindow = API.new('CloseWindow', 'L', 'B', 'user32') CreateWindowEx = API.new('CreateWindowEx', 'LPPLIIIILLLL', 'L', 'user32') ShowWindow = API.new('ShowWindow', 'LL', 'B', 'user32') UpdateWindow = API.new('UpdateWindow', 'L', 'B', 'user32') BeginPaint = API.new('BeginPaint', 'LP', 'L', 'user32') EndPaint = API.new('EndPaint', 'LP', 'L', 'user32') PostQuitMessage = API.new('PostQuitMessage', 'I', 'V', 'user32') DefWindowProc = API.new('DefWindowProc', 'LLLL', 'L', 'user32') GetMessage = API.new('GetMessage', 'PLII', 'L', 'user32') DispatchMessage = API.new('DispatchMessage', 'P', 'L', 'user32') TranslateMessage = API.new('TranslateMessage', 'P', 'B', 'user32') TextOut = API.new('TextOut', 'LLLPL', 'B', 'gdi32' ); class POINT < Win32Struct LONG :x LONG :y end class MSG < Win32Struct uint32 :hwnd UINT :message WPARAM :wParam LPARAM :lParam DWORD :time POINT :pt end class WNDCLASSA < Win32Struct UINT :style uint32 :lpfnWndProc int32 :cbClsExtra int32 :cbWndExtra HINSTANCE :hInstance HICON :hIcon HCURSOR :hCursor HBRUSH :hbrBackground LPCSTR :lpszMenuName LPCSTR :lpszClassName end class RECT < Win32Struct LONG :left LONG :top LONG :right LONG :bottom end class PAINTSTRUCT < Win32Struct HDC :hdc BOOL :fErase RECT :rcPaint BOOL :fRestore BOOL :fIncUpdate BYTE :rgbReserved,[32] end @window_proc = API::Callback.new('LLLL', 'I') do |hwnd, msg, wparam, lparam| ret = 0 strMessage = "Hello, Win32 GUI(Ruby) World!" case msg when WM_PAINT ps = PAINTSTRUCT.new hdc = BeginPaint.call(hwnd, ps.data) TextOut.call(hdc, 0, 0, strMessage, strMessage.length); EndPaint.call(hwnd, ps.data) when WM_DESTROY PostQuitMessage.call(0) else ret = DefWindowProc.call(hwnd, msg, wparam, lparam) end ret end def alloc_string_buffer init_string, max_length buffer_pointer = LocalAlloc.call(0, max_length) buffer_addr = buffer_pointer Memset.call(buffer_addr, 0, max_length) init_string.each_byte do |byte| Memset.call(buffer_pointer, byte, 1) buffer_pointer += 1 end buffer_addr end def WinMain instance, cmd_show msg = MSG.new wc = WNDCLASSA.new wc.style = 0 wc.lpfnWndProc = @window_proc.address wc.cbClsExtra = 0 wc.cbWndExtra = 0 wc.hInstance = instance wc.hIcon = 0 wc.hCursor = 0 wc.hbrBackground = (COLOR_WINDOW+1) wc.lpszMenuName = 0 wc.lpszClassName = alloc_string_buffer 'helloWindow', 256 RegisterClass.call(wc.data) hwnd = CreateWindowEx.call( 0, "helloWindow", "Hello, World!", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 0, 0, wc.hInstance, 0 ) ShowWindow.call(hwnd, cmd_show) UpdateWindow.call(hwnd) while(GetMessage.call(msg.data, 0, 0, 0) > 0) TranslateMessage.call(msg.data) DispatchMessage.call(msg.data) end end def main instance = GetModuleHandle.call(0) WinMain instance, SW_SHOW end main
ライブラリ導入方法
C:¥> gem install cstruct
実行方法
C:¥> ruby hello.rb
実行結果
+------------------------------------------+ |Hello, World! [_][~][X]| +------------------------------------------+ |Hello, Win32 GUI(Ruby) World! | | | | | | | | | | | | | | | | | | | +------------------------------------------+