2014-09-29 2 views
2

그래서 델파이 프로그램은 DPI를 인식하지 못합니다. 고화질 DPI가있는 컴퓨터에서 실제 화면 해상도 (Wrong resolution reported by Screen.Width when "Make it easier to read what's on screen" is 150%)가 필요할 때까지는별로 신경 쓰지 않았습니다. 권장 사항 중 하나는 응용 프로그램을 높은 DPI 인식 (XML 매니페스트)으로 만드는 것이지만 다른 사람들은 이것이 많은 작업을 필요로한다고 경고합니다! 그래서, 게으르다는 (또는 시간이 부족한), 진짜 해상도를 계산하는 트릭이 있는지 궁금합니다.높은 DPI 시스템에서 실제 화면 해상도를 얻는 방법은 무엇입니까?

DPI를 인식 할 수있는 컴패니언 도구 (소형 콘솔 앱)를 만드는 것이 매우 위험한 트릭입니다. 내가해야 할 일은이 도구를 호출하고 그 도구에서 실제 해상도를 얻는 것입니다. 꽤 스파르타하지만 작동해야합니다. 어쨌든, 그것을 할 수있는 더 좋은 방법이 있어야합니다!

답변

4

Win32_DesktopMonitor WMI 클래스가 정보를 산출합니다. 여기에서 가져온 코드를 사용하여 예를 들어

: Delphi7: Get attached monitor properties

{$APPTYPE CONSOLE} 

uses 
    SysUtils, 
    ActiveX, 
    ComObj, 
    Variants; 

function VarStrNull(VarStr: OleVariant): string; 
// dummy function to handle null variants 
begin 
    Result := ''; 
    if not VarIsNull(VarStr) then 
    Result := VarToStr(VarStr); 
end; 

procedure GetMonitorInfo; 
var 
    objWMIService: OleVariant; 
    colItems: OleVariant; 
    colItem: OleVariant; 
    oEnum: IEnumvariant; 
    iValue: LongWord; 

    function GetWMIObject(const objectName: String): IDispatch; 
    var 
    chEaten: Integer; 
    BindCtx: IBindCtx; 
    Moniker: IMoniker; 
    begin 
    OleCheck(CreateBindCtx(0, BindCtx)); 
    OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, 
     Moniker)); 
    OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result)); 
    end; 

begin 
    objWMIService := GetWMIObject('winmgmts:\\localhost\root\CIMV2'); 
    colItems := objWMIService.ExecQuery 
    ('SELECT * FROM Win32_DesktopMonitor', 'WQL', 0); 
    oEnum := IUnknown(colItems._NewEnum) as IEnumvariant; 
    while oEnum.Next(1, colItem, iValue) = 0 do 
    begin 
    Writeln('Caption  ' + VarStrNull(colItem.Caption)); 
    Writeln('Device ID ' + VarStrNull(colItem.DeviceID)); 
    Writeln('Width  ' + VarStrNull(colItem.ScreenWidth)); 
    Writeln('Height  ' + VarStrNull(colItem.ScreenHeight)); 
    Writeln; 
    end; 
end; 

begin 
    try 
    CoInitialize(nil); 
    try 
     GetMonitorInfo; 
     Readln; 
    finally 
     CoUninitialize; 
    end; 
    except 
    on E: Exception do 
    begin 
     Writeln(E.Classname, ': ', E.Message); 
     Readln; 
    end; 
    end; 
end. 

WMI를 사용할 수없는 어떤 이유로 다음 작업을 수행하기 위해 별도의 DPI 인식 과정이 필요합니다. 어떤 IPC도 수반 될 것입니다.

또 다른 문제점은 최근 버전의 Windows가 이러한 WMI 클래스의 동작을 변경했기 때문입니다. 다른 WMI 쿼리를 사용해야 할 수도 있습니다. 참조 : https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/138d387c-b222-4c9f-b3bb-c69ee890491c/problem-with-win32desktopmonitor-in-windows-8-platform?forum=windowsgeneraldevelopmentissues

+0

멋진 솔루션처럼 들립니다. 불행히도 일부 컴퓨터에서는 사용할 수 없었던 WMI 사용 경험이 좋지 않았습니다. 내 프로그램은 일부 WMI 기능 이전에 사용되었습니다. 나는 그들을 결국 제거해야했다. Google에서 'WMI를 사용할 수 없음'을 검색하면 많은 보고서가 표시됩니다. – Ampere

+0

@ davidhefferman- WMI와 관련된 많은 오류가있는 이유를 알고 있습니다. WMI는 서비스이고 일부 시스템에서는 기본적으로 켜져 있지 않습니다 !!!!! https://www.youtube.com/watch?v=JgsHfc-4TUE – Ampere

+0

WMI에 대한 내 경험에 차임을하지 않습니다. –

관련 문제