c# Cooperate with c++ to adjust the screen brightness, non-gamma and RGB scheme

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <iostream>
#include <Ntddvdeo.h>
using namespace std;

#define IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS  CTL_CODE(FILE_DEVICE_VIDEO, 0x125, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS 	CTL_CODE(FILE_DEVICE_VIDEO, 0x126, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS 		CTL_CODE(FILE_DEVICE_VIDEO, 0x127, METHOD_BUFFERED, FILE_ANY_ACCESS)


int setBrightness(int level)
{
	HANDLE h;
	DWORD nOutBufferSize = 256;
	BYTE SupportedBrightness[256];
	DWORD g_supportedLevelCount;
	DISPLAY_BRIGHTNESS DisplayBrightness;

	memset(SupportedBrightness, 0, sizeof(SupportedBrightness));

	/* use createfile function to open lcd.
	* url from microsoft about IOCTL code.
	*  http://msdn.microsoft.com/en-us/library/windows/desktop/aa372703%28v=vs.85%29.aspx
	*/

	/*
	* char* 和 wchar_t* 互相转换参考博客
	* https://www.cnblogs.com/icqw/p/4614877.html
	*/
	/*
	* c++代码参考博客
	* https://blog.csdn.net/weixin_34111819/article/details/86328019
	*/
	char temchar[] = "\\\\.\\LCD";
	char* szSour = temchar;
	WCHAR Temp[128] = { 0 };
	mbstowcs(Temp, szSour, strlen(szSour));
	h = CreateFile(Temp, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
	if (h == INVALID_HANDLE_VALUE) {
		printf("Open \\\\.\\LCD error");
		exit(1);
	}

	/* Query for display supported level */
	if (!DeviceIoControl(h, IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS, NULL, 0, SupportedBrightness, nOutBufferSize, &g_supportedLevelCount, NULL)) {
		printf("IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS error - %d, - buffer: %d ", g_supportedLevelCount, nOutBufferSize);
		exit(1);
	}
	if (g_supportedLevelCount == 0)  	/* 0 means not supported */
	{
		printf("\nLCD not support LEVEL COUNT", g_supportedLevelCount);
		exit(1);
	}

	DisplayBrightness.ucDisplayPolicy = 0;
	DisplayBrightness.ucACBrightness = level;
	DisplayBrightness.ucDCBrightness = level;

	/* Set display backlight level */
	nOutBufferSize = sizeof(DisplayBrightness);
	if (!DeviceIoControl(h, IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS, (DISPLAY_BRIGHTNESS*)&DisplayBrightness, nOutBufferSize, NULL, 0, &nOutBufferSize, NULL)) {
		printf("IOCTL_VIDEO_SET_SUPPORTED_BRIGHTNESS error - %d, - buffer: %d ", g_supportedLevelCount, nOutBufferSize);
		exit(1);
	}

	Sleep(500); /* delay for some time while wmi event changed */
	nOutBufferSize = sizeof(DisplayBrightness);
	if (!DeviceIoControl(h, IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS, NULL, 0, (DISPLAY_BRIGHTNESS*)&DisplayBrightness, nOutBufferSize, &nOutBufferSize, NULL)) {
		printf("IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS error - %d, - buffer: %d ", g_supportedLevelCount, nOutBufferSize);
		exit(1);
	}
	printf("\nBrightness_AC: %d\nBrightness_DC: %d", DisplayBrightness.ucACBrightness, DisplayBrightness.ucDCBrightness);
}


int main(int argc, char* argv[]) {
	///* program with arguments support */
	//if (argc == 3 && strcmp("-b", argv[1]) == 0) {
	//	setBrightness(atoi(argv[2]));
	//}
	//else {
	//	help();
	//}
	int a;
	cin >> a;
	setBrightness(a);
	return 0;
}

The compilation environment is VS. As we all know, VS has relatively strict requirements on the code. So some parts of this big guy's code need to be modified. Here I will point out the changes and explain the changes.

First of all, #include <Ntddvdeo.h> can be quoted directly. Don't add a prefix, VS will automatically search for this header file.

	char temchar[] = "\\\\.\\LCD";
	char* szSour = temchar;
	WCHAR Temp[128] = { 0 };
	mbstowcs(Temp, szSour, strlen(szSour));
	h = CreateFile(Temp, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);

Secondly, the Temp parameter here, the previous big guy's writing is directly "\\\\.\\LCD", but the position of this parameter is to fill in a WCHAR type parameter, so we have to convert it. During the conversion process, VS does not allow the char* pointer to point to a string constant, so we must first assign the string constant to a character array, and then use the pointer to point to it. The conversion method is in the blog of another big guy, and I have given the address as a comment in the code (thanks to the contributions made by the predecessors).

Finally, I want to specify that the level in this int setBrightness(int level) ranges from 0 to 100, although in most cases it can be seen clearly when you adjust it to 0, but what about it, it’s best not to adjust it when testing. To zero.

The above is the c++ code. Now let us make a c# module. (I will release the connection at the end of this module, there are two connections to Baidu Cloud and CSDN, and gitHub has all the source code) Our idea is to compile C++ into a DLL module, and then reference it by c#, and encapsulate it into a module in C# The way to call for C#.

The following is a tutorial of c++ packaging DLL (materials are being prepared, not finished yet, save it first)

Guess you like

Origin blog.csdn.net/u011471253/article/details/114170009