7
votes

I'm writing a Win32 plug-in DLL for a third-party MFC app. The DLL needs to display a modal dialog. When I do this using DialogBox() or other plain Win32 API (e.g. I tried to write my own modal loop), the main application's window doesn't redraw all elements: it redraws standard elements, but not the client area. Modeless dialogs display just fine.

Screenshot

I suspect this happens because MFC doesn't really have modal dialogs in Win32 sense. It can only have one message loop and a separate loop in DialogBox() disrupts its delicate machinery. Here's a CodeProject article that explains this. But this CodeProject article is 9 years old, so maybe things have changed since then. Could somebody shed some light on this? The app uses MFC 8 (i.e. mfc80.dll).

Update. Here's a link to the original question; it may contain some additional information.

Update 2. Thanks everyone; I really appreciate all the advice, it certainly helps me to get the big picture of how things fit together. The first path I'm going to explore is to use native MFC 'modal' dialogs. (Since I do all this from Python, I'll use Python bindings for MFC, pywin32). This will take some time; when it's ready, I'll update the post with results.

1
+1 good question, I'll be interested to see the answer!David Heffernan
Also see stackoverflow.com/questions/5058929 of which this question is a followup (more or less).0xC0000022L
could you please use Spy++ (comes with Visual Studio) or some other similar application (one I know can be found at catch22.net/software/winspy) to find out whether the client area of the "Console" window is more than a single child window?!0xC0000022L
@STATUS There are a few child windows: at the top is a thick XTPTooBbar, below is a Dialog (#32770) (the one with 'Layout'), then there's also two scrollbars and a custom 'grow box' between them (not visible here). They all redraw properly. There's no other child windows. What does not redraw is the client area of the 'Console' window.Mikhail Edoshin

1 Answers

4
votes

Every thread can have a message loop. Put your modal dialog into a separate thread and emulate the standard behavior of Windows by disabling the parent window.

Edit: after some discussion (see below) it appears that the parent code behaves incorrectly.

Still, I think there are possible workarounds. One could be a parent window (to the modal dialog, but child to the one that currently behaves incorrectly) that overlays the erroneous window content, but redraws it from a DC in memory to mimic correct behavior. Of course the parent window still would have to be disabled. Another solution may be to subclass the parent window, to correct the behavior. Since the plugin would run within the same process, the implementation should be straightforward.