某程序替换图片资源,发现还是显示旧的
简述
- 替换了程序的一些背景图片,安装图片
- 编译后发现还是显示旧资源的内容
- 清理
visual studio项目缓存,重新编译还是显示旧资源内容
- 清理
分析
- 资源替换成功了,重新编译了,还显示旧内容,那说明跑起来的程序内部的资源本身就是旧的内容
- 也就是,调起来的程序不是新编的程序
原因
- 发现
debug模式指定了命令行参数/debugfile=xxx.exe,该exe是其他程序打包出来的 - 需要把新编出来的程序,替换到
xxx.exe的打包目录,重新编xxx.exe
窗口阻塞问题
简述
- 主线程先后创建了窗口
A,和主窗口B - 点击了主窗口
B的某个按钮后,启动了一个异步线程- 该线程中给窗口
A使用SendMessage发送了一个消息 - 后面主界面发生了阻塞
- 该线程中给窗口
分析
- 因为, 窗口属于创建它的线程
- 所以,这两个窗口的
HWND都属于主线程 - 所以,发生了阻塞,实际就是主线程发生了阻塞
- 所以,把程序附加到
visual studio上,手动触发阻塞,然后暂停程序,应该在线程列表里面切换到主线程,查看主线程的堆栈信息
- 所以,这两个窗口的
- 关于简述问题
- 上面描述的问题,最后查看主线程的堆栈,显示某个控件的
*Draw*函数 - 也就是说,点击那个按钮后,执行的代码里面有相关图片处理逻辑
- 查看代码发现,调用了
SetVisible,通过bRedraw参数触发了重绘,而重绘的时候调用相关*Draw*函数 - 继续查看
ing_group_相关代码发现,设置了图片A,进度条图片B,文本CD - 图片
A在点击触发按钮之前已经展示过,且此处处理图片B的代码和之前处理图片A的代码是一样的 - 文本
CD也是和之前处理文本的代码一样 - 虽然处理图片
B的代码和处理图片A的代码是一样的,但是图片B没有展示过,怀疑图片B有问题 - 查看本地图片
B文件,发现名字没对上,拷贝过去后没有改名字,和资源指向路径里名字不一致 - 修改图片
B的名字,解决了问题
- 上面描述的问题,最后查看主线程的堆栈,显示某个控件的
|
1 2 3 |
virtual void __stdcall SetVisible(BOOL bVisiable, BOOL bRedraw); ing_group_->SetVisible(TRUE, TRUE); |
其他
- 关于线程和窗口
- 窗口属于创建它的线程
- 关于消息循环
- 一个线程可以有多个消息循环,但同一时刻只能运行一个
- 多个窗口可以共享同一个消息循环
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// 主消息循环 int MainMessageLoop() { MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } // 模态对话框会启动嵌套消息循环 void ShowModalDialog() { CModalDlg dlg; dlg.DoModal(); // 内部启动新的消息循环! // DoModal 内部大致代码: // MSG msg; // while (GetMessage(&msg, NULL, 0, 0)) { // if (对话框关闭) break; // TranslateMessage(&msg); // DispatchMessage(&msg); // } } // 调用栈: //主消息循环 (运行中) // └→ 处理某个消息 // └→ ShowModalDialog() // └→ DoModal() 的消息循环 (运行中) ← 第二个消息循环 // └→ 对话框关闭后返回 // ← DoModal() 消息循环结束 // ← ShowModalDialog() 返回 // ← 继续主消息循环 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
void MainThread() { // 第一阶段:初始化窗口的消息循环 { CInitWindow initWnd; initWnd.Create(...); CMessageLoop loop1; _Module.AddMessageLoop(&loop1); loop1.Run(); // 运行第一个消息循环 _Module.RemoveMessageLoop(); // 当 PostQuitMessage 被调用,loop1.Run() 结束 } // 第二阶段:主窗口的消息循环 { CMainWnd mainWnd; mainWnd.Create(...); CMessageLoop loop2; _Module.AddMessageLoop(&loop2); loop2.Run(); // 运行第二个消息循环 _Module.RemoveMessageLoop(); } } |
- 关于消息队列
- 每个线程只有一个消息队列(系统级)
- 关于消息循环和窗口过程相关代码
- 一个窗口类里面,只看到了窗口过程相关的代码,如
BEGIN_MSG_MAP_EX,END_MSG_MAP - 只能说明该窗口有消息处理的能力,而不能说该窗口有消息循环
- 一个窗口类里面,只看到了窗口过程相关的代码,如
|
1 2 3 4 5 |
// 窗口过程相关代码 BEGIN_MSG_MAP_EX(CUIThreadWindow) MESSAGE_HANDLER( WM_SWITCH_TO_UI_THREAD, OnSwitchToUIThreadMessage ) MESSAGE_HANDLER( WM_ASYNC_TO_UI_THREAD, OnAsyncToUIThreadMessage ) END_MSG_MAP(); |
|
1 2 3 4 5 |
// 消息循环 while (GetMessage(&msg, NULL, 0, 0)) { // ← 消息循环 TranslateMessage(&msg); DispatchMessage(&msg); // 把消息分发给窗口 } |
A库调用B库funcD函数,却触发了B库funcB函数的断点
简述
A库是个DLL,B库是个libA库里面某个类继承了接口类
|
1 2 3 4 5 6 7 |
class IInterface { public: virtual void func1() = 0; virtual void func2() = 0; virtual void func3() = 0; virtual void func6() = 0; } |
|
1 2 3 4 5 6 7 8 9 |
class CTestA : public IInterface { public: virtual void func1() {} virtual void func2() {} virtual void func3() {} virtual void func4() {} virtual void func5() {} virtual void func6() {} }; |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class CMgr : { public: void init() { // construct interface CTestB } void test() { // ... if (interface) { // 调用了func6 interface->func6(); } } private: IInterface* interface; }; |
B类里面继承了接口类
|
1 2 3 4 5 6 7 8 9 |
class IInterface { public: virtual void func1() = 0; virtual void func2() = 0; virtual void func3() = 0; virtual void func4() = 0; virtual void func5() = 0; virtual void func6() = 0; } |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class CTestB : public IInterface { public: virtual void func1() {} virtual void func2() {} virtual void func3() { // func3的断点却触发了 // func3传进来的参数是0x000001 // func3内的代码使用该参数的地方发生奔溃 } virtual void func4() {} virtual void func5() {} virtual void func6() {} } |
原因
A库项目使用了B库生成的lib静态库A库的IInterface.h少了几个函数,和B库的IInterface.h内容不一样- 最后同步了一下接口文件的内容解决问题
声明:本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ breakpad记述:Windows07/27
- ♥ Duilib应用:安装程序相关09/30
- ♥ Windows 核心编程 _ 内核对象一06/04
- ♥ Windows 核心编程 _ 线程内幕07/06
- ♥ Windows 核心编程 _ 内核对象:线程同步一07/29
- ♥ Soui六06/01