Win32:模态对话框在父/所有者的客户区中留下痕迹 [英] Win32: modal dialog leaves a trail in the client area of parent/owner

查看:288
本文介绍了Win32:模态对话框在父/所有者的客户区中留下痕迹的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我正在使用和DialogBoxIndirectParam ; hWnd 是应用程序的顶部窗口,我即时构建的模板和对话框标志是 WS_POPUP | WS_CAPTION | DS_MODALFRAME | DS_SETFONT | WS_SYSMENU ,加上函数本身设置一些标志,例如 WS_CLIPSIBLINGS 。对话框类是标准的(CS + DBLCLKS,CS_SAVEBITS)对话框过程非常基本,只处理 WM_CLOSE 消息。



我尝试过Google,但没有找到任何直接相关的东西。我试图将我的对话框类与同一个应用程序的其他对话框进行比较,并检查了消息日志,但我没有看到任何重大的差异。



为什么不父/老板重画,如何解决?



更新。以下是相关电话。



调用对话框:

 类对话框(对象):
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);
返回1
返回0

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





这里我将窗口移动到所有可视窗口(工具栏,按钮等)和只有不重绘的部分是MDI文档的客户区。

解决方案

您需要将消息队列抽成使油漆循环工作。似乎有一些泵送发生(你说一些控制重新绘制)。



由于模态对话框运行自己的消息泵,我要采取一个野蛮的猜测,您的插件的主机在其消息泵中有一些特殊的消息消息可能是错误的,并且您的标准对话框消息泵做的不同。



我猜测和大量的信仰,但我怀疑你的主机应用程序的消息循环不是标准的 TranslateMessage / DispatchMessage 表单。如果是这样,那么你真的很沮丧。



没有更多的细节,真的不可能有任何确定的话。正如汉斯所说,最小的复制将使问题很容易解决。


I'm writing a plug-in for an app; the plug-in is to display a modal dialog. It displays just fine, but when I move it, it leaves a trail on the screen, i.e. the window below doesn't redraw. Some parts of it do redraw (all standard Windows controls, e.g. toolbar or scrollbar), but the rest of the client area does not.

I'm using DialogBoxIndirectParam; the hWnd is the top window of the app, the template I construct on the fly and the dialog flags are WS_POPUP | WS_CAPTION | DS_MODALFRAME | DS_SETFONT | WS_SYSMENU, plus the function sets some flags itself, e.g. WS_CLIPSIBLINGS. The dialog class is standard (CS+DBLCLKS,CS_SAVEBITS) The dialog procedure is very basic, it only handles the WM_CLOSE message at the moment.

I tried Google but didn't manage find anything directly relevant. I tried to compare my dialog class with other dialogs of the same app and also checked the messages logs, but I didn't see any drastic differences.

Why doesn't the parent/owner redraw and how do I fix it?

Update. Here's the relevant calls.

Calling the 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))

Window procedure:

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

This is Python code :) it's embedded Python working via ctypes. The plug-in runs in the main thread; the host application makes a synchronous call, i.e it waits for the called function to return. self.template() returns DLGTEMPLATEEX data I prepare on the fly; I believe I do this correctly, because the dialog displays and when I check it with Spy all flags seems to be set (except that there's a few more). I don't use the instance handle, because I don't load anything from resources. I believe I correctly wrapped all functions and constants, but I can post the definitions too. GetActiveWindow (or GetForegroundWindow) returns the pointer to the app's main window; it's a MDI app and it repaints everything except the client area of a MDI window:

Here I moved the window over all the visible windows (toolbars, buttons, etc.) and the only part that doesn't repaint is the client area of the MDI doc.

解决方案

You need the message queue to be pumped to make the paint cycle works. It seems that there is some pumping occurring (you say that some controls re-draw).

Since modal dialogs run their own message pump, I'm going to take a wild guess that the host for your plugin has some special treatment of messages, quite possibly erroneous, in its message pump and that your standard dialog box message pump does things differently.

I'm guessing and making large leaps of faith, but I suspect your host app's message loop isn't of the standard TranslateMessage / DispatchMessage form. If so then you are truly hosed.

Without more details it's really impossible to say anything with much certainty. As Hans says, a minimal reproduction would make the problem easy to solve.

这篇关于Win32:模态对话框在父/所有者的客户区中留下痕迹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆