Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Bildschirmhelligkeit steuern


Jojojoxx - So 17.01.10 01:31
Titel: Bildschirmhelligkeit steuern
Hallo zusammen!

Gibt es irgendwie eine Möglichkeit die Bildschirmhelligkeit bei Notebooks zu steuern?
Damit meine ich die "echte" Helligkeit (Backlight des Bildschirms).
Danke euch!
mfg

Jojo


BenBE - So 17.01.10 01:34

Ja, das geht. [http://homepages.tesco.net/~J.deBoynePollard/FGA/questions-with-yes-or-no-answers.html]


Jojojoxx - So 17.01.10 01:51

und wie? :roll:


BenBE - So 17.01.10 01:53

Google ergibt: [http://lmgtfy.com/?q=IOCTL+Display+Backlight&l=1] http://msdn.microsoft.com/en-us/library/aa372656%28VS.85%29.aspx


Jojojoxx - Sa 23.01.10 21:29

Hi!

Ich habe mir die Artikel mal durchgelesen. Zuerst muss ich ja die unterstütze Helligkeit "erfragen" mittels DeviceIoControl. Aber wie genau stell ich das an? Mir ist auch ehrlich gesagt keiner der Parameter klar und weiß auch nicht wie ich die setzen muss...
So soll der Funktionsaufruf laut Artikel aussehen:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
BOOL DeviceIoControl(
  (HANDLE) hDevice,                // handle to device
  IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS,  // dwIoControlCode
  NULL,                            // lpInBuffer
  0,                               // nInBufferSize
  (LPVOID) lpOutBuffer,            // output buffer
  (DWORD) nOutBufferSize,          // size of output buffer
  (LPDWORD) lpBytesReturned,       // number of bytes returned
  (LPOVERLAPPED) lpOverlapped      // OVERLAPPED structure
);


Danke!
mfg

Jojo


BenBE - Sa 23.01.10 22:16

hDevice ist das Device-Handle des Monitors, der gesteuert werden soll. Dazu steht im Artikel was, wie man dieses bekommt.

LPVOID ist nix anderes als ein Pointer auf Speicher; LPDWORD ein Pointer auf ein DWORD. LPOVERLAPPED ist eine OS-Spezifische Struktur für asynchrone Anfragen, die für deinen Fall mit nil übergeben werden kann. Und den Rest erklären doch eigentlich die Parameternamen, bzw. die Beschreibung der Funktion.

Die IOCTL-Konstante ist in den Delphi-Headern leider nicht übersetzt; da müsste ich aber auch erst den Wert für raussuchen; hatte das irgendwann für eine Lib von mir schon mal partiell portiert, aber nie wirklich testen können.


jaenicke - Sa 23.01.10 22:23

Ab Vista gibt es auch eine einfachere Möglichkeit über WMI [http://msdn.microsoft.com/en-us/library/aa394549(VS.85).aspx] mit WmiMonitorBrightness. Auf die Schnelle hat es jetzt bei mir nicht funktioniert, aber eigentlich sollte es damit gehen.


BenBE - Sa 23.01.10 22:35

Hier mal nen Auszug aus der OIncMonitors.pas von Omorphia:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
//BenBE: LCD Brightness Control
//  Note: This functions are available on WinXP SP1 and Win2K3 only,
//  because the used IOCTL-codes were introduced with windows versions.
//  TODO -oBenBE -cInc, Scrn, LCD : Brightness Support, WinXP SP1 DDK or ntddvdeo.h needed
//  MSG BenBE@All : Suche Kopie eines M$ WinXP DDK :D
//  Oder folgende Konstanten der ntddvdeo.h:
//      IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS
//      IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS
//      IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS

//Information obtained from the WinXP SP1 DDK:
Const
    //#define CTL_CODE( DeviceType, Function, Method, Access ) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) )
    //#define FILE_DEVICE_VIDEO               0x00000023
    FILE_DEVICE_VIDEO = $23;
    //#define METHOD_BUFFERED                 0
    METHOD_BUFFERED = 0;
    //#define FILE_ANY_ACCESS                 0
    FILE_ANY_ACCESS = 0;
    //#define IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS CTL_CODE(FILE_DEVICE_VIDEO, 0x125, METHOD_BUFFERED, FILE_ANY_ACCESS)
Const
    IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS =
        FILE_DEVICE_VIDEO Shl 16 Or
        $125 Shl 2 Or
        METHOD_BUFFERED Shl 14 Or
        FILE_ANY_ACCESS;
    //#define IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS CTL_CODE(FILE_DEVICE_VIDEO, 0x126, METHOD_BUFFERED, FILE_ANY_ACCESS)
Const
    IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS =
        FILE_DEVICE_VIDEO Shl 16 Or
        $126 Shl 2 Or
        METHOD_BUFFERED Shl 14 Or
        FILE_ANY_ACCESS;
    //#define IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS CTL_CODE(FILE_DEVICE_VIDEO, 0x127, METHOD_BUFFERED, FILE_ANY_ACCESS)
Const
    IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS =
        FILE_DEVICE_VIDEO Shl 16 Or
        $127 Shl 2 Or
        METHOD_BUFFERED Shl 14 Or
        FILE_ANY_ACCESS;

    //typedef struct _DISPLAY_BRIGHTNESS {
    //  UCHAR ucDisplayPolicy;
    //  UCHAR ucACBrightness;
    //  UCHAR ucDCBrightness;
    //} DISPLAY_BRIGHTNESS, *PDISPLAY_BRIGHTNESS;
Type
    TDisplayBrightness = Packed Record
        ucDisplayPolicy: Byte;
        ucACBrightness: Byte;
        ucDCBrightness: Byte;
    End;

    //TODO 4 -oBenBE -cInc, Scrn, LCD : DISPLAYPOLICY-Werte korrigieren!
    //DISPLAYPOLICY_AC
    //DISPLAYPOLICY_DC
    //DISPLAYPOLICY_BOTH
Const
    DISPLAYPOLICY_AC = 1;
    DISPLAYPOLICY_DC = 2;
    DISPLAYPOLICY_BOTH = 3;

Function IsLCDAvailable: Boolean;
Function IsLCD_ACBrightnessSupported(Level: Byte): Boolean;
Function IsLCD_DCBrightnessSupported(Level: Byte): Boolean;
Function GetLCD_ACBrightnessLevel: Byte;
Function GetLCD_DCBrightnessLevel: Byte;
Function GetLCD_CurrBrightnessLevel: Byte;
Function SetLCD_ACBrightnessLevel(Level: Byte): Boolean;
Function SetLCD_DCBrightnessLevel(Level: Byte): Boolean;
Function SetLCD_BothBrightnessLevel(Level: Byte): Boolean;

{...}

Const
    LCDDeviceFile = '\\.\LCD';

Function IsLCDAvailable: Boolean;
Var
    LCDHandle: HFILE;
Begin
    Result := False;
    LCDHandle := CreateFile(LCDDeviceFile, 0, FILE_SHARE_READ Or FILE_SHARE_WRITE, Nil, OPEN_EXISTING, 00);
    Try
        Result := IsValidHandle(LCDHandle);
    Finally
        If Result Then
            CloseHandle(LCDHandle);
    End;
End;

Function IsLCD_ACBrightnessSupported(Level: Byte): Boolean;
Var
    LCDHandle: HFILE;
    BufSize: DWORD;
    Buf: Array Of Byte;
    X: Integer;
Begin
    Result := False;

    If Not IsLCDAvailable Then
        Exit;

    LCDHandle := CreateFile(LCDDeviceFile, 0, FILE_SHARE_READ Or FILE_SHARE_WRITE, Nil, OPEN_EXISTING, 00);
    Try
        BufSize := 256;
        SetLength(Buf, BufSize);
        If Not DeviceIoControl(LCDHandle, IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS, Nil0, @Buf[0], BufSize, BufSize, NilThen
            Exit;
        SetLength(Buf, BufSize);
        // TODO -oBenBE -cInc, Scrn, LCD : Optimize IsLCD_ACBrightnessSupported by using ASM
        For X := 0 To BufSize - 1 Do
            If Buf[X] = Level Then
            Begin
                Result := True;
                Exit;
            End;
    Finally
        CloseHandle(LCDHandle);
    End;
End;

Function IsLCD_DCBrightnessSupported(Level: Byte): Boolean; Assembler;
Asm
    CALL IsLCD_ACBrightnessSupported
End;

Function GetLCD_ACBrightnessLevel: Byte;
Var
    LCDHandle: HFILE;
    DispBrightness: TDisplayBrightness;
    BufSize: DWORD;
Begin
    Result := 0;

    If Not IsLCDAvailable Then
        Exit;

    LCDHandle := CreateFile(LCDDeviceFile, 0, FILE_SHARE_READ Or FILE_SHARE_WRITE, Nil, OPEN_EXISTING, 00);
    Try
        BufSize := SizeOf(DispBrightness);
        If Not DeviceIoControl(LCDHandle, IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS, Nil0, @DispBrightness, BufSize, BufSize, NilThen
            Exit;
        Result := DispBrightness.ucACBrightness;
    Finally
        CloseHandle(LCDHandle);
    End;
End;

Function GetLCD_DCBrightnessLevel: Byte;
Var
    LCDHandle: HFILE;
    DispBrightness: TDisplayBrightness;
    BufSize: DWORD;
Begin
    Result := 0;

    If Not IsLCDAvailable Then
        Exit;

    LCDHandle := CreateFile(LCDDeviceFile, 0, FILE_SHARE_READ Or FILE_SHARE_WRITE, Nil, OPEN_EXISTING, 00);
    Try
        BufSize := SizeOf(DispBrightness);
        If Not DeviceIoControl(LCDHandle, IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS, Nil0, @DispBrightness, BufSize, BufSize, NilThen
            Exit;
        Result := DispBrightness.ucDCBrightness;
    Finally
        CloseHandle(LCDHandle);
    End;
End;

Function GetLCD_CurrBrightnessLevel: Byte;
Var
    LCDHandle: HFILE;
    DispBrightness: TDisplayBrightness;
    BufSize: DWORD;
Begin
    Result := 0;

    If Not IsLCDAvailable Then
        Exit;

    LCDHandle := CreateFile(LCDDeviceFile, 0, FILE_SHARE_READ Or FILE_SHARE_WRITE, Nil, OPEN_EXISTING, 00);
    Try
        BufSize := SizeOf(DispBrightness);
        If Not DeviceIoControl(LCDHandle, IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS, Nil0, @DispBrightness, BufSize, BufSize, NilThen
            Exit;
        If DispBrightness.ucDisplayPolicy = DISPLAYPOLICY_AC Then
            Result := DispBrightness.ucACBrightness
        Else If DispBrightness.ucDisplayPolicy = DISPLAYPOLICY_DC Then
            Result := DispBrightness.ucDCBrightness;
    Finally
        CloseHandle(LCDHandle);
    End;
End;

Function SetLCD_ACBrightnessLevel(Level: Byte): Boolean;
Begin
    // TODO -oBenBE -cInc, Scrn, LCD : SetLCD_ACBrightnessLevel implementieren
    Result := False;

    If Not IsLCDAvailable Then
        Exit;
End;

Function SetLCD_DCBrightnessLevel(Level: Byte): Boolean;
Begin
    // TODO -oBenBE -cInc, Scrn, LCD : SetLCD_DCBrightnessLevel implementieren
    Result := False;

    If Not IsLCDAvailable Then
        Exit;
End;

Function SetLCD_BothBrightnessLevel(Level: Byte): Boolean;
Begin
    // TODO -oBenBE -cInc, Scrn, LCD : SetLCD_BothBrightnessLevel implementieren
    Result := False;

    If Not IsLCDAvailable Then
        Exit;
End;


Bisher nie getestet, ob der so geht, dürfte aber ...

P.S.: Patches welcome ;-)


Jojojoxx - Sa 23.01.10 22:52

Also die Sache mit WMI hört sich ja interessant an, was muss ich denn einbinden um diese Funktion zu nutzen?
Denn

Quelltext
1:
WmiSetBrightness(1,100);                    

führt zu

Quelltext
1:
[Fehler] Unit1.pas(159): Undefinierter Bezeichner: 'WmiSetBrightness'                    


jaenicke - Sa 23.01.10 23:02

Ganz so einfach ist das auch wieder nicht. Du musst dich zuerst mit WMI verbinden, die Klasse des entsprechenden Providers holen, dann die Methode selbst und die Parameter aufbauen. Danach erst kannst du die Methode aufrufen.
Ein Beispiel in C++ findest du hier, damit und mit den Definitionen aus dem Vista SDK hatte ich es eben kurz versucht:
http://msdn.microsoft.com/en-gb/library/aa384833(VS.85).aspx


Delete - Mo 14.10.13 09:59

Siehe:
http://www.entwickler-ecke.de/viewtopic.php?p=680567#680567

und hier:
http://www.entwickler-ecke.de/viewtopic.php?t=112151