显示器 ddc/ci_windows管理工具命令

显示器 ddc/ci_windows管理工具命令【代码】windows系统下显示器的DDC/CI命令工具

显示器

Windows系统对接入系统的显示器设备制定了一套DDC/CI协议标准,方便程序对显示器进行操作,本篇分享一个在windows系统下通过DDC协议访问显示器的demo程序,可基于命令行方式对显示器支持的DDC接口进行访问和设置,方便以此为接口进行显示器相关的程序开发:

#include <atlstr.h>
#include <PhysicalMonitorEnumerationAPI.h>
#include <LowLevelMonitorConfigurationAPI.h>
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <functional>
#include <sstream>


std::vector<PHYSICAL_MONITOR> physicalMonitors{};

BOOL CALLBACK monitorEnumProcCallback(HMONITOR hMonitor, HDC hDeviceContext, LPRECT rect, LPARAM data)
{
	DWORD numberOfPhysicalMonitors;
	BOOL success = GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, &numberOfPhysicalMonitors);
	if (success) {
		auto originalSize = physicalMonitors.size();
		physicalMonitors.resize(physicalMonitors.size() + numberOfPhysicalMonitors);
		success = GetPhysicalMonitorsFromHMONITOR(hMonitor, numberOfPhysicalMonitors, physicalMonitors.data() + originalSize);
	}
	return true;
}

std::string toUtf8(wchar_t *buffer)
{
	CW2A utf8(buffer, CP_UTF8);
	const char* data = utf8.m_psz;
	return std::string{ data };
}

int printUsage(std::vector<std::string> args)
{
	std::cout << "Usage: winddcutil command [<arg> ...]" << std::endl
		<< "Commands:" << std::endl
		<< "\thelp                                           Display help" << std::endl
		<< "\tdetect                                         Detect monitors" << std::endl
		<< "\tcapabilities <display-id>                      Query monitor capabilities" << std::endl
		<< "\tgetvcp <display-id> <feature-code>             Report VCP feature value" << std::endl
		<< "\tsetvcp <display-id> <feature-code> <new-value> Set VCP feature value" << std::endl;
	return 1;
}

int detect(std::vector<std::string> args)
{
	int i = 0;
	for (auto &physicalMonitor : physicalMonitors) {
		std::cout << "Display " << i << ":\t" << toUtf8(physicalMonitor.szPhysicalMonitorDescription) << std::endl;
		i++;
	}
	return 0;
}

int capabilities(std::vector<std::string> args) {
	if (args.size() < 1) {
		std::cerr << "Display ID required" << std::endl;
		return printUsage(args);
	}

	size_t displayId = INT_MAX;
	try {
		displayId = std::stoi(args[0]);
	}
	catch (...) {
		std::cerr << "Failed to parse display ID" << std::endl;
		return 1;
	}

	if (displayId > physicalMonitors.size() - 1) {
		std::cerr << "Invalid display ID" << std::endl;
		return 1;
	}

	auto physicalMonitorHandle = physicalMonitors[displayId].hPhysicalMonitor;

	DWORD capabilitiesStringLengthInCharacters;
	auto success = GetCapabilitiesStringLength(physicalMonitorHandle, &capabilitiesStringLengthInCharacters);
	if (!success) {
		std::cerr << "Failed to get capabilities string length" << std::endl;
		return 1;
	}

	std::unique_ptr<char[]> capabilitiesString{ new char[capabilitiesStringLengthInCharacters] };
	success = CapabilitiesRequestAndCapabilitiesReply(physicalMonitorHandle, capabilitiesString.get(), capabilitiesStringLengthInCharacters);
	if (!success) {
		std::cerr << "Failed to get capabilities string" << std::endl;
		return 1;
	}

	std::cout << std::string(capabilitiesString.get()) << std::endl;

	return 0;
}

int getVcp(std::vector<std::string> args) {
	if (args.size() < 1) {
		std::cerr << "Display ID required" << std::endl;
		return printUsage(args);
	}

	size_t displayId = INT_MAX;
	BYTE vcpCode;
	try {
		displayId = std::stoi(args[0]);
		vcpCode = std::stoul(args[1], nullptr, 16);
	}
	catch (...) {
		std::cerr << "Failed to parse display ID" << std::endl;
		return 1;
	}

	if (displayId > physicalMonitors.size() - 1) {
		std::cerr << "Invalid display ID" << std::endl;
		return 1;
	}

	auto physicalMonitorHandle = physicalMonitors[displayId].hPhysicalMonitor;

	DWORD currentValue;
	bool success = GetVCPFeatureAndVCPFeatureReply(physicalMonitorHandle, vcpCode, NULL, &currentValue, NULL);
	if (!success) {
		std::cerr << "Failed to get the vcp code value" << std::endl;
		return 1;
	}

	std::stringstream ss;
	ss << std::hex << currentValue;
	std::cout << "VCP " << args[1] << " " << ss.str() << std::endl;

	return 0;
}

int setVcp(std::vector<std::string> args) {
	if (args.size() < 3) {
		std::cerr << "Invalid number of arguments" << std::endl;
		return printUsage(args);
	}

	size_t displayId = INT_MAX;
	BYTE vcpCode;
	DWORD newValue;
	try {
		displayId = std::stoi(args[0]);
		vcpCode = std::stoul(args[1], nullptr, 16);
		newValue = std::stoul(args[2], nullptr, 16);
	}
	catch (...) {
		std::cerr << "Failed to parse setvcp arguments" << std::endl;
		return printUsage(args);
	}

	if (displayId > physicalMonitors.size() - 1) {
		std::cerr << "Invalid display ID" << std::endl;
		return 1;
	}

	bool success = SetVCPFeature(physicalMonitors[displayId].hPhysicalMonitor, vcpCode, newValue);
	if (!success) {
		std::cerr << "Failed to set vcp feature" << std::endl;
		return 1;
	}
	return 0;
}

std::unordered_map<std::string, std::function<int(std::vector<std::string>)>> commands
{
	{ "help", printUsage },
	{ "detect", detect},
	{ "capabilities", capabilities },
	{ "getvcp", getVcp },
	{ "setvcp", setVcp},
};

int main(int argc, char *argv[], char *envp[])
{
	std::vector<std::string> args;

	if (argc < 2)
		return printUsage(args);

	for (int i = 1; i < argc; i++) {
		std::string arg(argv[i]);
		args.emplace_back(arg);
	}

	auto command = commands.find(args[0]);
	if (command == commands.end()) {
		std::cerr << "Unkown command" << std::endl;
		return printUsage(args);
	}
	args.erase(args.begin());

	EnumDisplayMonitors(NULL, NULL, &monitorEnumProcCallback, 0);

	auto success = command->second(args);

	DestroyPhysicalMonitors(physicalMonitors.size(), physicalMonitors.data());

	return success;
}

今天的文章显示器 ddc/ci_windows管理工具命令分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/83462.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注