Archive: InstallOptions fields "move" with different DPIs


InstallOptions fields "move" with different DPIs
I've set up a page with InstallOptions.dll to involve some paragraphs of text with links embedded right in the middle of them, like you see all over the web.

I did it by placing the paragraph in full as a label, then positioning a link field of *just* the right size and position to cover up the word that it is "turning into" a link.

Problem is, even though the docs for IO.dll say that it handles different DPI settings, it doesn't.

I've attached a file that contains an installer script based on the example included with NSIS, and screenshots of the resulting executable running at 96 and 120 dpi. In 120, the word "link" is off to the left of where it should be, though the position is perfect at the (default) 96 dpi.

I've searched the forum for just "DPI" and can only find it mentioned in passing. Am I doing something wrong? Can I fix this?


It handles different DPIs by using dialog units for sizes instead of pixels. This way, when you switch to another DPI, you don't have to recalculate how many pixels you need. However, this calculation is not good enough to aim at exactly one letter out a complete sentence as a dialog unit or even a pixel doesn't have a high enough resolution.

You can calculate the exact location with GetTextExtentPoint32.

!insertmacro MUI_INSTALLOPTIONS_INITDIALOG "ioA.ini"
Pop $7

!insertmacro MUI_INSTALLOPTIONS_READ $8 "ioA.ini" "Field 1" "HWND"
!insertmacro MUI_INSTALLOPTIONS_READ $9 "ioA.ini" "Field 3" "HWND"

System::Call user32::GetDC(ir9)i.r0

SendMessage $9 ${WM_GETFONT} 0 0 $1
System::Call gdi32::SelectObject(ir0,ir1)

StrCpy $1 "link"
StrLen $2 $1
System::Call gdi32::GetTextExtentPoint32(ir0,tr1,ir2,*l.r1)
System::Int64Op $1 >> 32
System::Int64Op $1 & 0xffffffff

StrCpy $1 "This is a long line with a "
StrLen $2 $1
System::Call gdi32::GetTextExtentPoint32(ir0,tr1,ir2,*l.r1)
System::Int64Op $1 & 0xffffffff
System::Call user32::MapWindowPoints(ir9,ir7,*lsr1,i1)
System::Int64Op $1 >> 32
System::Int64Op $1 & 0xffffffff

System::Call user32::ReleaseDC(ir0)

System::Call user32::MoveWindow(ir8,is,is,is,is,i1)

!insertmacro MUI_INSTALLOPTIONS_SHOW

Thank you very much kichik!