aerDNA
25th January 2012 01:00 UTC
Displaying a created window before installer displays anything?
It's a stupid title but I didn't know how to put it. I want to create a window as a child of a window from another process (static using CreateWindowEx, LoadImage etc.) and basically I succeeded but the problem is that it doesn't appear if my installer hasn't displayed any windows of its own yet, although my created window has 'external' parent, e.g. it will appear after I first display a Msgbox. I'm sure that folks here will know why that is and if there's a solution. Sorry if I didn't make my question clear enough.
T.Slappy
25th January 2012 08:44 UTC
Try .onInit or .onGUIInit functions: they are called before real installer is shown.
aerDNA
25th January 2012 10:51 UTC
I am using .onGUIInit, that's exactly the problem. I'll have to post some code to explain what i mean.
aerDNA
25th January 2012 21:14 UTC
Here. I have also attached this script, together with a test bitmap.
# This example uses the screensaver preview window as target.
OutFile "C:\WINDOWS\System32\PreviewTest.scr"
Name "PreviewTest"
Caption "PreviewTest"
RequestExecutionLevel User
!include "FileFunc.nsh"
!define WS_CHILD 0x40000000
!define WS_VISIBLE 0x10000000
!define SS_BITMAP 0x0000000EL
!define IMAGE_BITMAP 0
!define LR_LOADFROMFILE 0x0010
!define STM_SETIMAGE 0x0172
Function .onGUIInit
# When a screensaver is selected from the dropdown list, windows runs it with /p #### switch, passing it hwnd of the preview window.
${GetParameters} $R0
${GetOptions} "$R0" "/P" $R1 # R1=HWND of preview window
IfErrors 0 Preview
Exec 'Rundll32.exe shell32.dll,Control_RunDLL Desk.cpl,@0, 1'
Abort
Preview:
System::Call '*(&i4,&i4,&i4,&i4) i .r0' # RECT structure
System::Call 'user32::GetWindowRect(i R1, i r0) i.'
System::Call '*$0(&i4,&i4,&i4,&i4)i(.r1,.r2,.r3,.r4)'
System::Free $0
IntOp $1 $3 - $1 # x = right - left
IntOp $2 $4 - $2 # y = bottom - top
System::Call "user32::CreateWindowEx(i 0, t 'STATIC', t 'Preview', i '${WS_CHILD}|${WS_VISIBLE}|${SS_BITMAP}', i 0, i 0, i r1, i r2, i R1, i 0, i 0, i 0) i. R2"
IntCmp $R2 0 PreviewEnd
File /oname=$PLUGINSDIR\Test.bmp ".\Test.bmp"
System::Call "user32::LoadImage(i 0, t '$PLUGINSDIR\Test.bmp', i ${IMAGE_BITMAP}, i 0, i 0, i ${LR_LOADFROMFILE}) i. R3"
System::Call "user32::SendMessage(i R2, i ${STM_SETIMAGE}, i ${IMAGE_BITMAP}, i R3) i."
# Here's the problem: bitmap will not appear in the preview window until the msgbox is displayed.
# What can I do to change that?
Sleep 2000
MessageBox MB_OK|MB_USERICON "Test bitmap should be visible now."
PreviewEnd:
Abort
FunctionEnd
Section "Blank"
SectionEnd
Anders
25th January 2012 23:19 UTC
A window created with CreateWindowEx or CreateDialog (but not DialogBox) needs to process messages for the window to work correctly, so you either have to call GetMessage+DispatchMessage in a loop with the system plugin or create the window and then hide the nsis window in the pre/show callback of your first page so nsis pumps messages for you.
Have you thought about programming this in a "real" language or AutoIt?
aerDNA
26th January 2012 00:45 UTC
Thanks for a traditionally informative reply. I'll see what I can do about message processing. I'm aware nsis wasn't designed for these purposes. I first started using it when I needed to make an installer but then I realized it had possibilities beyond that. I started playing with it and using it to create small programs. I never found the will to move forward and learn a 'real' language, I always managed to find a way to achieve what I needed in nsis but of course I was bound to hit a wall sooner or later.
Anders
26th January 2012 06:05 UTC
If you came up with and/or understand the code you posted you are not that far away from coding win32 apps in C (Dealing with RECTs (and structs in general) is actually harder in NSIS)
There are several free options for you: mingw+codeblocks, the free visual studio from MS (The 2003 version can still be found online). Coding in c# can be done on any install of windows with dotnet installed (+notepad) http://www.youtube.com/watch?v=jr1XhCZJoEM
Afrow UK
26th January 2012 11:15 UTC
I would recommend C# as an excellent language to begin to learn real programming. You can download Visual Studio 2010 C# Express for free. You can always then branch to C/C++ if the requirement arises (note that C++ Express does not support 64-bit development which is lame).
Stu
aerDNA
26th January 2012 12:18 UTC
I did learn quite a lot about WinAPI fiddling with System plugin. Thanks for advice and encouragement, I really should get into this C# thing but don't be surprised if I turn up with another 'exotic' nsis question. :)
aerDNA
26th January 2012 15:02 UTC
GetMessage+DispatchMessage loop works. :up: