技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 242|回复: 8
收起左侧

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

[复制链接]

50

主题

260

帖子

8618

积分

用户组: 管理员

UID
77
精华
15
威望
204 点
宅币
7658 个
贡献
217 次
宅之契约
0 份
在线时间
210 小时
注册时间
2014-2-22
发表于 2022-6-28 21:41:32 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

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

评分

参与人数 1威望 +30 宅币 +100 贡献 +30 收起 理由
0xAA55 + 30 + 100 + 30 加油!

查看全部评分

回复

使用道具 举报

0

主题

22

帖子

554

积分

用户组: 大·技术宅

UID
7437
精华
0
威望
112 点
宅币
198 个
贡献
110 次
宅之契约
0 份
在线时间
22 小时
注册时间
2021-9-11
发表于 2022-6-29 07:51:27 | 显示全部楼层
我是来学习的

1094

主题

2671

帖子

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
238
威望
616 点
宅币
22347 个
贡献
46089 次
宅之契约
0 份
在线时间
2138 小时
注册时间
2014-1-26
发表于 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 在我的主窗体上,那么这个控件的单击事件的响应函数是这样写的:
[C] 纯文本查看 复制代码
void OnClick(HWND Button, size_t Button_ID)
{
    // 此处定义按钮行为
    MessageBeep(MB_OK); // 发出“咚”的一声
}
因为我写了这个函数,所以我的按钮被按下的时候,这个函数会被调用。但是我如果完全删除了这个函数呢?那依然可以正常编译。

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

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

int main()
{
    foo(); // 会输出 B
    return 0;
}
对比另一份代码(没写 void foo())则是这样的:
[C] 纯文本查看 复制代码
__attribute__((weak)) void foo()
{
    printf("A");
}

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

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



50

主题

260

帖子

8618

积分

用户组: 管理员

UID
77
精华
15
威望
204 点
宅币
7658 个
贡献
217 次
宅之契约
0 份
在线时间
210 小时
注册时间
2014-2-22
 楼主| 发表于 2022-7-1 21:33:26 | 显示全部楼层
0xAA55 发表于 2022-7-1 14:26
其实如果是我,我会使用 msys2 来编译我的 Win32 工程,并使用“弱符号”的方式来实现各种控件的“仿 VB6  ...


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

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

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

1094

主题

2671

帖子

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
238
威望
616 点
宅币
22347 个
贡献
46089 次
宅之契约
0 份
在线时间
2138 小时
注册时间
2014-1-26
发表于 2022-7-1 22:03:20 | 显示全部楼层
Golden Blonde 发表于 2022-7-1 21:33
我不喜欢使用第三方工具,如果用第三方工具,还不如直接用C++ BUILDER呢。。。

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

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

50

主题

260

帖子

8618

积分

用户组: 管理员

UID
77
精华
15
威望
204 点
宅币
7658 个
贡献
217 次
宅之契约
0 份
在线时间
210 小时
注册时间
2014-2-22
 楼主| 发表于 2022-7-1 22:29:23 | 显示全部楼层
0xAA55 发表于 2022-7-1 22:03
C 调用 OCX 麻烦死了……基本就是调用 COM DLL 那一套。

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

1

主题

5

帖子

64

积分

用户组: 小·技术宅

UID
7950
精华
0
威望
12 点
宅币
35 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2022-7-3
发表于 2022-7-3 10:41:39 | 显示全部楼层
RE: 【C】简化窗口消息处理(通用化的WndProc) [修改]

0

主题

3

帖子

70

积分

用户组: 小·技术宅

UID
6727
精华
0
威望
2 点
宅币
63 个
贡献
0 次
宅之契约
0 份
在线时间
7 小时
注册时间
2021-3-10
发表于 2022-7-3 13:04:49 | 显示全部楼层
学习怎么画ui

1

主题

119

帖子

132

积分

用户组: 小·技术宅

UID
7535
精华
0
威望
0 点
宅币
13 个
贡献
0 次
宅之契约
0 份
在线时间
11 小时
注册时间
2021-10-16
发表于 2022-7-20 08:58:13 | 显示全部楼层
楼主大能,感谢感谢

本版积分规则

QQ|申请友链||Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2022-8-9 16:26 , Processed in 0.046485 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表