Winapi Win32:模式对话框在父/所有者的客户端区域中留下一条线索

Winapi Win32:模式对话框在父/所有者的客户端区域中留下一条线索,winapi,modal-dialog,dialog,Winapi,Modal Dialog,Dialog,我正在为一个应用程序编写插件;该插件将显示一个模式对话框。它显示得很好,但当我移动它时,它会在屏幕上留下痕迹,即下面的窗口不会重新绘制。它的某些部分会重新绘制(所有标准的Windows控件,例如工具栏或滚动条),但客户端区域的其余部分不会 我使用的是对话框indirectparam;hWnd是应用程序的顶部窗口,我动态构建的模板和对话框标志是WS|u POPUP | WS|u CAPTION | DS|u MODALFRAME | DS|u SETFONT | WS|u SYSMENU,加上函数

我正在为一个应用程序编写插件;该插件将显示一个模式对话框。它显示得很好,但当我移动它时,它会在屏幕上留下痕迹,即下面的窗口不会重新绘制。它的某些部分会重新绘制(所有标准的Windows控件,例如工具栏或滚动条),但客户端区域的其余部分不会

我使用的是
对话框indirectparam
hWnd
是应用程序的顶部窗口,我动态构建的模板和对话框标志是
WS|u POPUP | WS|u CAPTION | DS|u MODALFRAME | DS|u SETFONT | WS|u SYSMENU
,加上函数本身设置一些标志,例如
WS|u CLIPSIBLINGS
。dialog类是标准的(CS+DBLCLKS,CS_SAVEBITS)。dialog过程非常基本,它目前只处理
WM_CLOSE
消息

我试过谷歌,但没有找到任何直接相关的东西。我试图将我的dialog类与同一应用程序的其他对话框进行比较,并查看了消息日志,但没有发现任何显著的差异

为什么父/所有者不重新绘制,我如何修复它

更新。这是相关的电话

调用对话框:

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代码:)它是通过
ctypes
工作的嵌入式Python。插件在主线程中运行;宿主应用程序进行同步调用,即等待被调用函数返回
self.template()
返回
DLGTEMPLATEEX
我动态准备的数据;我相信我这样做是正确的,因为对话框会显示,当我用Spy检查它时,所有的标志似乎都设置好了(除了还有一些标志)。我不使用实例句柄,因为我不从资源加载任何内容。我相信我正确包装了所有函数和常量,但我也可以发布定义
GetActiveWindow
(或
GetForegroundWindow
)返回指向应用程序主窗口的指针;这是一个MDI应用程序,它会重新绘制除MDI窗口的客户端区域以外的所有内容:


在这里,我将窗口移到所有可见窗口(工具栏、按钮等)上,唯一不重新绘制的部分是MDI文档的客户端区域。

您需要泵送消息队列以使绘制周期正常工作。似乎出现了一些泵送(您说一些控件重新绘制)

由于模态对话框运行它们自己的消息泵,我将大胆猜测,插件的主机在其消息泵中对消息进行了一些特殊处理,很可能是错误的,并且您的标准对话框消息泵的工作方式不同

我在猜测,并做出了巨大的飞跃,但我怀疑你的主机应用程序的消息循环不是标准的
TranslateMessage
/
DispatchMessage
形式。如果是这样的话,那么你真的被水淹没了


如果没有更多的细节,真的不可能有把握地说出任何事情。正如Hans所说,最小限度的复制将使问题更容易解决。

将显示这种行为的小复制项目发布到文件共享服务。您的父母WM_PAINT或WM_橡皮擦GND处理可能不正确。向我们展示代码。我不确定我是否能准备一个有效的代码片段;它是一个嵌入Python的DLL,代码也在Python中,WinAPI函数通过ctypes调用:)最重要的想法是有一个脚本化的对话框构造函数。当然,我可以在这里发布所有API调用。我也没有访问父代码的权限;正如我所说,这是一个插件。我可以访问另一个插件的代码,该插件也显示了一个对话框,但它似乎是相同的,只是它在关闭对话框时恢复了父级的焦点。最可能的问题是父级代码。我只是尝试将
NULL
用作
hWndParent
,不幸的是,这没什么区别。若你们的主机应用程序是FileMaker,我想你们会有大麻烦。这是计算机史上最糟糕的程序之一。我不相信他们有能力写一个正确的消息循环。只要在网上搜索filemake插件redraw,你就会发现其他人和你有同样的问题。我已经做出裁决,文件制作人有罪!是的,没错,有个家伙也有同样的问题()。他似乎没有把它修好:)但有些插件确实会以某种方式显示对话框,所以,我想,我必须问那些家伙他们是如何做到这一点的。@David,你认为有解决办法吗?如果有,可能是什么?我将尝试直接调用主窗口的窗口过程,但是我不知道这是否是最好的方法。