Win32: модальный диалог оставляет след в клиентской области родителя / владельца - PullRequest
0 голосов
/ 20 февраля 2011

Я пишу плагин для приложения; плагин для отображения модального диалога. Он отображается очень хорошо, но когда я перемещаю его, он оставляет след на экране, т.е. окно ниже не перерисовывается. Некоторые его части перерисовываются (все стандартные элементы управления Windows, например, панель инструментов или полоса прокрутки), но остальная часть клиентской области - нет.

Я использую DialogBoxIndirectParam; hWnd - это верхнее окно приложения, шаблон, который я создаю на лету, и флаги диалога WS_POPUP | WS_CAPTION | DS_MODALFRAME | DS_SETFONT | WS_SYSMENU, плюс функция сама устанавливает некоторые флаги, например, WS_CLIPSIBLINGS. Класс диалога является стандартным (CS + DBLCLKS, CS_SAVEBITS). Процедура диалога очень проста, в настоящий момент она обрабатывает только сообщение WM_CLOSE.

Я попробовал Google, но мне не удалось найти что-либо непосредственно релевантное. Я попытался сравнить свой класс диалога с другими диалоговыми окнами того же приложения, а также проверил журналы сообщений, но я не увидел каких-либо существенных отличий.

Почему родитель / владелец не перерисовывает и как это исправить?

Обновление . Вот соответствующие звонки.

Вызов диалога:

class Dialog(object):
    def run(self):
        t = cast(c_char_p(self.template()), LPCDLGTEMPLATE)
        p = GetActiveWindow()
        r = DialogBoxIndirectParamW(0, t, p, dialog_proc_2, py_object(self))

Оконная процедура:

def dialog_proc(window, message, wparam, lparam):
    if message == WM_CLOSE:
        EndDialog(window, IDCANCEL);
        return 1
    return 0

Это код Python :) это встроенный Python, работающий через ctypes. Плагин работает в основном потоке; хост-приложение выполняет синхронный вызов, то есть ожидает возврата вызванной функции. self.template() возвращает DLGTEMPLATEEX данные, которые я готовлю на лету; Я считаю, что я делаю это правильно, потому что отображается диалоговое окно, и когда я проверяю его с помощью Spy, все флаги, кажется, установлены (за исключением того, что есть еще несколько). Я не использую дескриптор экземпляра, потому что я ничего не загружаю из ресурсов. Я считаю, что правильно обернул все функции и константы, но я также могу опубликовать определения. GetActiveWindow (или GetForegroundWindow) возвращает указатель на главное окно приложения; это приложение MDI, и оно перерисовывает все, кроме клиентской области окна MDI:

Screenshot of the problem showing the trail

Здесь я переместил окно поверх всех видимых окон (панелей инструментов, кнопок и т. Д.), И единственная часть, которая не перерисовывается, - это клиентская область документа MDI.

1 Ответ

2 голосов
/ 20 февраля 2011

Вам нужно перекачать очередь сообщений, чтобы заставить цикл рисования работать. Кажется, что происходит некоторая прокачка (вы говорите, что некоторые элементы управления перерисовываются).

Так как модальные диалоги запускают свой собственный насос сообщений, я собираюсь сделать дикое предположение, что хост вашего плагина имеет некоторую специальную обработку сообщений, возможно, ошибочную, в своем насосе сообщений и что ваш стандартный насос сообщений диалогового окна делает вещи по-другому.

Я угадываю и делаю большие прыжки веры, но я подозреваю, что цикл сообщений вашего хост-приложения не имеет стандартной формы TranslateMessage / DispatchMessage. Если это так, то вы по-настоящему закопаны.

Без подробностей действительно невозможно сказать что-либо с большой уверенностью. Как говорит Ганс, минимальное воспроизведение позволит легко решить эту проблему.

...