c# - 如何将我的表单粘贴到第三方应用程序的窗口?

标签 c# winforms

我正在尝试将我的表单粘贴到另一个应用程序的窗口(假设是 Microsoft Outlook)。当我移动 Outlook 窗口时,我的表单仍应停留在其右侧。

目前,我正在 while(true) 循环(使用 sleep())中监视 Outlook 的位置,并根据它调整表单的位置。

这里有两个问题:

  • 如果 sleep() 持续时间太短,则检查 Outlook 的位置并经常调整表单会消耗大量性能。
  • 如果 sleep() 持续时间太长,我的表单适应 Outlook 的速度就会太慢(滞后)。

没有一个原生的解决方案吗?

最佳答案

你必须 Hook 进程并监听事件

这应该给你一个很好的起点

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private const uint WINEVENT_OUTOFCONTEXT = 0x0000;
        private const uint EVENT_OBJECT_LOCATIONCHANGE = 0x800B;

        private const uint EVENT_SYSTEM_MOVESIZESTART = 0x000A;
        private const uint EVENT_SYSTEM_MOVESIZEEND = 0x000B;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Width = 100;
            this.Height = 100;
            this.TopMost = true;
            int processId = Process.GetProcessesByName("OUTLOOK")[0].Id;

            //this will also be triggered by mouse moving over the process windows
            //NativeMethods.SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE, IntPtr.Zero, WinEventProc, (uint)processId, (uint)0, WINEVENT_OUTOFCONTEXT);

            NativeMethods.SetWinEventHook(EVENT_SYSTEM_MOVESIZESTART, EVENT_SYSTEM_MOVESIZEEND, IntPtr.Zero, WinEventProc, (uint)processId, (uint)0, WINEVENT_OUTOFCONTEXT);
        }

        private void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
        {
            Rect move = new Rect();

            if (eventType == EVENT_SYSTEM_MOVESIZESTART)
            {
                NativeMethods.GetWindowRect(hwnd, ref move);

                Debug.WriteLine("EVENT_SYSTEM_MOVESIZESTART");
            }
            else if (eventType == EVENT_SYSTEM_MOVESIZEEND)
            {
                NativeMethods.GetWindowRect(hwnd, ref move);

                Debug.WriteLine("EVENT_SYSTEM_MOVESIZEEND");
            }

            this.Left = move.Left;
            this.Top = move.Top;
        }
    }

    public struct Rect
    {
        public int Left { get; set; }
        public int Top { get; set; }
        public int Right { get; set; }
        public int Bottom { get; set; }
    }

    static class NativeMethods
    {
        [DllImport("user32.dll")]
        public static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);

        public delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);

        [DllImport("user32.dll")]
        public static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle);
    }
}

关于c# - 如何将我的表单粘贴到第三方应用程序的窗口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31832433/

相关文章:

c# - 根据绑定(bind)值与 DataTrigger 共享样式

c# - 如何阻止 Visual Studio 在我的 UserControl 中生成 Setter 调用?

c# - 在运行时更改 Windows 窗体窗体的宽度

mysql - 在 SQL 数据库中保存大型文本数据(保存在字符串生成器中)的最佳方法?

c# - 在C#中,如何求点到圆心的距离?

c# - 检查 Windows keystore 中是否安装了最终用户证书?

c# - 升级到 Entity Framework 4.3.1 后未处理的异常

c# - 批处理文件启动应用程序并传递多个参数将空格切换为á

c# - 如何通过按键盘上的特定键来激活按钮?

c# - 单击确定按钮时防止 ShowDialog() 返回