Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I've accepted oystein's answer, since it led me to the solution, but I thought I'd post my modifications. I had to modify it a bit to make it work for me, so it might come in useful to someone else.</p> <p>For the record, the dimming works well, but it doesn't look as natural as I hoped. In an application which frequently brings up dialogs, the dimming becomes distracting in its regularity of seemingly switching the main window on and off. To compromise, I've made the dimming fairly subtle (about 25% opacity) which gently highlights the active dialog; the instant dimming is still a little distracting, but I'm not sure how to have it fade in or fade out smoothly, especially when scoped.</p> <p>Also, I'm not a UI expert, but the dimming gave me a sort of impression that the dialog was less related to the window content behind it. This made it feel a bit detached from what I was working on in the application, even though the dialogs are directly manipulating that content. This might be another distraction.</p> <p>Here it is anyway:</p> <p><strong>CDimWnd.h</strong></p> <pre><code>// Dim the application main window over a scope. Creates dimmer window in constructor. class CDimWnd : public CFrameWnd { public: CDimWnd(); BOOL OnEraseBkgnd(CDC* pDC); ~CDimWnd(); protected: DECLARE_MESSAGE_MAP() }; </code></pre> <p><strong>CDimWnd.cpp</strong></p> <pre><code>#include "stdafx.h" #include "CDimWnd.h" #include "MainFrm.h" BEGIN_MESSAGE_MAP(CDimWnd, CFrameWnd) ON_WM_ERASEBKGND() END_MESSAGE_MAP() // For preventing two dimmer windows ever appearing bool is_dimmer_active = false; CDimWnd::CDimWnd() { // Get the main frame of the application which we want to dim. CMainFrame* pParent = theApp.pMainFrame; // Don't do anything if the main frame doesn't appear to be there, // or if there is already dimming happening. if (pParent != NULL &amp;&amp; !is_dimmer_active) { // Get the client area of the window to dim. CRect rc; pParent-&gt;GetClientRect(&amp;rc); pParent-&gt;ClientToScreen(&amp;rc); // convert to screen coordinates // Do some fudging to fit the client area exactly. // Other applications may not need this if the above client area fits already. rc.top += GetSystemMetrics(SM_CYFRAME); rc.top += GetSystemMetrics(SM_CYCAPTION); // MFC feature pack seems to include caption in client area rc.left -= GetSystemMetrics(SM_CXBORDER); rc.right += GetSystemMetrics(SM_CXBORDER) + 1; rc.bottom += GetSystemMetrics(SM_CYBORDER) + 1; // Create a layered window for transparency, with no caption/border. CreateEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW, NULL, TEXT(""), WS_POPUP, rc.left, rc.top, rc.Width(), rc.Height(), pParent-&gt;GetSafeHwnd(), NULL); // Bring in front of main window. BringWindowToTop(); // Apply 25% opacity SetLayeredWindowAttributes(RGB(0,0,0), 64, LWA_ALPHA); // Show the dimmer window ShowWindow(SW_SHOW); is_dimmer_active = true; } } CDimWnd::~CDimWnd() { is_dimmer_active = false; } BOOL CDimWnd::OnEraseBkgnd(CDC* pDC) { // Fill with black CBrush backBrush(RGB(0, 0, 0)); CBrush* pOldBrush = pDC-&gt;SelectObject(&amp;backBrush); CRect rect; pDC-&gt;GetClipBox(&amp;rect); // Erase the area needed pDC-&gt;PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY); pDC-&gt;SelectObject(pOldBrush); return TRUE; } </code></pre> <p>Usage is dead simple: because CDimWnd creates itself in its <em>constructor</em>, all you need to do is add <code>CDimWnd dimmer</code> as a member of the dialog class, and it automatically dims the main window, no matter where you call the dialog from.</p> <p>You can also use it within a scope to dim system modal dialogs:</p> <pre><code>{ CDimWnd dimmer; MessageBox(...); } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload