在程序之间切换时出现重新喷漆问题

Repaint issues when switching between programs

本文关键字:新喷漆 问题 程序 之间      更新时间:2023-10-16

MyApp(.NET c#(由OtherApp(c++(触发。

当触发时,我的应用程序会接管整个屏幕,并为用户提供两个选项。一个选项退出MyApp并返回OtherApp主屏幕。第二个选项退出初始屏幕并显示另一个用于用户输入的屏幕——输入后,它退出并返回OtherApp。

有时OtherApp屏幕不会重新绘制(只能看到背景,而不能看到按钮(——我无法轻易复制这一点(当我这样做时,这似乎是一种侥幸(,但我在许多应用程序中都看到过。

有没有一种方法可以让MyApp强制重新绘制OtherApp的屏幕?

是什么原因造成的?

澄清-其他应用程序不是我们的。我们的客户使用OtherApp。MyApp由文件观察程序事件触发。当我们看到一个文件时,我们会处理它。如果这是我们要找的文件,我们会给用户两个选项。OtherApp不知道MyApp存在。

尝试获取OtherApp主窗口的hwnd并使整个事件无效:

[DllImport("user32.dll")]
static extern bool InvalidateRect(IntPtr hWnd, IntPtr lpRect, bool bErase);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
static void InvalidateOtherApp()
{
  IntPtr hWnd = FindWindow(null, "OtherApp's Main Window's Title");
  if (hWnd != IntPtr.Zero)
    InvalidateRect(hWnd, IntPtr.Zero, true);
}

在OtherApp中,添加相当于Application.DoEvents((的C++。它显然没有处理Windows消息。你可以这样做,取自微软Vterm示例程序:

void CMainFrame::DoEvents()
{
MSG msg;
// Process existing messages in the application's message queue.
// When the queue is empty, do clean up and return.
while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE) && !m_bCancel)
{
if (!AfxGetThread()->PumpMessage())
return;
}
}

由于OtherApp不是您的应用程序,您可以修改MyApp并使用Win32 SendMessage函数向OtherApp发送消息。要在C#中执行此操作,请查看带有SendMessage的C#Win32消息传递。您要发送的消息是WM_PAINT。该网站使用了不同的信息,但想法是相同的。您的代码将类似于以下内容:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
private static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, IntPtr lParam);
int WM_PAINT = 0xF;
SendMessage(hWnd, WM_PAINT, IntPtr.Zero, IntPtr.Zero);

这将向应用程序发送重新绘制消息。您需要为hWnd提供OtherApp的窗口句柄。要获取窗口句柄,需要调用System.Diagnostics.Process类来查找应用程序,并调用MainWindowHandle属性来获取句柄。