#windows #gdi
#Windows #gdi
Вопрос:
Я пытаюсь нарисовать значок в строке заголовка диалогового окна Windows. Я не пытаюсь заменить обычный значок для диалогового окна. Я пытаюсь нарисовать значок в дополнение к значкам сворачивания, разворачивания / восстановления и закрытия. С этой целью я отправляю сообщение WM_GETTITLEBARINFOEX, чтобы я мог вычислить свою позицию. Как я ни пытаюсь, я не могу нарисовать значок в моем списке изображений. Я смог нарисовать значок в клиентской области. Я, наконец, просто попытался нарисовать (0,0) и (100,0), а теперь в середине строки заголовка. Я просто никогда не вижу значок в строке заголовка. Я также добавил код для рисования под строкой заголовка, чтобы убедиться, что с моим значком все в порядке, и значок отображается в окне.
Сначала я переопределяю OnNcPaint, вызываю базовый класс, а затем мою процедуру для рисования моего значка.
аннулировать MyDialog::OnNcPaint() {
CDialog::OnNcPaint();
CWindowDC dc(this);
DrawNonClientArea( amp;dc );
}
аннулировать MyDialog::DrawAttachIcon(CDC * pDC) {
if( -1 != m_AttachIconIndex amp;amp; pDC )
{
TITLEBARINFOEX TitleBarInfoEx;
TitleBarInfoEx.cbSize = sizeof( TitleBarInfoEx );
::SendMessage( GetSafeHwnd(), WM_GETTITLEBARINFOEX, 0, (LPARAM)amp;TitleBarInfoEx );
// As per the MSDN, rectangle indexes are 0 (reserved), 1 (reserved), 2 - minimize button, 3 - maximize button, 4 - help button and 5 close button.
CSize sizeClose( TitleBarInfoEx.rgrect[5].right - TitleBarInfoEx.rgrect[5].left, TitleBarInfoEx.rgrect[5].bottom - TitleBarInfoEx.rgrect[5].top );
CSize sizeMaximize( TitleBarInfoEx.rgrect[3].right - TitleBarInfoEx.rgrect[3].left, TitleBarInfoEx.rgrect[3].bottom - TitleBarInfoEx.rgrect[3].top );
CSize sizeMinimize( TitleBarInfoEx.rgrect[2].right - TitleBarInfoEx.rgrect[2].left, TitleBarInfoEx.rgrect[2].bottom - TitleBarInfoEx.rgrect[2].top );
int padding_x = TitleBarInfoEx.rgrect[5].left - TitleBarInfoEx.rgrect[3].right;
int padding_y = TitleBarInfoEx.rgrect[5].top - TitleBarInfoEx.rcTitleBar.top;
CPoint pt;
pt.x = TitleBarInfoEx.rgrect[2].left - sizeMinimize.cx;
pt.y = TitleBarInfoEx.rgrect[2].top;
// I give up. Try to draw in the middle of the caption.
pt.x = (TitleBarInfoEx.rcTitleBar.right - TitleBarInfoEx.rcTitleBar.left)/2; pt.y = 0;
m_ilIconAttachToFrame.Draw( pDC, m_AttachIconIndex, pt, ILD_NORMAL );
pt.y = 200;
m_ilIconAttachToFrame.Draw( pDC, m_AttachIconIndex, pt, ILD_NORMAL );
}
}
Эти последние две строки должны были просто отображаться в окне, и значок отображается там, где я ожидаю. Я также выделил сначала заполненную прямоугольную область на значках (закрыть, свернуть …), А затем всю область заголовка, используя прямоугольную область из информации в строке заголовка. И даже взорвал прямоугольник по всему окну, в результате чего только клиентская область была окрашена в цвет. Есть ли прямоугольник исключения над заголовком? Я вызвал GetClipRgn, и возвращаемое значение было равно нулю, поэтому я не думаю, что есть.
Комментарии:
1. Обратите пристальное внимание на свои координатные пространства. TITLEBARINFOEX использует экранные координаты, но окно DC находится в оконных координатах.
2. Привет, Рэймонд, я добавил вызов ScreenToClient. Те же результаты. Кроме того, в моем тестировании я просто сдался и установил pt.x = 0; pt.y = 0; Затем я установил pt.x равным 100. Я также переместил свое окно на главный монитор и установил его на (0,0), чтобы посмотреть, что произойдет. Даже с моим изменением единственный рисунок, который я получаю, — это когда я добавляю 200 к pt. y. Затем он рисуется с центром по ширине и при y = 200. Все еще пытаюсь понять, почему.
3. Возможно, некоторый прогресс. Я удалил вызов CDialog::OnNcPaint . Мое окно отображается с другим фреймом. Он использовал стандартный дочерний фрейм вместо всплывающего фрейма. Но, когда я изменил размер своего окна, я вижу свое растровое изображение как в строке заголовка, так и ниже в клиентской области из-за моего дополнительного вызова для повторного отображения с y = 200. Я предполагаю, что если я реализую OnNcPaint, я не должен вызывать базовый код CDialog, и вместо этого я должен отображать все сам. Совсем не то, на что я надеялся. Я просто хочу нарисовать свое изображение. Я собираюсь посмотреть, смогу ли я рисовать, создать область исключения, а затем вызвать базовый код.
4. Ну и дела. Я нашел часть своего собственного очень старого кода, в котором есть комментарий, в котором говорится, что не вызывайте базовый код MFC. Похоже, мне нужно реализовать весь чертеж NC. Крысы.