Если в WM_COMMAND рисовать графические объекты (линия, прямоугольник и пр.), а сам WM_COMMAND вызывать по событиям WM_SIZE или WM_MOVE - при старте приложения графические объекты не отрисовываются. В отличие от Windows, там все корректно отображается.
Последовательность вызовов: WM_PAINT -> BeginPaint -> send_erase -> WM_ERASEBKGND -> FillRect после чего вся отрисовка, сделанная по WM_COMMAND стирается.
Возможное решение: отловить вызов BeginPaint из обработчика по умолчанию (DEFWND_DefWinProc) сообщения WM_PAINT.
После получения WM_WINDOWPOSCHANGED и обработки вызванных им WM_SIZE и WM_MOVE, происходит Expose. Из-за этого все, что не выводится в WM_PAINT не выводиться вообще. Этот Expose вызывается потому что WM_ERASEBKGND от ShowWindow чистит окно через раз (т.е. в половине случаев окно запускается с неочищенным фоном).
Если убрать последний вызов Expose, в случае когда фон не чиститься - не вызывается WM_PAINT и вообще никакая отрисовка не происходит.
Точнее WM_PAINT вызывается, а никакой отрисовки по нему нет.
Есть тест для BeginPaint(). В Windows по BeginPaint генерируется WM_NCPAINT и WM_ERASEBKGND только для окна-потомка. Во всех остальных случаях, в отличие от WINE не генерируется ничего. В WINE по BeginPaint ничего не генерируется только для невидимого окна.
(In reply to comment #6) > Есть тест для BeginPaint(). В Windows по BeginPaint > генерируется WM_NCPAINT и WM_ERASEBKGND только для > окна-потомка. Во всех остальных случаях, в > отличие от WINE не генерируется ничего. > В WINE по BeginPaint ничего не генерируется только > для невидимого окна. > Шикарно, подготавливаем тест, который всё это демонстрирует и отсылаем его в wine-patches.
Продолжаю разбираться с отрисовкой по WM_COMMAND.
Похоже обновляет фон в основном WINE-сервер (файл wine/server/window.c). Обработчик DECL_HANDLER(redraw_window) отлавливает все перекрытия активного окна и отвечает за его перерисовку. А ф-ция set_window_pos, вызывающая redraw_window, отвечает за обновление фона при создании окна.
(In reply to comment #9) > Похоже обновляет фон в основном WINE-сервер > (файл wine/server/window.c). Обработчик > DECL_HANDLER(redraw_window) отлавливает все перекрытия > активного окна и отвечает за его > перерисовку. redraw_window, по-моему, посылается функциями, а не wineserver это ловит. > А ф-ция set_window_pos, вызывающая > redraw_window, отвечает за обновление фона при > создании окна. set_window_pos - это "рабочая лошадка" функции WinAPI SetWindowPos. И она может посылать сигнал об обновлении окна при куче случаев - изменение позиции, z-порядка, активации и т.д. Так же SetWindowPos вызвается в других user32/winex11.drv функциях - ShowWindow, SetWindowRgn... Проблема в том, что по WM_COMMAND экран больше раз обновляется, чем в Windows.
Единственное корректное решение проблемы - это октлючение режима управления окнами. Тогда перерисовки, вызванной X-ами не будет, и все нарисованное по WM_COMMAND не сотрется. Альтернатива - разные нелепые хаки, запрещающие перерисовку окна, вызванную X-ами в некоторых ситуациях.
(In reply to comment #11) > Единственное корректное решение проблемы - > это октлючение режима управления окнами. Это некорректное решение проблемы :) > Альтернатива - разные нелепые хаки, > запрещающие перерисовку окна, вызванную > X-ами в некоторых ситуациях. Просто X-берут на себя слишком много по отрисовке. Они должны использоваться только 1 раз, в конце, когда WINE всё подготовит в памяти для отображения. А не в промежуточных стадиях.
Бага #827 Компаса с отрисовкой картинки в диалоге настройки решена.