如何点击WinForm,而不关注焦点?

时间:2015-03-12 20:20:25

标签: c# winforms

我找不到任何相关信息......

基本上我在C#中有一个TopMost WinForm,它是另一个应用程序的叠加层。

叠加层有我需要按下的按钮,而不会从其他应用程序中窃取焦点。

这是可能的,因为我无法找到任何相关信息。

2 个答案:

答案 0 :(得分:2)

您可以存储鼠标位置:

Point point = Cursor.Position;

然后使用没有控件的区域将焦点更改回DirectX9窗口,

再次点击之前将光标移回原位置?这可能有用。

唯一的问题是该按钮仍然存在,所以你需要一些方法让它点击窗口而不是按钮。

e.g。

Point p = Cursor.Position;
Cursor.Position = new point(x,y);
mouse(leftClick);
Cursor.Position = p;
mouse(leftClick);

mouse(leftclick)方法为here

另一种方法是单独跟踪光标位置,然后每次点击,检查点击是否在任何控件内,如果是,则运行该方法;

(请在评论中告诉我是否有办法更有效地做到这一点,因为知道实际上非常有用)

答案 1 :(得分:0)

这是一个适合我的解决方案:

它通过标题或部分标识目标程序,并在每次Button点击后再次将目标设置为前景窗口。

我可以输入记事本,点击Button然后输入..

首先进行Form点击。

您可能想要做更多样式,可能最大化,删除控制/最小/最大框和标题,甚至抓住目标的位置和大小,并覆盖目标窗口。通过这种方式,您可以对目标制作完全不显眼的装饰。

(我之所以这样做是因为目标没有正确处理触摸屏;所以我在其非触控失效控件的区域做了一个带孔的覆盖层。没有人能注意到覆盖层在那里!)

我将一些状态信息写入输出控制台..

您也可以使用MainWindowTitle来识别目标,而不是ProcessName。您还可以合并代码以在发生错误后重新建立流程,例如用户关闭并重新启动目标应用程序。

using System.Runtime.InteropServices;
using System.Diagnostics;
...
public partial class Form1 : Form
{

    [DllImport("user32.dll")]
    static extern bool SetForegroundWindow(IntPtr hWnd);

    string targetTitle = "Notepad2";
    Process theProcess = null;

    public Form1()
    {
        InitializeComponent();
        // make the form clickthrough..
        TransparencyKey = Color.Fuchsia;
        BackColor = TransparencyKey;
        // find and keep a reference to the target process
        theProcess = findProcess(targetTitle);
        // our overlay should stay on top
        TopMost = true;
    }


    Process findProcess(string processTitle)
    {
        Process[] processList = Process.GetProcesses();
        return processList.FirstOrDefault(
               pr => pr.MainWindowTitle.ToLower().Contains(targetTitle.ToLower()));
    }


    void setActive(Process theProcess)
    {
        if (theProcess == null)
        { Console.WriteLine( "Process " + targetTitle + " not found";) return; }
        bool ok = SetForegroundWindow(theProcess.MainWindowHandle);
        Console.Write("Process " + theProcess.ProcessName + " (" + 
                       theProcess.MainWindowTitle + +  ok ? " OK." : " not OK!" );
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // do your stuff..
        Console.WriteLine("Testing Button 1");

        // done: bring the target process back:
        setActive(theProcess);
    }
}