singlepost

Вопрос для знатаков WinApi =) << На главную или назад  

Есть окно у которого фон закрашен невидимой кистью:
w.hbrBackground=(HBRUSH)GetStockObject(NULL_BRUSH);

В окне выводится текст без заднего фона:
SetBkMode(hdc, TRANSPARENT);
TextOut(hdc, 38, 10, h1, 10);

При перерисовке окна
InvalidateRect(hwnd, NULL, 1);
старый тексе не стирается, почему? InvalidateRgn то же не помогает.Если вместо NULL_BRUSH взять любу другую (например BLACK_BRUSH) то все нормально.
И еще почему окно не реагирует SendMessage(WM_PAINT) (незавсимо от фона) а только на Invalidate

9 ответов в теме “Вопрос для знатаков WinApi =)”

  1. 8
    Сергей Фирсов ответил:

    Спасибо.

  2. 7
    Анатолий Лютин ответил:

    ->При создании окна задний фон делается из того что было под окно, как при перерисовке сново это сделать.

    Только попиксельно копировать то что было, а потом обратно это рисовать через Bitblt или что-то похожее, либо уповать на то, что нужная область не будет чем-то перерисована..

    Приведу аналогию:
    Вы вывели на экран содержимое какого-нибудь случайного указателя (условный аналог вашего окна, закрашенного NULL_BRUSH), вам показалось какое-нибудь значения типа 0×67DAAA8, потом что-то делайте с кучей и после этого хотите, чтобы содержимое этого случайного указателя опять было равно0×67DAAA8, такое может случится только случайно, в 99% случаев значение этого указателя будет не определено (при условии, что указатель не константный и куча активно используется )…

    Как-то так…

  3. 6
    Сергей Фирсов ответил:

    При создании окна задний фон делается из того что было под окно, как при перерисовке сново это сделать.

  4. 5
    Анатолий Лютин ответил:

    Смысл в отправке SendMessage(WM_PAINT) состоит в том, что вы хотите принудительно попасть в обработчик WM_PAINT заданного окна, ведь вопрос не только в отрисовке, программист может переопределить этот обработчик как угодно, хоть файлы загружать, хоть по TCP/IP пакеты слать..

    Старый текст не затирается из-за, как указано ранее, NULL_BRUSH, API просто не знает _чем_ должно закрашиваться окно и поэтому оставляет старое значение содержимого без изменений, тут всё в порядке. Если вы хотите, чтобы фон перекрашивался, так объясните бедному Windows что вы хотите нарисовать на заднем фоне – всё окно белым залить, чёрным, случайными цветами и т.д.

  5. 4
    Александр Чигринец ответил:

    В SendMessage(WM_PAINT), по моему, никакого смысла нет. По хорошему это сообщение должно иметь параметром DC на котором желательно отрисовать окно.

    А зачем отдельно перерисовывать задний фон?

  6. 3
    Сергей Фирсов ответил:

    Какой тогда смысл в сообщении SendMessage(WM_PAINT)
    Есть ли способ заставить перерисовывать задний фон?

  7. 2
    Александр Чигринец ответил:

    Читаем документацию
    //support.microsoft.com/kb/66532 :
    Many GDI functions use the current brush to fill interiors and the current pen to draw lines. In some cases, an application may not want to modify the areas normally affected by the pen or brush. Selecting a NULL_PEN or NULL_BRUSH into the device context tells GDI not to modify the normally affected areas. In short, "NULL_" objects do not draw anything.

    Т.е. присвоение окну NULL_BRUSH означает, что фон не перерисовывается при отработке сообщения WM_ERASEBKGND

    Кроме того WM_PAINT само по себе ничего отрисовывать не будет, если регион не инвалидирован. Это сообщение приходит достаточно часто и грамотно написанный обработчик полную отрисовку каждый раз не выполняет. Для этого Invalidate и придуман.

  8. 1
    Alexx Sav ответил:

    есле мне память не изменяет надо рефрешзапустить ….виндовоспросто так рабоать не хочет)

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.