INNO Setup: How to get the primary monitor's r

2019-02-19 15:14发布

问题:

I'm trying to script an installer with INNO and I am stuck at a point where I need to get the screen resolution of the machine in which the setup is running and use that value to create a shortcut in the desktop with that resolution as one of the arguments. I know how to create a shortcut, however I do not know how to extract the screen resolution and how to pass that information (probably stored in a custom variable) to use it in the desktop shortcut.

Thanks for your time :)

EDIT: I cannot change the application because I'm not authorized to do that. So please do not suggest to do that.

回答1:

My solution to this was to use GetSystemMetrics(), which can be found in user32.dll. This piece of code gives me exactly what I want and has been tested on Windows7 Professional (64-bit) with a dual-monitor setup.

[Code]
function GetSystemMetrics (nIndex: Integer): Integer;
  external 'GetSystemMetrics@User32.dll stdcall setuponly';

Const
    SM_CXSCREEN = 0; // The enum-value for getting the width of the cient area for a full-screen window on the primary display monitor, in pixels.
    SM_CYSCREEN = 1; // The enum-value for getting the height of the client area for a full-screen window on the primary display monitor, in pixels.

function InitializeSetup(): Boolean;
  var 
      hDC: Integer;
      xres: Integer;
      yres: Integer;
begin
    xres := GetSystemMetrics(SM_CXSCREEN);
    yres := GetSystemMetrics(SM_CYSCREEN); //vertical resolution

    MsgBox( 'Current resolution is ' + IntToStr(xres) +
        'x' + IntToStr(yres)
, mbInformation, MB_OK );

    Result := true;
end;

EDIT: It seems the indices should've been SM_CXSCREEN and SM_CYSCREEN. Changed the code to reflect that.



回答2:

You'll need some code to get the current resolution. Then you can add those values to the [Icon] entry to create the shortcut. Here's some code to get you started:

[Setup]
AppName=DisplayResoltution
AppVerName=DisplayResoltution
DefaultDirName=DisplayResoltution
DisableStartupPrompt=true
Uninstallable=false

[Files]
Source: "C:\util\innosetup\Examples\MyProg.exe"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\My Program"; Filename: "{app}\MyProg.exe"; Parameters: {code:GetParams}


[Code]
// Functions to get BPP & resolution

function DeleteDC (hDC: Integer): Integer;
 external 'DeleteDC@GDI32 stdcall';

function CreateDC (lpDriverName, lpDeviceName, lpOutput: String; lpInitData: Integer): Integer;
 external 'CreateDCA@GDI32 stdcall';

function GetDeviceCaps (hDC, nIndex: Integer): Integer;
 external 'GetDeviceCaps@GDI32 stdcall';

Const
    HORZRES = 8;    //horizontal resolution
    VERTRES = 10;   //vertical resolution
    BITSPIXEL = 12; //bits per pixel
    PLANES = 14;    //number of planes (color depth=bits_per_pixel*number_of_planes)
var
xres, yres, bpp, pl, tmp: Integer;

function InitializeSetup(): Boolean;
  var 
      hDC: Integer;
begin

    //get resolution & BPP
    hDC := CreateDC('DISPLAY', '', '', 0);
    pl := GetDeviceCaps(hDC, PLANES);
    bpp := GetDeviceCaps(hDC, BITSPIXEL);
    xres := GetDeviceCaps(hDC, HORZRES); //horizontal resolution
    yres := GetDeviceCaps(hDC, VERTRES); //vertical resolution
    tmp := DeleteDC(hDC);
    bpp := pl * bpp;   //color depth

    MsgBox( 'Current resolution is ' + IntToStr(xres) +
        'x' + IntToStr(yres) +
        ' and color depth is ' + IntToStr( bpp )
        , mbInformation, MB_OK );

    Result := true;
end;

function GetParams(def: string): string;
var
sTemp : string;
begin
  sTemp := 'xres=' + IntToStr(xres) + ' yres=' +IntToStr(yres);
  result := sTemp;
end;

Code adapted from http://www.vincenzo.net/isxkb/index.php?title=Detect_current_display_resolution_and_color_depth