将Windows消息发送到在不同线程中创建的对话框时出现问题 [英] Issues sending windows messages to dialog boxes created in different threads

查看:119
本文介绍了将Windows消息发送到在不同线程中创建的对话框时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个自定义数据结构,该结构是对象和二进制树的二进制树.即:顶级树中的每个节点都可以是对象"或"objectContainer"(反过来,节点可以有"object"或"objectContainer").

我的主线程中有一个消息泵,通过该泵,我可以处理所有用于主窗口的窗口消息(单击,拖动和调整大小,按下按钮).当它不处理Windows消息时,它会打勾计时器并更新场景.当主窗口接收到特定的击键时(当前),它会旋转出一个新线程,然后该线程创建一个新对象(或objectContainer),并在创建新对象的过程中产生一个模态(阻止)对话框以便用户可以与新创建的对象交互/输入初始值.单击确定"后,如果提供的名称是唯一的(关于顶层容器的内容),则将新对象添加到顶层容器.最后,如果打开了一个模式对话框(从另一个线程中产生),该对话框显示了(在本例中为顶级)容器的内容,则向该对话框发送WM_message,以告知其添加新项目的名称将显示在字符串列表框中.我在将这些消息发送到对话框时遇到问题.例如,当我创建一个objectContainer时,按下OK按钮后,正确的名称会立即显示在列表中,但是如果我正在创建一个对象,则不会显示正确的名称.我以为它可能与线程有关,但我不知道.每种类型的对象都使用相同的addObject()函数,这是测试容器的显示框是否打开并发送消息的地方.

我尝试过的事情:

我读过一些文章说永远不要使用线程……除非绝对必要!并且所有UI应该在同一线程中完成.甚至有人说只能通过主线程执行UI.我尝试使用一些我觉得这些文章的作者建议的技术来改变我的应用程序,但是有些不对劲.

我制作了一个版本,在该版本中,当按下按钮时,主线程会生成一个无模式对话框,该对话框负责与新创建的对象进行交互的工作.这很有效,除了,如果说用户长时间在无模式对话框中拖动时,主进程会停滞不前.我在主消息泵的IsDialogMessage部分之后有一个函数,用于计算帧速率,并且当用户单击并按住无模式对话框时,该函数会运行.我不希望发生这种情况,更新场景的功能要等到用户放开后才能运行. (想一想,如果我在主窗口周围拖动,帧速率处理也会停顿……但是我怀疑这是不可避免的,对吗?除非该处理是在其自己的线程中进行的??)

我还创建了一个版本,单击该按钮后,主线程会旋转出一个新线程,新线程将创建新对象或objectContainer,并且在创建新项目后立即产生一个无模式对话框来editObject().使用无模式对话框,调用线程不会被阻塞,因此我在创建所述无模式对话框后直接添加了一个消息泵,它似乎正在运行.我还没有测试过对象的添加,并没有验证名称在顶级容器中是唯一的.我不知道wm_messages是否会到达正确的窗口并根据需要控制对话框的字符串列表框.

我在每次设计尝试时都遇到问题,并且想知道您对设计的想法,然后再花更多的时间调试错误的设计.主线程是否应该拆分线程并调用模式对话框?还是应该从主线程中调用所有对话框,然后以某种方式将我认为需要不断处理的内容移到其自己的线程中?还是主线程应该剥离线程,然后使用无模式对话框?

I am building a custom data structure that is a binary tree of objects and binary trees. ie: each node in the top level tree could be an "object" or an "objectContainer" (which in turn could have "object"s or "objectContainer"s for nodes).

I have a message pump in my main thread, through this pump I handle all the windows messages intended for my main window (clicks, drags and resizing, button presses). And when it is not dealing with windows messages it ticks a timer and updates the scene. When the main window receives a specific key stroke it (currently) spins off a new thread, that thread then creates a new object (or objectContainer) and, during the new object''s creation, a modal (blocking) dialog box is spawned so that the user can interact with/input initial values for the newly created object. Upon clicking OK, if the name provided is unique (with regards to the contents of the top level container), the new object is added to the top level container. Finally, if a modal dialog box (spawned from inside yet another thread) that displays the contents of a (in this case the top level) container, is open, I send a WM_message to said dialog box that is intended to tell it to add the new item''s name to a list box of strings. I am having issues with the sending of these messages to dialog boxes. For instance, when I create an objectContainer the correct name appears in the list right away after pressing the OK button, but not if I am creating an object. I assumed it may have something to do with threading, but I do not know. Each type of object uses the same addObject() function, which is where the container''s displaying box is tested to be open or not and the message is sent.

What I have tried:

I have read articles that say never use threading… unless you absolutely have to! And that all UI should be done in the same thread. Some even say to only do UI through the main thread. I have tried variations of my application with some of the techniques I feel like the authors of these articles are suggesting but something is not right.

I made a version in which, when the button is pressed, the main thread spawns a modeless dialog that does the work of interacting with the newly created object. This works well except for, if say the user is dragging around a modeless dialog box for a long period of time, the main process gets stalled. I have a function after the IsDialogMessage part of the main message pump that calculates frame rate and it tanks when the modeless dialog box is clicked and held by the user. I don’t think I want that happening, the functions that update the scene are not run until the user lets go. (come to think of it, if i drag around the main window the frame rate processing stalls too... but i suspect that is unavoidable, right? unless that processing is in its own thread...?)

I have also created a version where once the button is clicked the main thread spins off a new thread, the new thread creates the new object or objectContainer and right after the new item is created it spawns a modeless dialog box to editObject(). With the modeless dialog box the calling thread is not blocked and so I added a message pump directly after the creation of said modeless dialog box and it appears to be working. I have not yet tested past the adding of the objects and verifying that the name is unique in the top level container. I do not know if the wm_messages will reach the correct window and control the dialog box''s string list box as I wish.

I am having issues with each of my design attempts and would just like to know your thoughts on design before I waste more time debugging a bad design. Should the main thread spin off a thread and call a modal dialog box? Or should all dialog boxes be called from the main thread and I, somehow, move what I think needs to be continually processing to its own thread? Or should the main thread spin off a thread and then use modeless dialog boxes?

推荐答案



近十年来没有听说过这个问题. :)

我建议您将所有窗口创建"和窗口管理"都保留在主线程中.模态窗口可能正在占用您的线程消息.

通过消息过滤器从模态循环中抢救线程消息 [模态循环会吃掉线程消息 [

如果希望线程能够接收线程消息,请避免从工作线程启动模式对话框. 相反,...让您的非GUI工作线程将消息发布回主线程,并允许该线程创建/管理所有窗口.

最好的祝福,
-大卫·德劳恩(David Delaune)
Hi,

Have not heard of this problem for nearly a decade. :)

I would recommend that you keep all ''window creation'' and ''window management'' in the main thread. Modal windows may be eating your thread messages.

Rescuing thread messages from modal loops via message filters[^]

Thread messages are eaten by modal loops[^]

You are indeed looking at a bad software design... be careful because some of these message eating bugs happen less than 1% of the time... if this is commercial software you may have hundreds of customers complaining of bugs while you are sitting in your office saying "It works for me!"

Avoid launching a modal dialog from a worker thread if you expect the thread to be able to receive thread messages. Instead... have your non-GUI worker threads post a message back to the main thread and allow that thread to create/manage ALL windows.

Best Wishes,
-David Delaune


这篇关于将Windows消息发送到在不同线程中创建的对话框时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆