/// <summary> /// Изменить UI размер /// </summary> private void ChangeUISize() { IntPtr dialogPtr = PI.GetParent(devicesTreeViewAdv.Handle); PI.RECT rctDialog; PI.GetWindowRect(dialogPtr, out rctDialog); int w = rctDialog.Right - rctDialog.Left; int h = rctDialog.Bottom - rctDialog.Top; toolStrip.Location = new Point(0, 0); devicesTreeViewAdv.Location = new Point(0, toolStrip.Height); toolStrip.Width = w; devicesTreeViewAdv.Width = w; devicesTreeViewAdv.Height = h - toolStrip.Height; }
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; }
private IntPtr DlgWndHookCallbackFunction(int code, IntPtr wParam, IntPtr lParam) { PI.CWPSTRUCT msg = (PI.CWPSTRUCT)System.Runtime.InteropServices.Marshal.PtrToStructure(lParam, typeof(PI.CWPSTRUCT)); if (msg.hwnd == panelPtr) { switch (msg.message) { case (int)PI.WM.MOVE: case (int)PI.WM.SIZE: 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; break; } return(PI.CallNextHookEx(IntPtr.Zero, code, wParam, lParam)); } if (msg.hwnd == dialogHandle) { switch (msg.message) { case (int)PI.WM.GETTEXTLENGTH: return((IntPtr)newCapt.Length); case (int)PI.WM.SETTEXT: return(IntPtr.Zero); case (int)PI.WM.WINDOWPOSCHANGED: PI.WINDOWPOS p = new PI.WINDOWPOS(); p = (PI.WINDOWPOS) System.Runtime.InteropServices.Marshal.PtrToStructure( lParam, typeof(PI.WINDOWPOS)); break; case (int)PI.WM.DESTROY: PI.UnhookWindowsHookEx(dialogHookPtr); dialogHookPtr = IntPtr.Zero; dialogHandle = IntPtr.Zero; PI.SetParent(modesTreeViewAdv.Handle, this.Handle); PI.SetParent(toolStrip.Handle, this.Handle); this.Controls.Add(modesTreeViewAdv); this.Controls.Add(toolStrip); modesTreeViewAdv.Hide(); System.Threading.Thread.Sleep(1); modeIsShown = false; break; case (int)PI.WM.GETTEXT: System.Runtime.InteropServices.Marshal.Copy( newCapt, 0, lParam, newCapt.Length); return((IntPtr)newCapt.Length); } } return(PI.CallNextHookEx(IntPtr.Zero, code, wParam, lParam)); }