将任何用户输入重定向到单独的底层程序

时间:2012-06-25 22:36:13

标签: c# windows-7 keyboard mouse user-input

这是我的处女帖,所以请放轻松我!

我正在用C#编写一个程序,我想运行最大化并始终在顶部。该应用程序将是半透明的,以便用户仍然可以看到我最大化的应用程序背后发生的一切。

我的目标是实现一个用户可以(尽管我的应用程序具有焦点)仍然可以与所有其他正在运行的程序正常交互的场景 - 就好像它是一块彩色玻璃,只是将所有用户输入重定向到另一个预期的应用程序例如,在叠加层后面的给定x,y鼠标点击时存在的东西。

基本思想是在任务栏以外的所有内容上创建叠加层,以便为用户在屏幕上看到的所有内容应用色调或色调。

请记住,我是一名本科生,因此知识有限 - 因此我在这里的原因。

我还考虑了一些与图形驱动程序交谈的方法来进行这些颜色变化,但我不确定前进的方向?

我最初的想法是重定向用户输入是否可行?或者我应该沿着司机和车窗颜色配置文件等路线走下去?

所以关于gammaramp的想法,我试过他跟随但没有按预期表现......

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Runtime.InteropServices;
using System.Drawing;

namespace GammaRAMP
{
public class Program
{

    [DllImport("user32.dll")]
    public static extern IntPtr GetDC(IntPtr hWnd);

    [DllImport("gdi32.dll")]
    public static extern bool SetDeviceGammaRamp(IntPtr hDC, ref RAMP lpRamp);



    [DllImport("gdi32.dll")]
    public static extern int GetDeviceGammaRamp(IntPtr hDC, ref RAMP lpRamp);


    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
    public struct RAMP
    {
        [ MarshalAs(UnmanagedType.ByValArray, SizeConst=256)] 
        public UInt16[] Red;
        [ MarshalAs(UnmanagedType.ByValArray, SizeConst=256)] 
        public UInt16[] Green;
        [ MarshalAs(UnmanagedType.ByValArray, SizeConst=256)] 
        public UInt16[] Blue;
    }

    public static void SetGamma(int gamma)
    {
        if (gamma <= 256 && gamma >= 1)
        {
            RAMP ramp = new RAMP();
            ramp.Red = new ushort[256];
            ramp.Green = new ushort[256];
            ramp.Blue = new ushort[256];

            for( int i=1; i<256; i++ )
            {
                int iArrayValue = i * (gamma + 128);

                if (iArrayValue > 65535) // I assume this is a max value.
                    iArrayValue = 65535;

                // So here I purposfully set red to max all the time expecting 
                // a lot of extra red but hardly any change occurs?

                //ramp.Red[i] = 65535; 

                // However if I do this:
                ramp.Red[i] = (ushort)iArrayValue;
                // I get VERY noticable changes?


                ramp.Blue[i] = ramp.Green[i] = (ushort)iArrayValue;
            }
            SetDeviceGammaRamp(GetDC(IntPtr.Zero), ref ramp);

        }
     }

    public static void Main(string[] args)
    {
        string ent = "";
        int g=0;

        // A RAMP struct to store initial values.
        RAMP r = new RAMP();
        // Store initial values.
       GetDeviceGammaRamp(GetDC(IntPtr.Zero),ref r);

        while (ent != "EXIT")
        {

            Console.WriteLine("Enter new Gamma (or 'EXIT' to quit):");
            ent = Console.ReadLine();
            try
            {
            g=int.Parse(ent);
            SetGamma(g);
            }
            catch
            {
            //Here only to catch errors where input is not a number (EXIT, for example, is a string)        
            }
        }

        // Reset any RAMP changes.
        SetDeviceGammaRamp(GetDC(IntPtr.Zero), ref r);
        Console.ReadLine();
    }
}
}

期待回复并非常感谢您的时间!

好的,所以我玩了上面的代码,发现如果你改变一个给定的红色/绿色/蓝色斜坡成员的因子是传递给public static void SetGamma(int gamma)的伽玛值并设置你不想要的值更改为iArrayValue = i * 128;您将获得所需的效果。现在还有待完成的是将特定于地图的rgb标量转换为滑块控件或者是colordialog。感谢大家的回复!

2 个答案:

答案 0 :(得分:0)

您可以尝试查看以下内容:

http://www.pinvoke.net/default.aspx/gdi32.setdevicegammaramp

http://www.pinvoke.net/default.aspx/gdi32/getdevicegammaramp.html

这些是易于访问的伽玛修饰符 - 您应该能够将快速应用程序组合在一起以查看它们的工作原理。它不像叠加层,但它允许您以较低的级别修改整个屏幕。

答案 1 :(得分:0)

我不确定您是否想要使用WinForms或WPF执行此操作。使用WPF,您可以执行以下操作:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525" Background="Transparent"
    AllowsTransparency="True" WindowStyle="None" Topmost="True" WindowState="Maximized">
</Window>

这将为您提供一个完全透明的窗口,所有点击等都将转到底层屏幕。然后,您可以在窗口上放置控件,它们将被看到并响应点击。例如,如果您希望这些控件部分透明,则可以使Opacity =“0.2”。

查看here以获取WinForms解决方案。

编辑: 要在屏幕上留下始终保持在顶部并且没有鼠标或键盘效果的彩色色调,请使用...

this.TopMost = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.WindowState = FormWindowState.Maximized;
this.Opacity = 0.5;
int initialStyle = GetWindowLong(this.Handle, -20);
SetWindowLong(this.Handle, -20, initialStyle | 0x20);