WPF WinForm Interop: обработка ярлыков в многоуровневом приложении WinForm - PullRequest
0 голосов
/ 01 июня 2019

У меня есть ситуация, когда мне нужно обработать некоторую комбинацию клавиш, и у меня есть следующая структура приложения с использованием ElementHost и WindowsFormsHost (эту структуру нельзя изменить)

Winform App --> (ElementHost) --> Wpf Control --> (WindowsFormsHost) --> WinForm Control

Есть несколько ярлыков, которые обрабатываются на уровне WinForm Control с помощью переопределения ProcessCmdKey(ref Message msg, Keys keyData).

Также есть глобальные сочетания клавиш, которые обрабатываются на уровне WinForm App с использованием переопределения ProcessCmdKey(ref Message msg, Keys keyData) (пример: F3 )

Задача

Когда WinForm Control находится в фокусе, нажатие F3 / любая клавиша вызывает только WinForm Control метод ProcessCmdKey при включении переходит к соответствующему событию нажатия клавиши управления. Событие препроцессора не достигает Wpf Control OnPreviewKeyDown или Winform App ProcessCmdKey. Поэтому Winform App не имеет возможности работать с ключом.

Другие наблюдения

  • Если Wpf Control находится в фокусе, нажатие любой клавиши вызывает следующие события
 Wpf Control's OnPreviewKeyDown() --> Winform App's ProcessCmdKey()
  • Если элемент управления WPF размещен в приложении WPF, события работают должным образом.
WinForm Control's ProcessCmdKey() -> WPF App Window's PreviewKeyDown() -> WpfControl's PreviewKeyDown()
  • Я пытался вызвать PreviewKeyDown событие элемента управления WindowsFormsHost из Winform Control метода ProcessCmdKey (). PreviewKeyDown срабатывает на слое WPF, но не вызывает ProcessCmdKey из Winform App

  • Я пытался использовать SendMessage для отправки сообщения в очередь сообщений Winform App с WinForm Control, но безуспешно.

Похожие проблемы

WinFormApp

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            ElementHost host = new ElementHost();
            host.Dock = DockStyle.Fill;
            host.Child = new WpfControl();
            this.Controls.Add(host);
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            return base.ProcessCmdKey(ref msg, keyData);
        }
    }  

WPFControl.xaml

<UserControl x:Class="App.WpfControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:local="clr-namespace:App"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="124*" />
            <ColumnDefinition Width="388*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="2*" />           
        </Grid.RowDefinitions>

        <Label Grid.Row="0" Grid.Column="0" Content="value1" Height="28" HorizontalAlignment="Left" Name="value1" VerticalAlignment="Top" />
        <TextBox Grid.Row="0" Grid.Column="1" Height="23" HorizontalAlignment="Left" Name="textBox1" VerticalAlignment="Top" Width="257" />

        <WindowsFormsHost Grid.Column="1" Grid.Row="2" Height="90" HorizontalAlignment="Left" Name="windowsFormsHost1" VerticalAlignment="Top" Width="307">
            <local:WinControl></local:WinControl>
        </WindowsFormsHost>

    </Grid>
</UserControl>

WpfControl.cs

public partial class WpfControl : UserControl
    {
        public WpfControl()
        {
            InitializeComponent();
        }

        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            base.OnPreviewKeyDown(e);
        }
    }

WinControl

 public partial class WinControl : UserControl
    {
        public WinControl()
        {
            InitializeComponent();
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            return base.ProcessCmdKey(ref msg, keyData);
        }
    }
partial class WinControl
    {       
        private System.ComponentModel.IContainer components = null;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code
        private void InitializeComponent()
        {
            this.HostedLabel = new System.Windows.Forms.Label();
            this.txtHost = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // HostedLabel
            // 
            this.HostedLabel.AutoSize = true;
            this.HostedLabel.Location = new System.Drawing.Point(15, 18);
            this.HostedLabel.Name = "HostedLabel";
            this.HostedLabel.Size = new System.Drawing.Size(67, 13);
            this.HostedLabel.TabIndex = 0;
            this.HostedLabel.Text = "HostedLabel";
            // 
            // txtHost
            // 
            this.txtHost.Location = new System.Drawing.Point(107, 18);
            this.txtHost.Name = "txtHost";
            this.txtHost.Size = new System.Drawing.Size(161, 20);
            this.txtHost.TabIndex = 1;
            // 
            // WinControl
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.Controls.Add(this.txtHost);
            this.Controls.Add(this.HostedLabel);
            this.Name = "WinControl";
            this.Size = new System.Drawing.Size(284, 50);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label HostedLabel;
        private System.Windows.Forms.TextBox txtHost;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...