Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MFC's dialog-based app title bar highlighting visual artifacts on Windows 10 (i.e. bugs in CDialogEx)

I'm not sure why am I getting this visual artifact?

Here's how to repro:

I'm using Visual Studio 2017 Community. Create a new C++ -> MFC project:

enter image description here

Then specify "dialog based":

enter image description here

Then build as "Debug" x86 app and run it.

So I'm running it on Windows 10.

When this dialog-based process has focus, it looks as I would expect it:

enter image description here

but if I switch keyboard focus to some other app (by clicking on it), this dialog-based process still retains its title bar color:

enter image description here

I'm not sure if it's just a matter of a visual glitch or if there's a deeper mess-up with the window message handling. How do I correct it? (This wasn't an issue with older MFC projects.)

like image 632
c00000fd Avatar asked Dec 24 '22 02:12

c00000fd


2 Answers

I managed to replicate your problem and found a quick fix for it. You need to add the WM_ACTIVATE message handler to your main dialog, comment out the base class OnActivate and modify it like this:

void CMFCApplication1Dlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
    //CDialogEx::OnActivate(nState, pWndOther, bMinimized);

    // TODO: Add your message handler code here
    this->Default();
}

CWnd::Default call is needed to keep the active/inactive visualization of the default button.

like image 178
VuVirt Avatar answered Dec 25 '22 15:12

VuVirt


OK, as much as I appreciate @VuVirt's solution, it doesn't completely remove all the bugs that are shipped in the default Dialog-based solution in VS2017. It solves the title bar focus issue, but while continuing to develop my project I encountered another bug. So I'm copy-and-pasting it from my comment to his answer:

There's still some kinda screw-up there. I'm not sure if it's related to this fix or not. Ex: If you create a button and then in its handler try to do: CFileDialog d(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_EXPLORER, NULL, this); d.DoModal(); to open a file picker dialog. When file picker opens up, close it and see if the title bar of the parent MFC dialog window goes back to being active. In my case it remains inactive until I click onto the Windows taskbar and then back onto that MFC app.

After banging my head against the wall trying to see what is going on there, I decided to try an earlier solution proposed by @zett42 in the comments to my original question (i.e. to replace CDialogEx with CDialog) and it worked! All the bugs are gone!

So here's my verdict: CDialogEx is buggy af.

The resolution is quite simple: When you create a new dialog-based project use project-wide find-and-replace (in the Edit menu) and replace all occurrences of CDialogEx with CDialog. And that is it. (I tried to use VS2017's refactoring tool for that but it messed it up and didn't replace it all. So simple search-and-replace does the job.)

And if you think that you'll be missing some functionality without CDialogEx, then you won't. All it does (besides introducing bugs) is that it adds background images and colors to the dialog.

So until MS fixes those glaring bugs in their templates I'm sticking with this approach.

like image 38
c00000fd Avatar answered Dec 25 '22 15:12

c00000fd