2011-04-26 89 views
2

当我点击一个ESRI COM工具栏项时,它产生一个窗口 - 它看起来像一个Winform。由于我没有直接产生窗口,所以我不能只对它做一个Object.Close()。我可以使用什么技术删除我的应用程序产生的窗口,但我没有对象引用?如何杀死一个窗口?

+2

我很好奇,什么ESRI的COM工具栏? – 2011-04-26 19:42:23

+0

@Gabriel我有一个WindowsFormHost的WPF应用程序,在这个WindowsFormHost是一个AxToolbarControl。它是一个ESRI.ArcGIS.Controls.AxToolbarControl它实现IToolbar - http://resources.esri.com/help/9.3/arcgisengine/java/api/arcobjects/com/esri/arcgis/controls/IToolbarControl.html – 0x4f3759df 2011-04-26 19:49:01

回答

3

我认为最简单的方法是使用p/invoke。

最简单的方法: 使用FindWindow函数()函数来获取和HWND为窗口(在C#中的IntPtr的,你可以使用NativeWindow类的包装 - http://msdn.microsoft.com/en-us/library/system.windows.forms.nativewindow.aspx#Y114

一旦你的HWND你可以使用CloseWindow()关闭窗口或向使用SendMessage(youHWND,WM_CLOSE,IntPtr.Zero,IntPtr.Zero)的窗口发送消息(WM_CLOSE = 0x0010)。

如果你的窗口有一个父窗口(你可以使用spy ++来查找),你可以使用FindWindowEx()以更精确的方式找到你的窗口。

希望它有帮助!

祝你好运!

p.s.我们可以使用GetWindowThreadProcessId()来确保窗口属于你的进程!为了确保你不会意外地杀死另一个应用程序的窗口(如果你在没有父窗口的情况下使用FindWindow或FindWindowEx),你可以使用GetWindowThreadProcessId()来确保窗口属于你的进程!

+0

我也会检查WinAPI代码包为.Net: http://archive.msdn.microsoft.com/WindowsAPICodePack/Release/ProjectReleases.aspx?ReleaseId=4906 它可能有你所需要的(从未使用过) – TCS 2011-04-26 19:52:44

2

假设你没有窗口句柄,你可以互操作,以Win32和执行以下操作:

在一些方法调用:

CallBackPtr callback = WindowEnumeration; 
EnumWindows(callback, IntPtr.Zero); 

然后,它会调用下面找到窗口,关闭它,只需将<标题>替换为描述性窗口的标题即可,以防止关闭不打算关闭的窗口。

private bool WindowEnumeration(IntPtr hwnd, IntPtr lParam) 
{ 
    _windowName.Clear(); 
    if (GetWindowText(hwnd, _windowName, _windowName.Capacity) != 0) 
    { 
     if (_windowName.ToString().Contains("<title>")) 
     { 
      PostMessage(window, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); 
     } 
    } 

    return true; 
} 

调用Win32的信息可以在MSDN中找到或pinvoke.net

+0

请不要不这样做。不管它们来自哪里,或者它们属于哪个,所有顶层窗口的字幕仅包含*标题将收到一条“WM_CLOSE”消息。想象一下,如果“标题”是常见的事情会发生什么,例如, 'Document'。考虑匹配整个标题,以及如果可能的话,也是窗口类。 – 2011-04-26 19:56:15

+0

@Hamidi - 我补充说明以提供一个描述性标题。我刚刚复制了一段我已经用于其他地方的代码,其中有一个描述性窗口标题。在我的情况下,我确实尝试了基于Spy ++来指定窗口类,但是由于某种原因它永远找不到窗口。 – 2011-04-26 20:09:42