如何更改单个显示器的伽玛斜坡(NVidia Config)?

2024-03-05

我尝试仅更改一个屏幕而不是所有屏幕的伽玛值。

I use 这段代码 http://devadd.com/2010/10/too-bright-too-early/帮我

但是这个SetDeviceGammaRamp(GetDC(IntPtr.Zero), ref s_ramp);适用于所有设备。

[EDIT2]我看到一件奇怪的事情:SetDeviceGammaRamp 与Nvidia 面板控制器 http://international.download.nvidia.com/geforce-com/international/images/geforce-garage/how-to-calibrate-your-monitor/nvidia-control-panel-color-adjustment.png(我尝试更改 SetDeviceGammaRamp 的值,就像更改 Nvidia 面板中的亮度和对比度值一样)。所以我想我必须使用 NVidia API :/

那么,我如何更改此代码以将伽玛放在我的第一个屏幕或第二个屏幕上,但不能同时显示在两个屏幕上

[EDIT1]这就是我做的:

 class Monitor
{
    [DllImport("user32.dll")]
    static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumProc lpfnEnum, IntPtr dwData);

    public delegate int MonitorEnumProc(IntPtr hMonitor, IntPtr hDCMonitor, ref Rect lprcMonitor, IntPtr dwData);



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

    [DllImport("user32.dll")]
    static extern bool GetMonitorInfo(IntPtr hmon, ref MonitorInfo mi);


    [StructLayout(LayoutKind.Sequential)]
    public struct Rect
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    /// <summary>
    /// The struct that contains the display information
    /// </summary>
    public class DisplayInfo
    {
        public string Availability { get; set; }
        public string ScreenHeight { get; set; }
        public string ScreenWidth { get; set; }
        public Rect MonitorArea { get; set; }
        public Rect WorkArea { get; set; }
        public IntPtr DC { get; set; }
    }


    [StructLayout(LayoutKind.Sequential)]
    struct MonitorInfo
    {
        public uint size;
        public Rect monitor;
        public Rect work;
        public uint flags;
    }

    /// <summary>
    /// Collection of display information
    /// </summary>
    public class DisplayInfoCollection : List<DisplayInfo>
    {
    }

    /// <summary>
    /// Returns the number of Displays using the Win32 functions
    /// </summary>
    /// <returns>collection of Display Info</returns>
    public DisplayInfoCollection GetDisplays()
    {
        DisplayInfoCollection col = new DisplayInfoCollection();

        EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero,
            delegate (IntPtr hMonitor, IntPtr hdcMonitor, ref Rect lprcMonitor, IntPtr dwData)
             {
                 MonitorInfo mi = new MonitorInfo();
                 mi.size = (uint)Marshal.SizeOf(mi);
                 bool success = GetMonitorInfo(hMonitor, ref mi);
                 if (success)
                 {
                     DisplayInfo di = new DisplayInfo();
                     di.ScreenWidth = (mi.monitor.right - mi.monitor.left).ToString();
                     di.ScreenHeight = (mi.monitor.bottom - mi.monitor.top).ToString();
                     di.MonitorArea = mi.monitor;
                     di.WorkArea = mi.work;
                     di.Availability = mi.flags.ToString();
                     di.DC = GetDC(hdcMonitor);
                     col.Add(di);
                 }
                 return 1;
             }, IntPtr.Zero);
        return col;
    }

    public Monitor()
    {

    }
}

对于 SetDeviceGammaRamp,我做了这个:

    GammaRamp gamma = new GammaRamp();
    Monitor.DisplayInfoCollection monitors;
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        Monitor monitor = new Monitor();
        monitors = monitor.GetDisplays();
    }

    private void trackBar1_Scroll(object sender, EventArgs e)
    {
        int value = trackBar1.Value;
        gamma.SetValue(Convert.ToByte(value), monitors[1].DC);
    }

GammaRamp 类:

public void SetValue(byte value, IntPtr hdc)
    {
        Ramp gammaArray = new Ramp { Red = new ushort[256], Green = new ushort[256], Blue = new ushort[256] };
        for (int i = 0; i < 256; i++)
        {
            gammaArray.Red[i] = gammaArray.Green[i] = gammaArray.Blue[i] = (ushort)Math.Min(i * (value + 128), ushort.MaxValue);
        }

        SetDeviceGammaRamp(hdc, ref gammaArray);
    }

您可以使用以下方法获取另一台显示器的 DC枚举显示监视器 https://msdn.microsoft.com/en-us/library/windows/desktop/dd162610(v=vs.85).aspx or 获取监控信息 https://msdn.microsoft.com/en-us/library/windows/desktop/dd144901(v=vs.85).aspx功能。

完整解释请参见HMONITOR 和设备上下文 https://msdn.microsoft.com/en-us/library/windows/desktop/dd144968(v=vs.85).aspx.

EDIT

正如中所解释的枚举显示监视器 https://msdn.microsoft.com/en-us/library/windows/desktop/dd162610(v=vs.85).aspx,

  • pass IntPtr.Zero to hdc参数(值涵盖所有显示)
  • then in 监控数字过程 https://msdn.microsoft.com/en-us/library/windows/desktop/dd145061(v=vs.85).aspx, hdcMonitor应包含当前正在评估的监视器的正确 DC
  • 然后改变你的di.DC = GetDC(IntPtr.Zero); to di.DC = GetDC(hdcMonitor);

(通过Zero to GetDC显然会指定所有监视器,而不是您想要的)

EDIT 2

与文档很少混淆,实际上应该执行 EnumDisplayMonitors 注释中的第三种类型的调用:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows;

namespace WpfApplication1
{
    public partial class MainWindow
    {
        private readonly List<IntPtr> _dcs = new List<IntPtr>();

        public MainWindow()
        {
            InitializeComponent();
            Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var hdc = NativeMethods.GetDC(IntPtr.Zero);
            if (hdc == IntPtr.Zero)
                throw new InvalidOperationException();
            if (!NativeMethods.EnumDisplayMonitors(hdc, IntPtr.Zero, Monitorenumproc, IntPtr.Zero))
                throw new InvalidOperationException();
            if (NativeMethods.ReleaseDC(IntPtr.Zero, hdc) == 0)
                throw new InvalidOperationException();

            foreach (var monitorDc in _dcs)
            {
                // do something cool !   
            }
        }

        private int Monitorenumproc(IntPtr param0, IntPtr param1, ref tagRECT param2, IntPtr param3)
        {
            // optional actually ...
            var info = new MonitorInfo {cbSize = (uint) Marshal.SizeOf<MonitorInfo>()};
            if (!NativeMethods.GetMonitorInfoW(param0, ref info))
                throw new InvalidOperationException();

            _dcs.Add(param1); // grab DC for current monitor !

            return 1;
        }
    }


    public class NativeMethods
    {
        [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
        public static extern int ReleaseDC([In] IntPtr hWnd, [In] IntPtr hDC);

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

        [DllImport("user32.dll", EntryPoint = "GetMonitorInfoW")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetMonitorInfoW([In] IntPtr hMonitor, ref MonitorInfo lpmi);

        [DllImport("user32.dll", EntryPoint = "EnumDisplayMonitors")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool EnumDisplayMonitors([In] IntPtr hdc, [In] IntPtr lprcClip, MONITORENUMPROC lpfnEnum,
            IntPtr dwData);
    }

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    public delegate int MONITORENUMPROC(IntPtr param0, IntPtr param1, ref tagRECT param2, IntPtr param3);

    [StructLayout(LayoutKind.Sequential)]
    public struct MonitorInfo
    {
        public uint cbSize;
        public tagRECT rcMonitor;
        public tagRECT rcWork;
        public uint dwFlags;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct tagRECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }
}

您应该能够获得每个显示器的 DC(无法 100% 确认,因为我只有一个屏幕)。

如果其他一切都失败了,那么也许 NVidia 的东西会在幕后以某种方式干扰。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何更改单个显示器的伽玛斜坡(NVidia Config)? 的相关文章

  • 列出 C 常量/宏

    有没有办法使GNU C 预处理器 cpp 或其他一些工具 列出给定点上的所有可用宏及其值C file 我正在寻找特定于系统的宏 同时移植一个已经精通 UNIX 的程序并加载一堆稀疏的 UNIX 系统文件 只是想知道是否有比寻找定义更简单的方
  • 读取进程的进程内存不会返回所有内容

    我正在尝试扫描第三方应用程序的内存 我已经查到地址了 现在是在0x0643FB78 问题是 从那以后我就再也爬不上去LPMODULEENTRY32 gt modBaseAddr is 0x00400000 and LPMODULEENTRY
  • fgetc,检查 EOF

    在书里Linux系统编程我读过一些这样的内容 fgetc返回读取为的字符unsigned char投射到int or EOF在文件末尾或错误 使用时的一个常见错误fgetc is char c if c fgetc EOF 该代码的正确版本
  • 了解左值到右值转换的示例

    我很难理解这段代码 来自 C 14 草案标准的示例 转换拉瓦尔 调用未定义的行为g false 为什么constexpr使程序有效 另外 不访问 是什么意思 y n 在两次通话中g 我们正在返回n数据成员那么为什么最后一行说它不能访问它呢
  • 使用回溯(而不是 DFS)背后的直觉

    我正在解决单词搜索 https leetcode com problems word search description LeetCode com 上的问题 给定一个 2D 板和一个单词 查找该单词是否存在于网格中 该单词可以由顺序相邻单
  • 与智能指针的返回类型协方差

    在 C 中我们可以这样做 struct Base virtual Base Clone const virtual Base struct Derived Base virtual Derived Clone const overrides
  • 使用箭头键滚动可滚动控件

    我正在使用一个ScrollableControl在我的 C 项目中 我想知道如何将箭头键映射到垂直 水平滚动 编辑 我的图片框获得焦点 并且我设法映射滚动键 这里的问题是 当我按下箭头键时 它会滚动一次 然后失去焦点 将其交给滚动查看器旁边
  • C 预处理器“/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cpp”未通过完整性检查

    在使用 Xcode 11 3 的 macOS Mojave 上 我有一个基于 Autotool 的第三方库 在终端中运行我的构建脚本时构建得很好 但在 Xcode 中运行时失败Run Script步骤为 BuildScript Showin
  • C++ 标准是否保证未使用的私有字段会影响 sizeof?

    考虑以下结构 class Foo int a 在 g 中测试 我明白了sizeof Foo 4但这是由标准保证的吗 是否允许编译器注意到a是一个未使用的私有字段并将其从类的内存表示中删除 导致更小的 sizeof 我不希望任何编译器真正进行
  • 如何取消 NetworkStream.ReadAsync 而不关闭流

    我正在尝试使用 NetworkStream ReadAsync 读取数据 但我找不到如何取消调用后的 ReadAsync 作为背景 NetworkStream 由连接的 BluetoothClient 对象 来自 32Feet NET 蓝牙
  • GoogleTest:如何跳过测试?

    使用 Google Test 1 6 Windows 7 Visual Studio C 如何关闭给定的测试 又名如何阻止测试运行 除了注释掉整个测试之外 我还能做些什么吗 The docs https github com google
  • 即使使用前向声明也会出现未定义的类型错误

    我正在阅读循环引用和前向声明 我确实知道在头文件中实现并不是一个好的设计实践 然而我正在尝试并且无法理解这种行为 使用以下代码 包含前向声明 我期望它能够构建 但是我收到此错误 Error 1 error C2027 use of unde
  • List.Except 不起作用

    我尝试减去 2 个列表 如下代码所示 assignUsers已获得 3 条记录assignedUsers有 2 行 后Except方法我仍然得到 3 行 尽管我应该得到 1 条记录 因为 2 行assignedUsers类似于assignU
  • LINQ 分组依据和选择集合

    我有这个结构 Customer has many Orders has many OrderItems 我想生成一个列表CustomerItems通过 LINQ 给出的子集OrderItems List of new Customer Li
  • 以编程方式将 Word 文件另存为图片

    我想将Word文档的第一页另存为图片 使用 C 有什么方法可以做到这一点 您可以将 Word 文档打印到 XPS 文档 在 WPF Net 3 5 应用程序中打开它 并使用 WPF 框架的文档和图像功能将第一个内部固定页面对象转换为位图 如
  • 我试图使这段代码递归,但由于某种原因它不起作用[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我试图使这
  • 如何使用va_start()?

    在具有可变参数的函数中 我们使用函数 va start 初始化 va list ap 类型的对象 如下所示 void va start va list ap parmN 我不明白1 什么类型的对象可以作为 parMN 最后一个已知参数 传递
  • SQL 注入在 winform 中有效吗?

    我正在用 C 制作一个 Windows 软件 我读过关于sql injection但我没有发现它适用于我的应用程序 SQL 注入在 winform 中有效吗 如果是的话如何预防 EDIT 我正在使用文本框来读取用户名和密码 通过使用 tex
  • 实现“计时器”的最佳方法是什么? [复制]

    这个问题在这里已经有答案了 实现计时器的最佳方法是什么 代码示例会很棒 对于这个问题 最佳 被定义为最可靠 失火次数最少 和最精确 如果我指定 15 秒的间隔 我希望每 15 秒调用一次目标方法 而不是每 10 20 秒调用一次 另一方面
  • 提高大型结构列表的二进制序列化性能

    我有一个以 3 个整数保存 3d 坐标的结构 在测试中 我将 100 万个随机点放在一起 List 然后对内存流使用二进制序列化 内存流大小约为 21 MB 这似乎非常低效 因为 1000000 点 3 坐标 4 字节应该至少为 11MB

随机推荐