Ejemplo n.º 1
0
        /// <summary>
        /// Processes Windows messages.
        /// </summary>
        /// <param name="m">The Windows Message to process. </param>
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
            case PI.WM_.NCLBUTTONDOWN:
            {
                // Perform a hit test to determine which area the mouse press is over at the moment
                uint result = PI.SendMessage(Handle, PI.WM_.NCHITTEST, IntPtr.Zero, m.LParam);

                // Only want to override the behaviour of moving the window via the caption bar
                if (result == PI.HT.CAPTION)
                {
                    // Extract screen position of the mouse from the message LPARAM
                    Point screenPos = new Point(PI.LOWORD(m.LParam),
                                                PI.HIWORD(m.LParam));

                    // Find the mouse offset relative to the top left of the window
                    Point offset = new Point(screenPos.X - Location.X, screenPos.Y - Location.Y);

                    // Do not intercept message if inside the max/close buttons
                    if (!HitTestMaxButton(offset) && !HitTestCloseButton(offset))
                    {
                        // Capture the mouse until the mouse us is received and gain focus so we look active
                        Capture = true;
                        Activate();

                        // Use event to notify the request to drag the window
                        OnWindowCaptionDragging(new ScreenAndOffsetEventArgs(screenPos, offset));

                        // Eat the message!
                        return;
                    }
                }
            }
            break;

            case PI.WM_.KEYDOWN:
                base.WndProc(ref m);
                FloatingMessages?.OnKEYDOWN(ref m);

                return;

            case PI.WM_.MOUSEMOVE:
                base.WndProc(ref m);
                FloatingMessages?.OnMOUSEMOVE();

                return;

            case PI.WM_.LBUTTONUP:
                base.WndProc(ref m);
                FloatingMessages?.OnLBUTTONUP();

                return;
            }

            base.WndProc(ref m);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Показать скрытое окно
 /// </summary>
 /// <param name="process">Процесс</param>
 /// <param name="windowHandle">Дескриптор окна</param>
 /// <param name="windowWmCommand">Команда для открытия окна</param>
 public static void ShowHiddenWindow(Process process,
                                     IntPtr windowHandle, int windowWmCommand)
 {
     if (PI.IsWindowVisible(windowHandle) == false)
     {
         PI.SendMessage(process.MainWindowHandle,
                        (uint)PI.WM.COMMAND, windowWmCommand, 0);
         return;
     }
 }
        /// <summary>
        /// A few keyboard messages need to be forwarded to the inner textbox of the
        /// KryptonNumericUpDown control so that the first character pressed appears in it.
        /// </summary>
        protected override bool ProcessKeyEventArgs(ref Message m)
        {
            TextBox textBox = Controls[0] as TextBox;

            if (textBox != null)
            {
                PI.SendMessage(textBox.Handle, m.Msg, m.WParam, m.LParam);
                return(true);
            }

            return(base.ProcessKeyEventArgs(ref m));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Поиск дескриптора окна
        /// </summary>
        /// <param name="currentProcess">Текущий процесс</param>
        /// <param name="windowName">Имя окна</param>
        /// <param name="wndWmCommand">WM-команда окна</param>
        /// <param name="dialogHandle">handle диалога</param>
        /// <param name="wndVisiblePtr">Дескриптор найденного окна</param>
        /// <returns>True - успешно, False - с ошибкой</returns>
        /// <param name="isSecondUse">Второй ли запуск функции (рекурсивный)
        /// </param>
        public static bool SearchWindowDescriptor(Process currentProcess,
                                                  string windowName, int wndWmCommand, ref IntPtr dialogHandle,
                                                  ref IntPtr wndVisiblePtr, bool isSecondUse = false)
        {
            // Поиск плавающего представления окна через функцию
            IntPtr res = PI.FindWindowByCaption(IntPtr.Zero, windowName);

            if (res != IntPtr.Zero)
            {
                var resList = PI.GetChildWindows(res);
                if (resList.Count > 0)
                {
                    dialogHandle  = resList[0];
                    wndVisiblePtr = dialogHandle;
                }
            }
            else
            {
                const int bufferSize   = 200;
                var       stringBuffer = new StringBuilder(bufferSize);

                // Поиск плавающего представления окна по всем окнам системы
                SearchFloatWindow(stringBuffer, windowName, ref dialogHandle,
                                  ref wndVisiblePtr);

                if (dialogHandle == IntPtr.Zero)
                {
                    // Поиск закрепленного представления окна
                    SearchStaticWindow(currentProcess, stringBuffer, windowName,
                                       ref dialogHandle, ref wndVisiblePtr);
                }

                if (dialogHandle == IntPtr.Zero)
                {
                    PI.SendMessage(currentProcess.MainWindowHandle,
                                   (uint)PI.WM.COMMAND, wndWmCommand, 0);

                    if (isSecondUse == true && dialogHandle == IntPtr.Zero)
                    {
                        MessageBox.Show("Не удалось найти окно!");
                        return(false);
                    }

                    // Повторный поиск
                    SearchWindowDescriptor(currentProcess, windowName,
                                           wndWmCommand, ref dialogHandle, ref wndVisiblePtr,
                                           true);
                }
            }

            return(true);
        }
Ejemplo n.º 5
0
        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;
        }
        /// <summary>
        /// Discover the preferred size of the element.
        /// </summary>
        /// <param name="context">Layout context.</param>
        public override Size GetPreferredSize(ViewLayoutContext context)
        {
            Size preferredSize = Size.Empty;

            // We need an owning form to perform calculations
            if (CompOwnerForm != null)
            {
                // We only have size if custom chrome is being used with composition
                if (CompOwnerForm.ApplyCustomChrome && CompOwnerForm.ApplyComposition)
                {
                    try
                    {
                        // Create structure that will be populated by call to WM_GETTITLEBARINFOEX
                        PI.TITLEBARINFOEX tbi = new PI.TITLEBARINFOEX();
                        tbi.cbSize = (uint)Marshal.SizeOf(tbi);

                        // Ask the window for the title bar information
                        PI.SendMessage(CompOwnerForm.Handle, PI.WM_.GETTITLEBARINFOEX, IntPtr.Zero, ref tbi);

                        // Find width of the button rectangle
                        int closeWidth = tbi.rcCloseButton.right - tbi.rcCloseButton.left;
                        int helpWidth  = tbi.rcHelpButton.right - tbi.rcHelpButton.left;
                        int minWidth   = tbi.rcMinimizeButton.right - tbi.rcMinimizeButton.left;
                        int maxWidth   = tbi.rcMaximizeButton.right - tbi.rcMaximizeButton.left;

                        int clientWidth       = CompOwnerForm.ClientSize.Width;
                        int clientScreenRight = CompOwnerForm.RectangleToScreen(CompOwnerForm.ClientRectangle).Right;
                        int leftMost          = clientScreenRight;

                        // Find the left most button edge (start with right side of client area)
                        if ((closeWidth > 0) && (closeWidth < clientWidth))
                        {
                            leftMost = Math.Min(leftMost, tbi.rcCloseButton.left);
                        }

                        if ((helpWidth > 0) && (helpWidth < clientWidth))
                        {
                            leftMost = Math.Min(leftMost, tbi.rcHelpButton.left);
                        }

                        if ((minWidth > 0) && (minWidth < clientWidth))
                        {
                            leftMost = Math.Min(leftMost, tbi.rcMinimizeButton.left);
                        }

                        if ((maxWidth > 0) && (maxWidth < clientWidth))
                        {
                            leftMost = Math.Min(leftMost, tbi.rcMaximizeButton.left);
                        }

                        // Our width is the distance between the left most button edge and the right
                        // side of the client area (this space the buttons are taking up). Plus a small
                        // extra gap between the first button and the caption elements to its left.
                        _width = (clientScreenRight - leftMost) + SPACING_GAP;

                        preferredSize.Width = _width;
                    }
                    catch (ObjectDisposedException)
                    {
                        // Asking for the WM_GETTITLEBARINFOEX can cause exception if the form level
                        // Icon has already been disposed. This happens in rare circumstances.
                    }
                }
            }

            return(preferredSize);
        }