一个简单图形界面框架XYGui的设计与实现 (三)

(同步个人博客 http://sxysxy.org/blogs/70 到csdn)

回顾

上节解决了只用ruby语言制作窗口过程的问题。只用ruby语言的话,可以用局部变量_self = self,然后在Fiddle::Closure的匿名子类里面的call方法,借助_self变量访问ruby世界的”窗口对象”。

但是用C语言的话,怎么办呢?

CreateWindowEx这个函数

最后一个参数,lpParam。一般我们都把它设为0,也就是无用。但是现在他就要派上用场了。这个参数可以传递一个值,这个值会在窗口创建WM_CREATE消息发生时又传递给窗口,而窗口拥有一个存放用户自定义数据的地方,可以用SetWindowLong(GWL_USERDATA)来设置用户数据。于是我们就可以把ruby对象的指针的值放到用户自定义数据里面…打开XYGui源代码的xy_mainwindow.rb,发现

    def create
        @handle = WinAPI.call("user32", "CreateWindowEx", 0 | @ex_style, @className, @title,  
                            @style,   
                            @x, @y, @width, @height,              
                            0, 0,
                            @app.instance, selfval)
    end

selfval是个c扩展:

VALUE XYWidget_selfval(VALUE self)
{
    return INT2NUM(self); 
    /*
        In ruby, INT2NUM(self) is the real value of self
    */
}

然后窗口过程(XYGui_ext.c:

static LRESULT CALLBACK XYWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    VALUE __arg1__;
    VALUE __arg2__;

    unsigned __tmp1__;
    unsigned __tmp2__;
    char *__tmpcptr1__;

    HDC hdc;

    //Store the 'self' when creating the window
    VALUE self;
    if(uMsg == WM_CREATE)
    {
        self = (VALUE)(((LPCREATESTRUCT)lParam)->lpCreateParams);
        SetWindowLong(hWnd, GWL_USERDATA, (LONG)self);
    }
    self = (VALUE)GetWindowLong(hWnd, GWL_USERDATA);

    switch(uMsg)
    {
           ....

这样我们就可以在c代码里面得到ruby的对象了。然后一切就都好办了。

记得注册窗口类,XYApp是怎么回事我下节会讲:

static LRESULT CALLBACK XYWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static VALUE XYApp_registerClass(VALUE self)
{
    WNDCLASS wc;
    RtlZeroMemory(&wc, sizeof(wc));
    wc.lpfnWndProc = XYWndProc;                                 // XYWndProc !
    wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszClassName = RSTRING_PTR(rb_iv_get(self, "@name"));
    wc.hInstance = GetModuleHandle(NULL);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    RegisterClass(&wc);
    return self;
}

然后请读者参考xy_window的实现,自己做一个对窗口的简单封装。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值