非クライアント領域で描画するにはどうすればよいですか?
質問
メニューバーの右側、ウィンドウの非クライアント領域で描画できるようにしたいと考えています。
C++/MFCを使用してこれは可能ですか?
解決
チャーリーは答えを思いつきました WM_NCPAINT
. 。MFC を使用している場合、コードは次のようになります。
// in the message map
ON_WM_NCPAINT()
// ...
void CMainFrame::OnNcPaint()
{
// still want the menu to be drawn, so trigger default handler first
Default();
// get menu bar bounds
MENUBARINFO menuInfo = {sizeof(MENUBARINFO)};
if ( GetMenuBarInfo(OBJID_MENU, 0, &menuInfo) )
{
CRect windowBounds;
GetWindowRect(&windowBounds);
CRect menuBounds(menuInfo.rcBar);
menuBounds.OffsetRect(-windowBounds.TopLeft());
// horrible, horrible icon-drawing code. Don't use this. Seriously.
CWindowDC dc(this);
HICON appIcon = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
::DrawIconEx(dc, menuBounds.right-18, menuBounds.top+2, appIcon, 0,0, 0, NULL, DI_NORMAL);
::DestroyIcon(appIcon);
}
}
他のヒント
非クライアント領域に描画するには、(「クライアント」DC ではなく)「ウィンドウ」DC を取得し、「ウィンドウ」DC に描画する必要があります。
WM_NCPAINT を処理してみる必要があります。これは通常の WM_PAINT メッセージに似ていますが、クライアント領域だけではなくウィンドウ全体を処理します。WM_NCPAINT に関する MSDN ドキュメントには、次のサンプル コードが記載されています。
case WM_NCPAINT:
{
HDC hdc;
hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN);
// Paint into this DC
ReleaseDC(hwnd, hdc);
}
このコードは、アプリケーションのメッセージ ループで使用することを目的としており、大きな 'switch' ステートメントを使用して標準的に編成されています。
Shog の MFC の例で述べたように、必ずデフォルトのバージョンを呼び出してください。この例では、DefWindowProc の呼び出しを意味します。
メニュー バーに何かを表示したいだけの場合は、右揃えのメニュー項目として追加する方が簡単できれいかもしれません。こうすることで、さまざまな Windows テーマなどでも動作します。
所属していません StackOverflow