В моем диалоговом окне нет области, не относящейся к клиенту, потому что я хочу нарисовать пользовательскую строку заголовка. Но это означает, что системное меню не отображается, когда пользователь нажимает на заголовок.
Я изменил WM_NCHITTEST, чтобы отвечать HTCLIENT для моего заголовка, и я могу перехватить сообщение WM_NCRBUTTONUP, но мне нужна помощь с отображением системного меню, я не могу найти, как это сделать правильно.
Пока у меня есть это:
void CSkinnedDialog::OnNcRButtonUp( UINT nHitTest, CPoint point )
{
CMenu* pMenu = GetSystemMenu(FALSE);
if (int cmd = pMenu->TrackPopupMenu(TPM_RETURNCMD, point.x, point.y, this))
SendMessage(WM_SYSCOMMAND, cmd, MAKELPARAM(point.x, point.y));
}
void CSkinnedDialog::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
LRESULT CSkinnedDialog::OnNcHitTest( CPoint point )
{
LRESULT res = CDialog::OnNcHitTest(point);
ScreenToClient(&point);
if (res == HTCLIENT && point.y < m_nFrameHeight)
{
res = HTCAPTION;
}
return res;
}
void CSkinnedDialog::SysMenuAddAboutEntry()
{
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, "About...");
}
}
Показывает системное меню, но работает не очень хорошо. Он не реагирует на все команды, которые пользователь может выбрать (например, нажатие на пункт меню «О программе» ничего не делает, а некоторые действия, которые следует отключить и выделить серым, такие как максимизация и восстановите, пока не нажмете хотя бы один раз левой кнопкой на заголовке.