任何编程语言对于窗口组件(超级列表框)在线程内频繁写入消息,都会造线程堵塞成崩溃,解决的方法就是采用窗口子类化,和Windows消息机制,也就是采用窗口发送消息和投递消息,调用GetWindowLon

任何编程语言对于窗口组件(超级列表框)在线程内频繁写入消息,都会造线程堵塞成崩溃,解决的方法就是采用窗口子类化,和Windows消息机制,也就是采用窗口发送消息和投递消息,调用GetWindowLongW和SetWindowLongW,CallWindowProcW来完成对窗口超级列表框的劫持,由于火山采用了Unicode(统一码/万国码)字符集,所以这里的api调用了W结尾的,这里我们采用窗口投递消息,也就是调用PostMessage函数(投递)消息到创建指定窗口的线程所关联的消息队列中,并且不会等待相应线程处理消息,而直接返回,也就是所谓的异步;值得一提的是,窗口发送消息(SendMessage)必须等待其他程序处理消息后才返回,继续执行,也就是同步;使用sendmessagea有时会导致程序假死,尤其是单线程进程,在多线程处理时也会有这样的情况;你可以更好的加深了解:
API比较PostMessageA和SendMessageA游戏屏蔽 | 511遇见 (511yj.com)
易语言SendNotifyMessage发送消息 | 511遇见 (511yj.com)
在线预览:火山视窗PC大漠多线程模板游戏实战 | 511遇见 (511yj.com)
当然采用许可证(互斥锁)也是可以避免上面说的情况,但是会降低多线程的执行效率,失去多线程的意义。

火山视窗PC大漠多线程模板游戏实战

说明:


1.本套是59套《火山视窗PC大漠多线程模板游戏实战》升级优化版,难度较大!
2.采用窗口子类化
3.采用Windows投递消息PostMessage函数(异步投递)
4.加入线程中文本变量的初始化,因为线程对文本类型的变量写入会造成堵塞,所以需要先申请内存;包括主线程状态,任务状态,副线程状态
5.对线程进行了初始化赋值;包括索引,窗口句柄,线程句柄,主线程状态,任务状态
6.对脚本中所有调用的API和第三方dll单独封装一个类DLL类
7.对所有程序常量封装了一个常量类
8.优化程序结构,分类整理,便于维护升级。
9.调用SetThreadIdealProcessor【设置线程的首选处理器。 系统尽可能在其首选处理器上计划线程。
在处理器超过 64 的系统上,此函数将首选处理器设置为调用线程分配到的 处理器组中 的逻辑处理器。】
可以简单的理解为:充分利用所有多核CPU,切换到其他空闲执行
https://learn.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadidealprocessor
10.一套好的模板在于细节,在于规范化,和一些准则。这样我们的程序才更稳定。
11.如果开启的线程特别多,超级列表框输出特别多,务必采用本套优化升级。

课程目录:


1.程序优化升级说明
2.建立DLL类调用免注册SetDllPathW和初始化CoInitializeEx
3.建立常量类
4.调用SetThreadIdealProcessor实现线程优化
5.调用GetWindowLongW获取窗口回调函数地址
参数:
Hwnd:窗口句柄
Index取值如下:
GWL_EXSTYLE (-20)得到扩展的窗口风格
GWL_STYLE (-16) 得到窗口风格
GWL_WNDPROC (-4)得到窗口回调函数的地址,或者句柄。得到后必须使用CallWindowProc函数来调用
GWL_HINSTANCE (-6)得到应用程序运行实例的句柄
GWL_HWNDPARENT(-8)得到父窗口的句柄
GWL_ID (-12) 得到窗口的标识符
GWL_USERDATA (-21)得到和窗口相关联的32位的值(每一个窗口都有一个有意留给创建窗口的应用程序是用的32位的值)
当hWnd标识一个对话框时可以使用下面的值
DWL_DLGPROC (4) 得到对话框回调函数的地址,或者句柄。得到后必须使用CallWindowProc函数来调用
DWL_MSGRESULT (0)得到对话框回调函数中消息处理过程的返回值
DWL_USER (8) 得到额外的应用程序私有信息,如一些句柄和指针等
返回值:
成功时,返回一个请求的32位的值
6.调用SetWindowLongW更改窗口属性
SetWindowLongW 函数 (winuser.h) - Win32 apps | Microsoft Learn
7.设置SetWindowLongW的回调函数
8.调用CallWindowProcW将消息信息传递给指定的窗口过程完成子类化
CallWindowProcW 函数 (winuser.h) - Win32 apps | Microsoft Learn
9.增加多线程成员变量序号主线程状态任务状态和副线程状态并初始化申请内存空间
10.主线程复位
11.主线程初始化和复位调用位置处理
12.子类化回调函数WindowProc自定义消息处理
13.火山视窗封装窗口投递消息
14.用窗口消息投递替换所有超级列表框置标题

  • 20
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
小白可以看看 很简单的处理 原帖和原始源码在这里是超级列表框线程线程调用时间区别 https://bbs.125.la/forum.php?mod=viewthreadtid=13916045 本例子 源码加了cpu亲和度 和线程里面利用标签反馈事件 1,CPU亲和度设置,线程里面操作超级列表框的话 我用了这个 机器没负载的情况下  线程里面写入超级列表框的速度大概比非线程慢1倍  如果不用这个线程里面写入超级列表框比非线程慢10倍,高级表格的没测试 .版本 2 SetProcessAffinityMask (-1, 1)  ' 完美 ' SetProcessAffinityMask 设置进程CPU相关性 参数设置 (2018-01-05 18:39:48)转载▼ ' 标签: setprocessaffinityma it 分类: API ' SetProcessAffinityMask ' 参数一:进程句柄    -1为自身句柄 ' 参数二:指定CPU ' 参数二的设置是二进制转十进制。参数二需填写十进制数字 ' 例如我想设置 ' 1CPU二进制为1 转换为十进制为 1 ' 2CPU二进制为10 转换为十进制为 2 ' 3CPU二进制为100 转换为十进制为 4 ' 4CPU二进制为1000 转换为十进制为 8 ' 1,2CPU二进制为11 转换为十进制为 3 ' 3,4CPU二进制为1100 转换为十进制为 12 ' 123CPU二进制为1110 转换为十进制为 14 ' 1234CPU二进制为1111 转换为十进制为 15 2,线程里面测试用超级列表框写入数据 比非线程慢很多 显示到列表框很慢  线程里面调用标签反馈  相当于 写入操作是在主线程/非线程里面进行的。 高级表格线程里面会崩溃  全部删除或者增加减少行 插入之类的操作会崩溃  同理可以这样处理  置数据不会崩溃 其他高级表格选择框按钮之类的没有测试过

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

511遇见

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值