在C中构建Windows UI是否有一种无痛的方法?

Car*_*ers 5 c user-interface winapi

编辑

好吧,我猜C在本质上是痛苦的 - 只是,这部分,特别痛苦.
另外,没有一个真正的原因我只用C语写,除了,这是我想写的语言,并且现在精通.我知道从C转向C++是不好的,但无论如何.

有没有人知道一个解决方案,我在程序中创建多个窗口的问题?


好吧,我正在连接一个C DLL和一个VB6前端,但是 - 尝试来回传递字符串变得很难看,而且每当我添加一个新函数时,似乎其他一切都会破坏.所以,我想,为什么我只是为了与一种甚至不再支持的语言接口而让自己完成所有这些痛苦?为什么不把这种痛苦用于更好地使用并学习在C中构建前端?

好吧,我开始了,但我不得不问:有一个简单的方法吗?WndProc这个巨大的switch语句让我眼前一亮,反对我学到的关于干净代码的一切(很像12参数CreateWindowEx()或14参数CreateFont()).

我意识到我可以在某种程度上重构所有这些 - 如果我使用C++,我可以将窗口及其组件放入类中,并以更自然的方式访问它们,我想...

无论如何,我设法构建了一个名为"主窗口!"的大表格,带有"弹出消息!" 按钮,哪个工作正常 - 而且它根本不复杂.然后是"改变那个文字!" 用于更改编辑控件中文本的按钮.为了实现这一点,WndProc在WM_COMMAND从按钮接收消息时必须知道编辑控件.我不能将编辑控件的hWnd传递给它,因为我不是那个调用它的人,你不能只是向WndProc添加参数.所以我不得不将编辑控件放在全局范围内.

我想将按钮的字体改为13pt Tahoma - 简单,对吗?当然 - 但是我不能得到比WM_PARENTNOTIFY消息更远的东西......经过仔细阅读MSDN后,我发现有些信息在wParam的高位字中,有些信息在低位字中.所以,我不得不这样写:if(wParam==(WM_CREATE | (POPUP_COMMAND<<16))){

使控件全球化?巨大的转换声明?12和14参数函数调用?简单通知的位移?我仍然无法弄清楚如何使一个窗口(窗口窗口,而不是控制窗口)出现更多 - 这很痛苦......

请告诉我有更好的方法!

顺便提一下,如何制作多个窗口?如果我只在同一个类上注册两个类或CreateWindowEx两次(对于两个句柄),则只会出现第一个类.我尝试使用dwStyle参数一点,但无济于事.任何人?

小智 8

作为C Windows编程的前任讲师,我可以肯定地说,使用C构建GUI没有简单的方法 - 语言不适合这项任务.几乎任何其他东西都是更好的选择 - 我自己最喜欢的GUI开发是Delphi.


Jas*_*wen 6

Win32 + C是一种非常低级的方法,它有其优点和缺点.也就是说,有办法让事情变得更容易.

首先,关于位移,有几个宏可用于WPARAM和LPARAM.事实上,您可能不应该编写位移,因为WPARAM和LPARAM大小多年来已经发生了变化,您可能正在创建未来的错误.

其次,关于WindowProc函数中的巨型switch语句,虽然它会存在,但有一种方法可以使它更易于管理. #include <windowsx.h>获得一大堆有用的宏,最值得一提的是HANDLE_MSG.而不是需要写

LRESULT CALLBACK MyWindowProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)    {
    switch(Message) {
    case WM_COMMAND:
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以写:

void MyOnCommand(HWND hwnd, int controlID, HWND hwndCtl, UINT codeNotify);
LRESULT CALLBACK MyWindowProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)    {
    switch(Message) {
    HANDLE_MSG(hwnd, WM_COMMAND, MyOnCommand);
    }
}
Run Code Online (Sandbox Code Playgroud)

并且宏自动将该消息类型的所有不同参数转换并分离为适当命名的&typed变量.浏览windowsx.h以查看处理的消息以及所需的函数原型.并非所有不同的消息都被处理,但不少消息.

至于同时拥有多个窗口,不应该阻止你多次调用CreateWindow或其亲属.虽然你只有一个HINSTANCE(给你的WinMain),你可以拥有任意数量的HWNDs.

您可能会发现Raymond Chen的临时程序非常有用,因为它应该为您提供一个合适的骨架.您还可以考虑使应用程序使用对话框而不仅仅是窗口; 你可以免费获得一堆东西,你可以使用资源编辑器来设计窗口及其所有控件. Visual C++ Standard及以上版本包括一个资源编辑器,还有几个免费版本: XN Resource Editor似乎是一个流行的开源编辑器,我相信你可以在Google上找到更多.所有这些生产资源的脚本,你应该在你的工具链的资源编译器:RC.EXE为Visual Studio(包括速成版,或可作为SDK的一部分),或windres在Cygwin的GNU的BINUTILS的一部分或者mingw.


RBe*_*eig 6

我将抛弃我传统的开箱即用建议:将Lua添加到您的应用程序中,并使用Lua和合适的工具包模块组合构建GUI.一个很好的选择是IUP,另一个是wxWidgets.两者都有不错的Lua绑定.更好的是,Lua本身连同wxLua和IUP都可以在一个安装中与Lua for Windows项目中的一堆其他有用的Lua模块一起使用.

Lua很容易与C代码集成,因为它从一开始就是为此目的而设计的.

使用Lua作为将应用程序保持在一起的粘合剂也很容易,其核心功能在C中实现或作为本机API调用的接口实现.

如果您有一个广泛的库来适应,SWA也支持Lua .

当然,您可以直接使用来自C的wxWidgets或IUP,因为它们都具有C可调用API,但事件驱动的GUI通常充满了极易处理的小型管家回调函数,这些函数易于用脚本语言处理.

另一个需要考虑的工具包是Tk,它最常见于Tcl脚本语言.Tcl的开发也考虑了嵌入更大的应用程序,尽管它已经从它作为主要用例发展而来.Tk已经被各种其他语言所包括,包括Perl.