Как отключить окно?

#c# #windows #winforms #com

#c# #Windows #winforms #com

Вопрос:

Когда я нажимаю на элемент панели инструментов ESRI COM, он создает окно — оно выглядит как Winform. Поскольку я не создавал окно напрямую, я не могу просто создать объект.Close() для него. Какой метод я могу использовать, чтобы удалить окно, созданное моим приложением, но на которое у меня нет ссылки на объект?

Комментарии:

1. мне любопытно, что это за панель инструментов esri com?

2. @Gabriel У меня есть приложение WPF, у которого есть WindowsFormHost, в этом WindowsFormHost является AxToolbarControl. Это ESRI. ArcGIS. Элементы управления. AxToolbarControl реализует IToolbar — resources.esri.com/help/9.3/arcgisengine/java/api/arcobjects /…

Ответ №1:

Я думаю, что самый простой способ — это использовать 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.

Просто чтобы быть ДЕЙСТВИТЕЛЬНО уверенным, что вы случайно не убиваете окно другого приложения неожиданно (если вы используете FindWindow или FindWindowEx без родительского элемента), вы можете использовать GetWindowThreadProcessId(), чтобы убедиться, что окно принадлежит вашему процессу!

Комментарии:

1. Я бы также проверил пакет кода WinAPI для .Net: archive.msdn.microsoft.com/WindowsAPICodePack/Release/… Возможно, в нем есть то, что вам нужно (никогда не использовал его)

Ответ №2:

Предполагая, что у вас нет дескриптора окна, вы могли бы взаимодействовать с Win32 и выполнить следующее:

При вызове какого-либо метода:

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

Затем он вызовет следующее, чтобы найти окно и закрыть его, просто замените <title> на максимально описательный заголовок для окна, чтобы предотвратить закрытие окон, которые не предназначались для закрытия.

 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

Комментарии:

1.Пожалуйста, не делайте этого. Все окна верхнего уровня, заголовки которых просто содержат title , получат WM_CLOSE сообщение, независимо от того, откуда они пришли или кому принадлежат. Представьте, что произошло бы, если бы title было что-то общее, например, Document . Рассмотрите возможность сопоставления всего заголовка, а также класса window, если это вообще возможно.

2. @Hamidi — Я добавил уточнение, чтобы предоставить описательный заголовок. Я только что скопировал фрагмент кода, который я уже использовал для чего-то другого, где у меня есть описательный заголовок окна. В моем случае я также пытался указать класс window на основе Spy , но тогда по какой-то причине он никогда не найдет окно.