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 |