Archive: Make window small while copying?


Make window small while copying?
Is there any way to make the installer window small/smaller while it's copying, and/or move it into a corner, so that users can see the splash screens/screenshots I am displaying in the background while they are waiting?
-jimb
Cryptic Studios
www.cityofheroes.com


You can reposition the installer using this code:

System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) b ($HWNDPARENT, 0, 5, 5, 0, 0, 0x201)"
This code repositions the installer 5 pixels lower and 5 pixels to the right of the top left hand corner. I'm not certain of this but I think that it might be possible to resize the installer window using this function aswell although I would not recommend it.

Vytautas :D

Thanks! I'll try that. The installer is still sorta big... can I use the ChangeUI directive to create a new dialog resource that is a much smaller window, perhaps with only a progress bar visible?


Well... for a start, here's what I wrote to move the installer to the lower left or lower right of the screen:

Function repositionWindow

; Reposition window
; Create RECT struct
; create WIN32_FIND_DATA struct
System::Call '*${stRECT} .r1'
StrCpy $R1 0
; Find Window info
System::Call 'User32::GetWindowRect(i, i) i ($HWNDPARENT, r1) .r2'
; Get left/top/right/bottom
System::Call '*$1${stRECT} (.r2, .r3, .r4, .r5)'
System::Free $1

; MessageBox MB_OK "Got $2 $3 $4 $5"
!define SM_CXSCREEN 0
!define SM_CYSCREEN 1
System::Call "User32::GetSystemMetrics(i) i (${SM_CXSCREEN} ) .r0"
System::Call "User32::GetSystemMetrics(i) i (${SM_CYSCREEN} ) .r1"
; MessageBox MB_OK "Got $0 $1"

; Width of screen - window - 10
IntOp $2 $4 - $2
IntOp $0 $0 - $2
IntOp $0 $0 - 10
; Height of screen - window - 10
IntOp $3 $5 - $3
IntOp $1 $1 - $3
IntOp $1 $1 - 10

System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) b ($HWNDPARENT, 0, 10, $1, 0, 0, 0x201)"

FunctionEnd

That works quite well except for one problem. It assumes that the TaskBar is at the bottom of the screen and is only one bar high. On my system it two bars high and the NSIS buttons get hidden behind it. Also if the taskbar was on one of the sides it would also move the installer to a wrong place.

I'm not sure which API call you would use but in Delphi you can attain the client area of the screen which does not include the taskbar thus this problem does not occur.

Another way would be to get the position & size of the TaskBar and take that into consideration when working out the position.

Vytautas


Ah! Forgot about that, thanks! I'll call the appropriate GetSystemMetrics and fix it. On my system I don't even have a taskbar on my primary monitor, so I completely forgot about that =).

Looks like the correct call is SystemParametersInfo(SPI_GETWORKAREA, 0, PRECT, 0). I'll post the final version tomorrow when I get around to finishing it.


Well, looks like the BgImage plugin hides the taskbar anyway, so I'm going to leave it at the lower left corner while it is copying files. I'll have to give resizing the window a shot, because when you've got pretty screens in the background, the big installer is sorta annoying (I'm using the MUI interface, maybe I should have stuck with the default little one ;).


Turns out BgImage only obscures the TaskBar on WinXP, and once the bgimage goes away, the task bar pops up to obscure the installer once again. So, here's my final code that gets the work area and places the window in the lower left or lower right of the screen:


Function repositionWindow

; !define SPI_GETWORKAREA 0x0030

; Reposition window in the lower left
; Create RECT struct
System::Call "*${stRECT} .r1"
; Find Window info for the window we're displaying
System::Call "User32::GetWindowRect(i, i) i ($HWNDPARENT, r1) .r2"
; Get left/top/right/bottom
System::Call "*$1${stRECT} (.r2, .r3, .r4, .r5)"

; Calculate width/height of our window
IntOp $2 $4 - $2 ; $2 now contains the width
IntOp $3 $5 - $3 ; $3 now contains the height

; Determine the screen work area
System::Call "User32::SystemParametersInfo(i, i, i, i) i (${SPI_GETWORKAREA}, 0, r1, 0) .r4"
; Get left/top/right/bottom
System::Call "*$1${stRECT} (.r4, .r5, .r6, .r7)"

System::Free $1

; Right side of screen - window - 10
;IntOp $0 $6 - $2
;IntOp $0 $0 - 10
; Left side of screen + 10
IntOp $0 $4 + 10

; Bottom of screen - window - 5
IntOp $1 $7 - $3
IntOp $1 $1 - 5

System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) b ($HWNDPARENT, 0, $0, $1, 0, 0, 0x201)"

FunctionEnd

Can you create an Archive page for this code?


put window back
Thanks a lot for this tip - it works great!

Now.. How can I recenter the window after sticking it in the corner?


Use the code above, but instead of using the corner values you will need to use ((right side / 2) - (width / 2)) and similar for the other attribute.

Hope this helps you out.
Vytautas


Thanks for the quick reply.. but can I ask you to be more specific? Sorry, I'm not very good at programming..


Try this code, (not tested but should work):

Function repositionWindow

; !define SPI_GETWORKAREA 0x0030

; Reposition window in the lower left
; Create RECT struct
System::Call "*${stRECT} .r1"
; Find Window info for the window we're displaying
System::Call "User32::GetWindowRect(i, i) i ($HWNDPARENT, r1) .r2"
; Get left/top/right/bottom
System::Call "*$1${stRECT} (.r2, .r3, .r4, .r5)"

; Calculate width/height of our window
IntOp $2 $4 - $2 ; $2 now contains the width
IntOp $3 $5 - $3 ; $3 now contains the height

; Determine the screen work area
System::Call "User32::SystemParametersInfo(i, i, i, i) i (${SPI_GETWORKAREA}, 0, r1, 0) .r4"
; Get left/top/right/bottom
System::Call "*$1${stRECT} (.r4, .r5, .r6, .r7)"

System::Free $1

; (Right side of screen / 2) - (window / 2)
IntOp $0 $6 / 2
IntOp $8 $2 / 2
IntOp $0 $0 - $8

; (Bottom of screen / 2) - (window / 2)
IntOp $1 $7 / 2
IntOp $8 $3 / 2
IntOp $1 $1 - $8

System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) b ($HWNDPARENT, 0, $0, $1, 0, 0, 0x201)"

FunctionEnd

Vytautas

sweet! It works perfectly. Thank you very much-


To get it back in the middle again, it might be easier to just store the position of the window from before you moved it to the corner and then restore to that position.

Remco


Yes you could do that but then you would have to either create two new variables for this task, which would waiste memmory, or use existing variables which could not be used for other purposes.

Vytautas