当前位置 : 主页 > 手机开发 > 其它 >

如何将WinAPI应用程序封装到C类中

来源:互联网 收集:自由互联 发布时间:2021-06-19
有一个简单的WinAPI应用程序.目前所做的一切都是这样的: 注册一个窗口类 使用菜单注册托盘图标 在注册表中创建一个值以自动启动 最后,它使用互斥锁检查它是否是唯一的 由于我习惯
有一个简单的WinAPI应用程序.目前所做的一切都是这样的:

>注册一个窗口类
>使用菜单注册托盘图标
>在注册表中创建一个值以自动启动
>最后,它使用互斥锁检查它是否是唯一的

由于我习惯于主要在C中编写代码,并且不允许使用MFC,因此我不得不以某种方式将其封装到C类中.到目前为止,我已经提出了这样的设计:

>有一个代表应用程序的类
>它保存所有wndclass,hinstance等变量,其中hinstance作为构造函数参数以及icmdshow和其他参数传递(参见WinMain原型)
>它具有注册窗口类,托盘图标,reigstry信息的功能
>它将消息循环封装在一个函数中

在WinMain中,完成以下操作:

Application app(hInstance, szCmdLIne, iCmdShow);
return app.exec();

并且构造函数执行以下操作:

registerClass();
registerTray();
registerAutostart();

到现在为止还挺好.现在的问题是:如何创建窗口过程(必须是静态的,因为它是指向函数的c样式指针)并跟踪应用程序对象是什么,即保持指向应用程序的指针.

主要问题是:这通常是怎么做的?我太复杂了吗?将hInstance作为参数传递给Application构造函数是否可以? WndProc在哪里?

也许WndProc应该在课外,应用程序指针应该是全局的?然后WndProc调用Application方法来响应各种事件.

还有一个可能的解决方案:使应用程序类成为单例.然后从WndProc获取该对象的句柄是微不足道的.

答案是SetWindowLongPtr.它允许您将void *与给定的hWnd相关联.然后,在WndProc中,您只需提取所述void *,强制转换并调用成员方法.问题解决方案.使用SetWindowLongPtr有一些起伏,您必须调用其他函数来查看效果或某些BS,并且Windows在CreateWindowEx返回之前发送消息,因此您必须为GetWindowLongPtr(hWnd,GWL_USERDATA)返回NULL做好准备.

这当然意味着对于给定的WindowProc,使用它的所有实例都必须具有公共接口,因为使用void *可以做的事情并不多.

并且,是的,将HINSTANCE传递给App构造函数是可以的.我见过的样本做了一些奇怪的事情来避免这种情况,但我从来没有让它成功.

编辑:不要将Get / SetWindowLong与Get / SetWindowLongPtr混淆. Get / SetWindowLong已弃用且不安全.

网友评论