Как мне нарисовать значок в диалоговом окне Windows?

#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. Крысы.