Adding items to the title bar
-
Is it possible to add icons to a dialog window's title bar? I'd like to add some LED-style status indicators to a dialog-based MFC application which should be shown next to the close/maximize/minimize icons. I imagine it's to do with non-client area painting but I couldn't find sample code. I don't want to create the whole title bar - there are examples around for that - but just add an icon or a bitmap.
-
Is it possible to add icons to a dialog window's title bar? I'd like to add some LED-style status indicators to a dialog-based MFC application which should be shown next to the close/maximize/minimize icons. I imagine it's to do with non-client area painting but I couldn't find sample code. I don't want to create the whole title bar - there are examples around for that - but just add an icon or a bitmap.
Check if WM_NCPAINT message helps: http://msdn.microsoft.com/en-us/library/dd145212(VS.85).aspx[^] http://www.codeguru.com/cpp/w-d/dislog/titlebar/article.php/c1987[^]
-
Check if WM_NCPAINT message helps: http://msdn.microsoft.com/en-us/library/dd145212(VS.85).aspx[^] http://www.codeguru.com/cpp/w-d/dislog/titlebar/article.php/c1987[^]
It didn't really help. I assume the sample code should go into an override of CWnd::DefWindowProc, so I tried this:
/*virtual*/ LRESULT CMyDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_NCPAINT)
{
LRESULT lRes = CDialog::DefWindowProc(message, wParam, lParam);
HDC hdc = ::GetDCEx(GetSafeHwnd(), (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN);
// Paint into this DC
if (hdc)
{
CDC dc;
dc.Attach(hdc);
CBrush brush(HS_FDIAGONAL, RGB(255, 255, 255));
dc.FillRgn(CRgn::FromHandle((HRGN)wParam), &brush);
}
::ReleaseDC(GetSafeHwnd(), hdc);
return lRes;
}
return CDialog::DefWindowProc(message, wParam, lParam);
}A breakpoint on the 'if (hdc)' line would be hit but a breakpoint on the 'CDC dc' line wouldn't, so hdc seems to be 0 all the time :-( Anyway, thanks for the reply!
modified on Saturday, April 24, 2010 3:52 PM
-
It didn't really help. I assume the sample code should go into an override of CWnd::DefWindowProc, so I tried this:
/*virtual*/ LRESULT CMyDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_NCPAINT)
{
LRESULT lRes = CDialog::DefWindowProc(message, wParam, lParam);
HDC hdc = ::GetDCEx(GetSafeHwnd(), (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN);
// Paint into this DC
if (hdc)
{
CDC dc;
dc.Attach(hdc);
CBrush brush(HS_FDIAGONAL, RGB(255, 255, 255));
dc.FillRgn(CRgn::FromHandle((HRGN)wParam), &brush);
}
::ReleaseDC(GetSafeHwnd(), hdc);
return lRes;
}
return CDialog::DefWindowProc(message, wParam, lParam);
}A breakpoint on the 'if (hdc)' line would be hit but a breakpoint on the 'CDC dc' line wouldn't, so hdc seems to be 0 all the time :-( Anyway, thanks for the reply!
modified on Saturday, April 24, 2010 3:52 PM
hummm .... see the comments at http://msdn.microsoft.com/en-us/library/dd145212%28VS.85%29.aspx#CommunityContent[^] Looks like MSDN didn't tell the whole story: Just copied from the user commnt
Getting the device context when handling WM_NCPAINT does not work as described. Additional undocumented flag 0x10000 has to be used:
case WM_NCPAINT:
{
HDC hdc;
hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW | DCX_INTERSECTRGN | 0x10000);
// Paint into this DC
ReleaseDC(hwnd, hdc);
}(Verified on Windows XP)
2 bugs found. > recompile ... 65534 bugs found. :doh:
-
hummm .... see the comments at http://msdn.microsoft.com/en-us/library/dd145212%28VS.85%29.aspx#CommunityContent[^] Looks like MSDN didn't tell the whole story: Just copied from the user commnt
Getting the device context when handling WM_NCPAINT does not work as described. Additional undocumented flag 0x10000 has to be used:
case WM_NCPAINT:
{
HDC hdc;
hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW | DCX_INTERSECTRGN | 0x10000);
// Paint into this DC
ReleaseDC(hwnd, hdc);
}(Verified on Windows XP)
2 bugs found. > recompile ... 65534 bugs found. :doh:
-
Is it possible to add icons to a dialog window's title bar? I'd like to add some LED-style status indicators to a dialog-based MFC application which should be shown next to the close/maximize/minimize icons. I imagine it's to do with non-client area painting but I couldn't find sample code. I don't want to create the whole title bar - there are examples around for that - but just add an icon or a bitmap.
Thanks to all who helped me. I finally found a solution. 1. Insert the ON_WM_NCPAINT() macro into the dialog's message map, and create an overwritten OnNcPaint method. 2. In OnNcPaint, first call the derived OnNcPaint method, then get the paint DC by calling GetWindowDC(), and paint into the DC whatever you want to paint. That's it. It is a good idea to exit the function before painting if IsWindowVisible() returns false, or if IsIconic() returns true, because there is no visible title bar to paint on. If you don't want to paint over the close, minimize, etc. icons, you can retrieve their positions by calling GetTitleBarInfoEx. This function is unfortunately not defined in CWnd, so you must define it as
BOOL GetTitleBarInfoEx(HWND hWnd, PTITLEBARINFOEX pstInfo)
{
return ::SendMessage(hWnd, WM_GETTITLEBARINFOEX, 0, (LPARAM)pstInfo);
}GetTitleBarInfoEx will return FALSE unless running Vista and up, so you must check its return value and call GetTitleBarInfo if the call to GetTitleBarInfoEx is not successful. GetTitleBarInfo is a member of CWnd :-) If you want to put a flashlight on the title bar, create a timer event which changes a flag (which indicates whether the light is on or off) and then calls
RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
. This will post the WM_NCPAINT message. What I wrote is for CDialog derived classes. I read (but I haven't tried it) that for MDI applications, you must insert this functionality into the main frame.modified on Friday, June 18, 2010 3:50 AM