Golden Blonde 发表于 2022-6-28 21:41:32

【C】简化窗口消息处理(通用化的WndProc)

众所周知,VB6至今仍被大量使用,其中一个重要原因是可以快速开发带窗口的应用程序。其它工具虽然也可以“画”出图形界面,但在事件处理上没有VB6那么直观。之所以没有那么直观,完全是因为WINDOWS坑爹的消息处理机制设计。比如最常见的“鼠标左键单击”事件,有的情况要处理WM_COMMAND,有的情况要处理WM_NOTIFY,有的情况要处理WM_LBUTTONUP和WM_LBUTTONDOWN;有的情况消息发给控件本身,有的情况消息发给控件所属窗体。我在被这套东西折腾了几年之后,写出了一个通用的WndProc函数。比如要处理BUTTON的CLICK事件时,只需要调用AssignEventHandler给BUTTON指派一个函数来处理事件。
DEMO代码只实现了窗口和几个常用控件的20个基本事件,有需要的人可以自行完善。这个代码需要结合《史上最“屌”的纯WINAPI界面编程学习笔记》的代码使用。**** Hidden Message *****

tlwh163 发表于 2022-6-29 07:51:27

我是来学习的

0xAA55 发表于 2022-7-1 14:26:16

其实如果是我,我会使用 msys2 来编译我的 Win32 工程,并使用“弱符号”的方式来实现各种控件的“仿 VB6 事件函数”的自动调用,效果就是:我如果写了事件函数的实现,那么它会被自动调用;如果我没写,也不妨碍它正常编译。

msys2 包含 Windows 上可用的 GCC 编译工具链,可以使用 Windows 的头文件和库(比如 Windows.h )并且生成 exe、dll。

类似于原版 VB6 的一个特点:我如果写了事件处理过程(比如 Private Sub Form_Click() 也就是窗体的单击事件)那么这个 Sub 会在你单击窗体的时候自动被调用,但如果你不写这个过程,那也不妨碍你程序可以编译(也就是你不需要把所有控件的所有事件的过程都写出来)。

假设我有个 Button 控件名为 Button1 在我的主窗体上,那么这个控件的单击事件的响应函数是这样写的:void OnClick(HWND Button, size_t Button_ID)
{
    // 此处定义按钮行为
    MessageBeep(MB_OK); // 发出“咚”的一声
}因为我写了这个函数,所以我的按钮被按下的时候,这个函数会被调用。但是我如果完全删除了这个函数呢?那依然可以正常编译。

原理是:在 GCC 可以使用 __attribute__((weak)) 来修饰一个变量、函数,使其成为“弱符号”。然后这个“弱符号”对应的函数、变量等,就会变为一个“备用”的函数或者变量。如果出现了同名的非弱符号,则链接器会链接到这个非弱符号上。比如:__attribute__((weak)) void foo()
{
    printf("A");
}

void foo()
{
    printf("B");
}

int main()
{
    foo(); // 会输出 B
    return 0;
}对比另一份代码(没写 void foo())则是这样的:__attribute__((weak)) void foo()
{
    printf("A");
}

int main()
{
    foo(); // 会输出 A
    return 0;
}我在我的“通用消息处理函数”里面对几种我设定的常用的控件的事件函数进行调用,并且我把这些事件函数都以弱符号的形式定义好。那么我的界面库在被使用的时候,使用者就可以通过自己写同名、同返回值、同参数列表的事件函数来处理事件了。

可以通过参阅 STM32 的 HAL 库,你可以看到它对 STM32 的各种 CPU 中断函数进行了封装,每一种中断都有它的默认行为,而只要你编写了同名的中断处理函数,则最终生成的指令里会选用你的中断处理函数对 CPU 的中断进行处理。



Golden Blonde 发表于 2022-7-1 21:33:26

0xAA55 发表于 2022-7-1 14:26
其实如果是我,我会使用 msys2 来编译我的 Win32 工程,并使用“弱符号”的方式来实现各种控件的“仿 VB6...

我不喜欢使用第三方工具,如果用第三方工具,还不如直接用C++ BUILDER呢。。。

用VB6画界面+自动生成A5UI代码,再结合这个GWNDPROC库,基本就是一个C版VB了。。。

对了,如何用C代码调用OCX?

0xAA55 发表于 2022-7-1 22:03:20

Golden Blonde 发表于 2022-7-1 21:33
我不喜欢使用第三方工具,如果用第三方工具,还不如直接用C++ BUILDER呢。。。

用VB6画界面+自动生成A5U ...

C 调用 OCX 麻烦死了……基本就是调用 COM DLL 那一套。

Golden Blonde 发表于 2022-7-1 22:29:23

0xAA55 发表于 2022-7-1 22:03
C 调用 OCX 麻烦死了……基本就是调用 COM DLL 那一套。

有没有DEMO代码?VB里这么多第三方控件在C程序里无法使用,实在太可惜了。

dqw2d23 发表于 2022-7-3 10:41:39

RE: 【C】简化窗口消息处理(通用化的WndProc) [修改]

悠哉日常 发表于 2022-7-3 13:04:49

学习怎么画ui

xiawan 发表于 2022-7-20 08:58:13

楼主大能,感谢感谢

小冰 发表于 2022-8-10 02:10:53

0xAA55 发表于 2022-7-1 14:26
其实如果是我,我会使用 msys2 来编译我的 Win32 工程,并使用“弱符号”的方式来实现各种控件的“仿 VB6...

谢谢A5,原来weak是这么用的。:kiss:

610100 发表于 2023-3-21 16:20:53

学到了,研究一下

Mat 发表于 2023-3-25 20:50:55

Good Job!:D:D
页: [1]
查看完整版本: 【C】简化窗口消息处理(通用化的WndProc)