gpt4 book ai didi

c# - 如何在 Windows 中嵌入 tabtip.exe

转载 作者:太空狗 更新时间:2023-10-29 19:46:36 31 4
gpt4 key购买 nike

我正在尝试将 osk 嵌入到 wpf 窗口或用户控件中,我找到了下面的代码,它适用于记事本,但适用于 tabtip.exe,是说它没有图形界面? ?

WaitForInputIdle 失败。这可能是因为该进程没有图形界面。

我试着让它休眠一段时间而不是调用 waitForInputIdle 方法,但它抛出了另一个异常:

进程已退出,因此请求的信息不可用。

但在我的任务管理器中,我仍然可以看到 TabTip.exe 正在运行。

namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private System.Windows.Forms.Panel _panel;
private Process _process;

public MainWindow()
{
InitializeComponent();
_panel = new System.Windows.Forms.Panel();
windowsFormsHost1.Child = _panel;
}

[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32")]
private static extern IntPtr SetParent(IntPtr hWnd, IntPtr hWndParent);

[DllImport("user32")]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);

private const int SWP_NOZORDER = 0x0004;
private const int SWP_NOACTIVATE = 0x0010;
private const int GWL_STYLE = -16;
private const int WS_CAPTION = 0x00C00000;
private const int WS_THICKFRAME = 0x00040000;


protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
base.OnClosing(e);
if (_process != null)
{
_process.Refresh();
_process.Close();
}
}

private void ResizeEmbeddedApp()
{
if (_process == null)
return;

SetWindowPos(_process.MainWindowHandle, IntPtr.Zero, 0, 0, (int)_panel.ClientSize.Width, (int)_panel.ClientSize.Height, SWP_NOZORDER | SWP_NOACTIVATE);
}

protected override Size MeasureOverride(Size availableSize)
{
Size size = base.MeasureOverride(availableSize);
ResizeEmbeddedApp();
return size;
}

private void button1_Click_1(object sender, RoutedEventArgs e)
{
button1.Visibility = Visibility.Hidden;
ProcessStartInfo psi = new ProcessStartInfo("C:\\Program Files\\Common Files\\microsoft shared\\ink\\TabTip.exe");
_process = Process.Start(psi);

Thread.Sleep(500);
//_process.WaitForInputIdle();

SetParent(_process.MainWindowHandle, _panel.Handle);

// remove control box
int style = GetWindowLong(_process.MainWindowHandle, GWL_STYLE);
style = style & ~WS_CAPTION & ~WS_THICKFRAME;
SetWindowLong(_process.MainWindowHandle, GWL_STYLE, style);

// resize embedded application & refresh
ResizeEmbeddedApp();
}

}
}

编辑:受 rene 评论的启发,我尝试如下获取窗口 ptr 并使用 spy++ 验证 FindWindow 给出的地址是否指向正确的窗口,但它仍然没有移动:

 IntPtr KeyboardWnd = FindWindow("IPTip_Main_Window", null);


int style = GetWindowLong(KeyboardWnd, GWL_STYLE);
style = style & ~WS_CAPTION & ~WS_THICKFRAME;
SetWindowLong(KeyboardWnd, GWL_STYLE, style);
SetWindowPos(KeyboardWnd, IntPtr.Zero, 0, 0, (int)_panel.ClientSize.Width, (int)_panel.ClientSize.Height, SWP_NOZORDER | SWP_NOACTIVATE);

编辑 2:我的第一个想法是无法调整选项卡提示的大小,但后来我注意到当我尝试在两个不同的屏幕上移动窗口时出现的行为,它会调整大小以适应屏幕大小,所以我'我确定必须有一种调整大小的方法,所以我开始使用 spy++(x64) 来检查:

window log

编辑 3:在修改了 user32 api 但没有任何进展后,我尝试使用内存扫描器扫描 tabtip 的 x 和 y 位置并更改它,但是,在触发重绘之前它不会刷新,我想知道沿着这条路走下去的可行性。

最佳答案

您可以尝试在 STA 线程中运行您的句柄代码吗?我在 native 窗口中遇到了类似的问题,我已使用 STA 线程解决了这个问题。

var thread = new Thread(() => {
// Your code here
});
thread.TrySetApartmentState(ApartmentState.STA);
thread.Start();

关于c# - 如何在 Windows 中嵌入 tabtip.exe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38891713/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com