纯Ruby创建Win32窗口

前言

所谓纯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

结束

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ShenmeGUI是一套受Shoes启发而诞生的GUI工具,拥有相似的DSL语法,使用HTML构建界面,并实现了前后端数据的双向绑定,可以便捷地实现一些轻量的GUI应用。安装执行 gem install shenmegui 。示例代码require 'shenmegui' ShenmeGUI.app do   form(title: 'Your Application') do     button('alert').onclick do       alert 'Hello World!'     end     button('open an image').onclick do       path = get_open_file_name       @t.text = path       @i.src = path     end     stack do       label 'image path:'       @t = textarea '', width: '100%'     end     @i = image "http://7jpqbr.com1.z0.glb.clouddn.com/bw-2014-06-19.jpg"     @p = progress(75)     button(' ').onclick { @p.percent  = 5 }     button('-').onclick { @p.percent -= 5 }   end end ShenmeGUI.start!将会产生如图所示的界面:如未自动打开浏览器,可手动打开程序代码同目录的index.html。button定义按钮,并通过onclick绑定上了点击事件。第一个按钮弹出一个对话框,第二个按钮弹出一个打开文件的对话框,将文件路径写到下方定义的textarea里,并改变image的src以显示这个图片。下方的两个按钮演示了进度条的增减。系统需求Ruby版本大于等于2.0.0。因为前后端通讯使用了websocket,所以需要使用支持websocket的浏览器。目前打开文件对话框只实现了windows版本,在Linux等使用会出错,以后会尝试在其他系统实现,除此之外对系统没有要求。 标签:ShenmeGUI  GUI开发框架
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值