How to retrieve and change display settings (Views: 300)
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; |