小编Woo*_*y20的帖子

工作线程如何与主 UI 线程通信?

工作线程与主 UI 线程通信的最佳方式是什么?

摘要: 我的 C++/MFC 应用程序是基于对话框的。为了进行长时间的计算,主 UI 线程创建了多个工作线程。当工作线程在计算中取得进展时,它们会将进度报告给主 UI 线程,然后主 UI 线程会显示进度。

这对于数字进度值来说效果很好,这些值位于共享内存中(由工作人员写入,由 UI 读取),但我在处理文本进度消息时遇到了问题。我尝试的解决方案已经经历了多次迭代,但似乎都不起作用。

  1. 我让 UI 线程将控件指针传递给工作人员,工作人员直接更新 UI。这不是很有效,而且似乎是错误的方法。

  2. 我让工作人员使用 SendMessage 向 UI 线程的窗口发送消息。这就陷入了僵局。(在处理消息之前 SendMessage 不会返回。)

  3. 与 (2) 相同,但使用 PostMessage 发送到 UI 线程的窗口。这在一段时间内有效,然后消息就丢失了。(PostMessage 立即返回。)进一步调查显示,消息队列的配额(默认为 10,000)已被超出。

  4. 我增加了消息队列的配额(注册表中的变量 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\USERPostMessageLimit),但丢失消息的数量没有改变。

  5. 我让每个工作线程在 4 KB 缓冲区中缓冲消息,并在缓冲区填满时发送 PostMessage。此操作失败,因为 UI 线程从未收到任何消息。当我将缓冲区大小增加到 64 KB 时,情况也是如此。

工作线程以“最低”优先级运行,UI 线程以“正常”优先级运行。工作线程正在发送消息,代码如下

UIMessage *pUI=new UIMessage; // so it won't go out of scope (main dialog will delete it)
pUI->buffer=traceLineBuffer; pUI->nOutputs=traceN;
BOOL ok=::PostMessage(hWndMainDlg,TraceLineMsg,(WPARAM)pUI, NULL/*lParam*/);
Run Code Online (Sandbox Code Playgroud)

UI 正在使用类似的代码接收它们

BEGIN_MESSAGE_MAP(CMainDlg, CDialog)
...
ON_MESSAGE(TraceLineMsg,OnTraceLineMsg)
...
END_MESSAGE_MAP() …
Run Code Online (Sandbox Code Playgroud)

c++ mfc multithreading

5
推荐指数
1
解决办法
5759
查看次数

Visual Studio 2017 链接器出现错误 C4789

这是 64 位 Windows 7、Visual Studio 2017、C++ 项目。

当我使用编译器选项进行发布构建时,/sdl我收到错误 4789(如果/sdl未启用,这是一个警告)。

1>Finished searching libraries
1>Generating code
1>c:\program files (x86)\windows kits\10\include\10.0.10586.0\ucrt\corecrt_memcpy_s.h(50): error C4789: buffer 'buffer' of size 262144 bytes will be overrun; 262143 bytes will be written starting at offset 2
1>All 2506 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
Run Code Online (Sandbox Code Playgroud)

我想找出错误的原因。阅读 C4789 上的 MS 文档表明,存在函数memsetwmemsetmemcpy之一strcpy,它指定操作长度 > 目标长度。此外,这必须在编译/链接时知道,这意味着目标大小和操作长度都是常量。

我的困难在于,在我的项目中实际上有数百次使用命名函数,并且链接器无法识别哪一个是错误的。我还只搜索了那些目的地名为“ buffer”的目的地,但没有成功。

有什么办法可以缩小错误原因吗?

c++ visual-studio

5
推荐指数
0
解决办法
1104
查看次数

CRichEditCtrl:无法用 Unicode 字符串替换选择内容

在MFC/C++中,我有一个丰富的编辑2.0控件,class CRichEditCtrl,它是RichEdit20W. Rich edit 2.0 控件应该支持 Unicode。我用它来显示 Unicode 字符。但该ReplaceSel函数不接受 Unicode 字符串。例如

CRichEditCtrl re;
wstring line;
auto x = line.c_str(); // array of const wchar_t
re.ReplaceSel(x); // ERROR
Run Code Online (Sandbox Code Playgroud)

收到编译器错误,因为CRichEditCtrl::ReplaceSel原型为

void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE);
Run Code Online (Sandbox Code Playgroud)

并且LPCTSTR是一个const char *.

如何使用 Unicode 字符串进行替换?

Windows 11 专业版 Visual Studio 2022

c++ mfc cricheditctrl

2
推荐指数
1
解决办法
105
查看次数

C ++ std :: vector-如何修改由迭代器指定的元素?

我正在尝试更改向量的每个元素,但是由于对consts 的某些混淆,我的代码无法编译。这是一个大大简化的示例(我省略了向量的初始化):

std::vector<int> test;
for (auto iter = test.cbegin(); iter != test.cend(); ++iter)
{
    int v = *iter; // gets the correct element
    *iter = v * 2; // compile error
}
Run Code Online (Sandbox Code Playgroud)

编译器错误为“'iter':您无法分配给const变量”。如图所示,使用迭代器修改单个元素的正确方法是什么?

c++ stdvector

0
推荐指数
1
解决办法
62
查看次数