2006. május 31., szerda
How to retrieve and change display settings
Problem/Question/Abstract:
I can't find a way to enumerate or test display frequencies. When I use ChangeDisplaySettings to test for a given mode it returns DISP_CHANGE_SUCCESSFUL, no matter what I put in for dmDisplayFrequency. Should I just attempt to set a good median freq such as 75Hz and forget about it? Any other ideas?
Answer:
type
PdmArray = ^TDmArray;
TDmArray = array[0..0] of TDeviceMode;
TForm1 = class(TForm)
{ ... }
private
lpDmArray: PDmArray;
NumModes: integer;
BitsPerPixel: DWord;
RefreshRate: DWord;
CurrentDisplayMode: integer;
SelectedDisplayMode: integer;
{ ... }
public
end;
procedure TForm1.RetrieveDisplayModes;
var
I: Integer;
MoreModes: Bool;
dm: TDeviceMode;
begin
StringGridDisplayModes.ColCount := 5;
StringGridDisplayModes.RowCount := 2;
StringGridDisplayModes.Cells[0, 0] := 'Mode';
StringGridDisplayModes.Cells[1, 0] := 'Resulution';
StringGridDisplayModes.Cells[2, 0] := 'Bits per Pixel (Colors)';
StringGridDisplayModes.Cells[3, 0] := 'DisplayFrequency';
StringGridDisplayModes.Cells[4, 0] := 'DeviceName';
for I := 0 to StringGridDisplayModes.ColCount do
StringGridDisplayModes.Cells[I, 1] := '';
MoreModes := TRUE;
I := 0;
while MoreModes do
begin
MoreModes := EnumDisplaySettings(nil, I, dm);
StringGridDisplayModes.Cells[0, StringGridDisplayModes.RowCount - 1] :=
IntToStr(I);
StringGridDisplayModes.Cells[1, StringGridDisplayModes.RowCount - 1] :=
IntToStr(dm.dmPelsWidth) + ' * ' + IntToStr(dm.dmPelsHeight);
StringGridDisplayModes.Cells[2, StringGridDisplayModes.RowCount - 1] :=
IntToStr(dm.dmBitsPerPel);
StringGridDisplayModes.Cells[3, StringGridDisplayModes.RowCount - 1] :=
IntToStr(dm.dmDisplayFrequency);
StringGridDisplayModes.Cells[4, StringGridDisplayModes.RowCount - 1] :=
dm.dmDeviceName;
if (dm.dmPelsWidth = Screen.Width) and (dm.dmPelsHeight = Screen.Height) and
(dm.dmBitsPerPel = BitsPerPixel) and (dm.dmDisplayFrequency = RefreshRate) then
CurrentDisplayMode := I;
StringGridDisplayModes.RowCount := StringGridDisplayModes.RowCount + 1;
Inc(i);
end;
StringGridDisplayModes.RowCount := StringGridDisplayModes.RowCount - 1;
NumModes := I;
GetMem(lpDmArray, sizeof(TDeviceMode) * NumModes);
FillChar(lpDmArray^, sizeof(TDeviceMode) * NumModes, #0);
{$IFOPT R+}
{$DEFINE CKRANGE}
{$R-}
{$ENDIF}
for I := 0 to (NumModes - 1) do
EnumDisplaySettings(nil, I, lpDmArray[i]);
{$IFDEF CKRANGE}
{$UNDEF CKRANGE}
{$R+}
{$ENDIF}
end;
procedure TForm1.ButtonRetrieveDisplayModesClick(Sender: TObject);
begin
RetrieveDisplayModes;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
try
FreeMem(lpDmArray, sizeof(TDeviceMode) * NumModes);
except
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
DC: hDC;
begin
DC := GetDC(0);
BitsPerPixel := GetDeviceCaps(DC, BITSPIXEL);
RefreshRate := GetDeviceCaps(DC, VREFRESH);
ReleaseDC(0, DC);
StatusBar.Panels[2].Text := 'Resolution: ' + IntToStr(Screen.Width) + ' * ' +
IntToStr(Screen.Height)
+ ', ColorDept: ' + IntToStr(BitsPerPixel) + ', RefreshRate: '
+ IntToStr(RefreshRate);
ButtonRetrieveDisplayModesClick(Sender);
end;
procedure Tform1.SetDisplayMode(Mode: integer);
var
ReturnVal: LongInt;
begin
{$IFOPT R+}
{$DEFINE CKRANGE}
{$R-}
{$ENDIF}
ReturnVal := ChangeDisplaySettings(lpDmArray[Mode], CDS_UPDATEREGISTRY);
{$IFDEF CKRANGE}
{$UNDEF CKRANGE}
{$R+}
{$ENDIF}
if ReturnVal <> DISP_CHANGE_SUCCESSFUL then
case ReturnVal of
DISP_CHANGE_SUCCESSFUL: ShowMessage('DISP_CHANGE_SUCCESSFUL');
DISP_CHANGE_RESTART: ShowMessage('DISP_CHANGE_RESTART');
DISP_CHANGE_BADFLAGS: ShowMessage('DISP_CHANGE_BADFLAGS');
DISP_CHANGE_FAILED: ShowMessage('DISP_CHANGE_FAILED');
DISP_CHANGE_BADMODE: ShowMessage('DISP_CHANGE_BADMODE');
DISP_CHANGE_NOTUPDATED: ShowMessage('DISP_CHANGE_NOTUPDATED');
end;
end;
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése