/// <summary> /// Поиск плавающего представления окна по всем окнам /// </summary> /// <param name="stringBuffer">Буфер</param> /// <param name="windowName">Имя окна</param> /// <param name="dialogHandle">Дескриптор диалога, выходное значение /// </param> /// <param name="res">Найденный дескриптор для сверки</param> /// <param name="wndVisiblePtr">Дескриптор окна</param> private static void SearchFloatWindow(StringBuilder stringBuffer, string windowName, ref IntPtr dialogHandle, ref IntPtr wndVisiblePtr) { List <IntPtr> mainWindowChilds = PI.GetChildWindows(PI.GetDesktopWindow()); foreach (IntPtr mainWindowChild in mainWindowChilds) { PI.GetWindowText(mainWindowChild, stringBuffer, stringBuffer.Capacity); if (stringBuffer.ToString().Contains(windowName) == false && stringBuffer.ToString().Contains("EPLAN") == false) { List <IntPtr> windowChilds = PI.GetChildWindows(mainWindowChild); foreach (IntPtr windowChild in windowChilds) { PI.GetWindowText(windowChild, stringBuffer, stringBuffer.Capacity); if (stringBuffer.ToString().Contains(windowName) == true) { // Если нашел в потомке название, беру родительское окно и работаю с ним var resList = PI.GetChildWindows(mainWindowChild); if (resList.Count > 0) { dialogHandle = resList[0]; wndVisiblePtr = dialogHandle; break; } } } } } }
/// <summary> /// Поиск закрепленного представления окна в процессе. /// </summary> /// <param name="currentProcess">Текущий процесс</param> /// <param name="stringBuffer">Буфер</param> /// <param name="windowName">Имя окна</param> /// <param name="dialogHandle">Handle диалога выходной</param> /// <param name="wndVisiblePtr">Найденный дескриптор окна</param> private static void SearchStaticWindow(Process currentProcess, StringBuilder stringBuffer, string windowName, ref IntPtr dialogHandle, ref IntPtr wndVisiblePtr) { List <IntPtr> resW = PI.GetChildWindows(currentProcess.MainWindowHandle); foreach (IntPtr panel in resW) { PI.GetWindowText(panel, stringBuffer, stringBuffer.Capacity); if (stringBuffer.ToString().Contains(windowName) == true) { if (PI.IsWindowVisible(panel) == true) { var resList = PI.GetChildWindows(panel); if (resList.Count > 0) { dialogHandle = resList[0]; wndVisiblePtr = dialogHandle; break; } } } } }
public static bool modeIsShown = false; // Показано ли окно. /// <summary> /// Инициализация формы данными для редактирования. /// /// Так как данная форма отображается как внутреннее окно, то алгоритм /// следующий: /// 1 Поиск окна "Основные данные изделия" (меню Сервисные программы -> /// Изделие -> Навигатор основных данных изделий). /// 1.1 Поиск плавающего представления: через FindWindowByCaption, /// потом для поиска панели и диалога DlgItemId (0xE81F - базовая панель, /// 0x32С8 - диалог). Если окно найдено, то переходим к 4, иначе к 1.1.1. /// 1.1.1 Поиск плавающего представления: иногда не отображается заголовок /// из-за чего невозможно сразу определить окно, тогда проверяются потомки окон, /// которые могут содержать заголовок родительского окна. Если не найдены заголовки, /// то переходим к 1.2 (значит плавающего представления нет). /// 1.2 Поиск закрепленного представления: через GetDlgItem для всех дочерних /// окон (GetChildWindows) приложения Eplan по DlgItemId (0x32C8 - диалог). /// Если окно найдено, то переходим к 4, иначе к 2. /// 2 Симулируем нажатие пункта меню (Сервисные программы -> /// Изделие -> Навигатор основных данных изделий - 35357) /// для его отображения. /// 3 Повторяем поиск окна (1.1, 1.1.1 и 1.2). Если окно не найдено выводим /// сообщение об ошибке, завершаем редактирование, иначе к 4. /// 4 Скрываем панель с элементами управления Eplan'а /// (GetDlgItem, 0x3E6 - родительская панель, ShowWindow). /// 5. Переносим на найденное окно свои элементы (SetParent) и подгоняем /// из размеры и позицию. /// 6. Устанавливаем свой хук для найденного окна (для изменения размеров /// своих элементов, сохранения изменений при закрытии и отключения хука). /// </summary> public void ShowDlg() { System.Diagnostics.Process oCurrent = System.Diagnostics.Process.GetCurrentProcess(); const int wndWmCommand = 35093; // Идентификатор команды вызова окна "Штекеры" if (modeIsShown == true) { if (PI.IsWindowVisible(wndModeVisibilePtr) == false) { PI.SendMessage(oCurrent.MainWindowHandle, (uint)PI.WM.COMMAND, wndWmCommand, 0); return; } return; } string windowName = "Штекеры"; IntPtr res = PI.FindWindowByCaption( IntPtr.Zero, windowName); //1.1 if (res != IntPtr.Zero) { var resList = PI.GetChildWindows(res); if (resList.Count > 0) { wndHandle = PI.GetParent(resList[0]); dialogHandle = resList[0]; wndModeVisibilePtr = dialogHandle; // Сохраняем дескриптор окна. } } else { StringBuilder stringBuffer = new StringBuilder(200); //1.1.1 List <IntPtr> mainWindowChilds = PI.GetChildWindows(PI.GetDesktopWindow()); foreach (IntPtr mainWindowChild in mainWindowChilds) { PI.GetWindowText(mainWindowChild, stringBuffer, stringBuffer.Capacity); if (stringBuffer.ToString().Contains(windowName) == false && stringBuffer.ToString().Contains("EPLAN") == false) { List <IntPtr> windowChilds = PI.GetChildWindows(mainWindowChild); foreach (IntPtr windowChild in windowChilds) { PI.GetWindowText(windowChild, stringBuffer, stringBuffer.Capacity); if (stringBuffer.ToString().Contains(windowName) == true) { if (PI.IsWindowVisible(windowChild) == true) { // Если нашел в потомке название, беру родительское окно и работаю с ним var resList = PI.GetChildWindows(mainWindowChild); if (resList.Count > 0) { dialogHandle = resList[0]; res = dialogHandle; wndModeVisibilePtr = dialogHandle; // Сохраняем дескриптор окна. break; } } } } } } List <IntPtr> resW = PI.GetChildWindows(oCurrent.MainWindowHandle); //1.2 foreach (IntPtr panel in resW) { PI.GetWindowText(panel, stringBuffer, stringBuffer.Capacity); if (stringBuffer.ToString().Contains(windowName) == true) { if (PI.IsWindowVisible(panel) == true) { var resList = PI.GetChildWindows(panel); if (resList.Count > 0) { dialogHandle = resList[0]; res = dialogHandle; wndModeVisibilePtr = dialogHandle; // Сохраняем дескриптор окна. break; } } } } if (res == IntPtr.Zero) { PI.SendMessage(oCurrent.MainWindowHandle, (uint)PI.WM.COMMAND, wndWmCommand, 0); //2 res = PI.FindWindowByCaption( IntPtr.Zero, windowName); //3 if (res != IntPtr.Zero) { var resList = PI.GetChildWindows(res); if (resList.Count > 0) { dialogHandle = resList[0]; wndHandle = PI.GetParent(resList[0]); wndModeVisibilePtr = dialogHandle; // Сохраняем дескриптор окна. } } else { mainWindowChilds = PI.GetChildWindows(PI.GetDesktopWindow()); foreach (IntPtr mainWindowChild in mainWindowChilds) { PI.GetWindowText(mainWindowChild, stringBuffer, stringBuffer.Capacity); if (stringBuffer.ToString().Contains(windowName) == false && stringBuffer.ToString().Contains("EPLAN") == false) { List <IntPtr> windowChilds = PI.GetChildWindows(mainWindowChild); foreach (IntPtr windowChild in windowChilds) { PI.GetWindowText(windowChild, stringBuffer, stringBuffer.Capacity); if (stringBuffer.ToString().Contains(windowName) == true) { // Если нашел в потомке название, беру родительское окно и работаю с ним var resList = PI.GetChildWindows(mainWindowChild); if (resList.Count > 0) { dialogHandle = resList[0]; wndModeVisibilePtr = dialogHandle; // Сохраняем дескриптор окна. break; } } } } } resW = PI.GetChildWindows(oCurrent.MainWindowHandle); foreach (IntPtr panel in resW) { PI.GetWindowText(panel, stringBuffer, stringBuffer.Capacity); if (stringBuffer.ToString().Contains(windowName) == true) { var resList = PI.GetChildWindows(panel); if (resList.Count > 0) { dialogHandle = resList[0]; wndModeVisibilePtr = dialogHandle; // Сохраняем дескриптор окна. break; } } } if (dialogHandle == IntPtr.Zero) { MessageBox.Show("Не удалось найти окно!"); return; } } } } var panelList = PI.GetChildWindows(dialogHandle); //4 if (panelList.Count > 0) { panelPtr = panelList[0]; } if (panelPtr == IntPtr.Zero) { MessageBox.Show("Не удалось скрыть окно!"); return; } PI.ShowWindow(panelPtr, 0); this.Controls.Clear(); modesTreeViewAdv.Show(); PI.SetParent(modesTreeViewAdv.Handle, dialogHandle); //5 PI.SetParent(toolStrip.Handle, dialogHandle); IntPtr dialogPtr = PI.GetParent(modesTreeViewAdv.Handle); PI.RECT rctDialog; PI.RECT rctPanel; PI.GetWindowRect(dialogPtr, out rctDialog); PI.GetWindowRect(panelPtr, out rctPanel); int w = rctDialog.Right - rctDialog.Left; int h = rctDialog.Bottom - rctDialog.Top; toolStrip.Location = new Point(0, 0); modesTreeViewAdv.Location = new Point(0, 0 + toolStrip.Height); toolStrip.Width = w; modesTreeViewAdv.Width = w; modesTreeViewAdv.Height = h - toolStrip.Height; uint pid = PI.GetWindowThreadProcessId(dialogHandle, IntPtr.Zero); //6 dialogHookPtr = PI.SetWindowsHookEx(PI.HookType.WH_CALLWNDPROC, dialogCallbackDelegate, IntPtr.Zero, pid); PI.SetWindowText(dialogHandle, caption); PI.SetWindowText(wndHandle, caption); modeIsShown = true; }