`
skandhas
  • 浏览: 35055 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

纯Ruby创建Win32窗口

    博客分类:
  • Ruby
阅读更多

前言

所谓纯Ruby是指只用Ruby代码调用API来创建出一个窗口。本文的例子使用了windows-pr和CStruct。 不熟悉的童鞋可以先看这篇文章:在Ruby中方便的调用Win32 API(使用windos-pr和CStruct) : 这里 这里

本文并不鼓励直接用API来做GUI程序,而是想借这个例子说明在Windows下, Ruby除了本身的强大之外,还可以很方便的使用API,充分利用Windows的资源,用来做Windows系统管理的脚本也是很方便的。

正文

win32的相关东东就不做普及了,相信大家都已很熟了。本文的例子就是创建一个窗口,显示一幅图片而已。具体请看源码。下面大体说说几个方法:

1. main

main方法创建一个窗口,并开始消息循环。创建窗口的具体工作是create_window来做的。
def main
   msg = MSG.new
   instance = GetModuleHandle 0
   create_window instance,SW_SHOW

   # message loop
   while( GetMessage( msg.data, 0, 0, 0 ))
     DispatchMessage( msg.data )
   end
end 
 

2.create_window

create_window 方法是创建窗口,里面调用了RegisterClass,CreateWindowEx,ShowWindow,UpdateWindow。熟悉win32的童鞋一看便知。
def create_window instance, cmd_show

   @ico_handle = LoadImageA(instance,"ruby.ico",IMAGE_ICON,16,16,LR_DEFAULTCOLOR|LR_LOADFROMFILE)
   @bk_bmp_handle = LoadImageA(instance,"ruby.bmp",IMAGE_BITMAP,299,299,LR_LOADFROMFILE)

   wc = WNDCLASSA.new
   wc.style = 0
   wc.lpfnWndProc = @window_proc.address
   wc.cbClsExtra = 0
   wc.cbWndExtra = 0
   wc.hInstance = instance
   wc.hIcon = @ico_handle
   wc.hCursor = 0
   wc.hbrBackground = (COLOR_WINDOW+1)
   wc.lpszMenuName = 0
   wc.lpszClassName = alloc_ansi_string_buffer 'MyWindowClass',256

   atom = RegisterClassA(wc.data)
   atom &=0x0000ffff
   return if atom == 0

   windows_style = WS_OVERLAPPEDWINDOW
   hwnd = CreateWindowEx(0,atom,"Pure Ruby Window", windows_style, 100, 100, 360,360, 0, 0, instance, 0)

   ShowWindow(hwnd, cmd_show)
   UpdateWindow(hwnd)

end 
 

3.window_proc

一个Win32 GUI程序当然少不了窗口过程函数,window_proc即是。就和用C写为Win32 GUI程序一样,只处理相关消息就可。本文示例处理了WM_PAINT消息,主要工作就是显示图片啦。

@window_proc = API::Callback.new('LLLL','I')do |hwnd, msg,wparam,lparam|
   ret = 0
   case msg
   when WM_PAINT
     ps = PAINTSTRUCT.new
     hdc = BeginPaint(hwnd, ps.data)
     mem_dc = CreateCompatibleDC(0)
     SelectObject(mem_dc,@bk_bmp_handle)
     BitBlt(hdc,20,20,299,299,mem_dc,0,0,SRCCOPY)
     EndPaint(hwnd, ps.data)
     DeleteDC(mem_dc)
   when WM_DESTROY
     PostQuitMessage 0
   else
     ret = DefWindowProc(hwnd,msg,wparam,lparam);
   end
   ret
end 
 

运行效果

示例代码的运行效果如下:


补充

之所以使用windows-pr,是因为它太方便了。但是也有一些函数和常量没有定义,所以在本例的代码中,需要自己动手定义。 还有一些Win32的结构体,需要用CStruct来定义。 另外,CStruct的Win32Struct也有几个类型没有定义,我扩充了一下。具体请参考源码。

下载

代码下载地址:pure_ruby_window.rar

结束

本文技术上无啥含量,众看官姑且看之吧。

 

1
0
分享到:
评论
1 楼 sevk 2010-11-27  
太方便了, 太智能了.

相关推荐

Global site tag (gtag.js) - Google Analytics