Skip to content

Пример показа любого окна внутри iikoFront #10

@ierof

Description

@ierof
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;

namespace Resto.Front.Api.Sample
{
    internal sealed class WindowTester : IDisposable
    {
        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
        [DllImport("user32.dll")]
        private static extern bool GetWindowRect(IntPtr hWnd, out Rectangle rectangle);
        [StructLayout(LayoutKind.Sequential)]
        private struct Rectangle
        {
            public readonly int Left;
            public readonly int Top;
            public readonly int Right;
            public readonly int Bottom;
        }

        private const string AppProcessName = "iikoFront.Net";
        private Window window;

        private void EntryPoint()
        {
            var button = new Button { Content = "Close" };
            button.Click += (s, e) => Close();
            window = new Window
            {
                // ваши произвольные свойства
                // вы можете вообще создать своё окно
                Content = button,
                // далее обязательные для функционирования свойства, 
                // при реализации своего окна их нужно перенести
                Topmost = true,
                ResizeMode = ResizeMode.NoResize,
                ShowInTaskbar = false,
                WindowStartupLocation = WindowStartupLocation.Manual,
                HorizontalContentAlignment = HorizontalAlignment.Center,
                VerticalContentAlignment = VerticalAlignment.Center,
                WindowStyle = WindowStyle.None,
                ShowActivated = true,
                Top = 0,
                Left = 0,
            };

            window.Loaded += (sender, args) =>
            {
                var runningProcesses = Process.GetProcessesByName(AppProcessName).SingleOrDefault();
                if (runningProcesses == null) 
                    return;
                var frontHwnd = runningProcesses.MainWindowHandle;
                GetWindowRect(frontHwnd, out var rectangle);
                window.Height = rectangle.Bottom - rectangle.Top;
                window.Width = rectangle.Right - rectangle.Left;
                var currentHwnd = new WindowInteropHelper(window).Handle;
                SetParent(currentHwnd, frontHwnd);
            };
     
            window.ShowDialog();
        }

        private void Close()
        {
            window.Close();
            Dispose();
        }

        public void Dispose()
        {
            window.Dispatcher.InvokeShutdown();
            window.Dispatcher.Thread.Join();
        }

        public void ShowDialog()
        {
            var windowThread = new Thread(EntryPoint);
            windowThread.SetApartmentState(ApartmentState.STA);
            windowThread.Start();
        }
    }
}

Вызвать такой код можно в любой момент.

Для тестов я вызываю его как:
PluginContext.Operations.AddButtonToPluginsMenu("Test window", (manager, printer) => new WindowTester().ShowDialog());
Для версий V5 и V6: PluginContext.Integration.AddButton("Test window", (manager, printer, progressBar) => new WindowTester().ShowDialog());

Результат:
test_wnd

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions