ウィンドウの非クライアント領域で、メニュー バーの右側に描画できるようにしたいと考えています。
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 テーマなどでも動作します。