Archive: nsDialogs, NSD_CreateBitmap, NSD_SetImage - JPEG support?


nsDialogs, NSD_CreateBitmap, NSD_SetImage - JPEG support?
Okay, I just ran into a bit of a stumbling block upgrading to the latest-and-greatest NSIS; using InstallOptionsEx has a drop-in no longer works when using MUI. I can work around it by using an older MUI header file, but I realize that eventually I'll have to move even this mammoth script over to nsDialogs.

However, that presents the next stumbling block.. I tried setting a JPG as a bitmap's image in the past and just again now and... I don't get any image. If I specify a BMP, things are fine.
What am I missing? Is there any way - no matter how contrived - to use a JPG directly for an nsDialogs bitmap control?

We're using JPEG files not just within the installer to cut down on size, but also for downloaded content.

I did think this was covered in the forums before, but I couldn't find anything among the noise in a search for the two rather common keywords.


You could probably replace the LoadImage call in nsDialogs.nsh with a call to OleLoadPicturePath and then get the image handle from the interface this function returns.


hehe.. well the "you" part in there is putting a lot of (misplaced) confidence in me - but I'll have a peek through MSDN and the System docs :)


This may help http://nsis.sourceforge.net/Embedded_Banner
You can also search for jpeg on NSIS main page http://nsis.sourceforge.net/Main_Page


yeah, unfortunately the various banner/etc. plugins all have their sets of limitations.. e.g.
- not within a dialog
- fixed place within a dialog
- not clickable

All I really need is basically what kichik wrote... which I *think* I can figure out... except I'm stuck (at least) at...

riid (in parameter) Reference to the identifier of the interface describing the type of interface pointer to return in ppvRet.

...which I mostly see as using 'IID_IPicture' in examples - but where on earth that particular ID is coming from.. *puzzles*

IID_IPicture is a guid, {7BF80980-BF32-101A-8BBB-00AA00300CAB} i think, so:

g "{7BF80980-BF32-101A-8BBB-00AA00300CAB}", and the pointer to the COM object param should look something like: *i .r0

Remember when working with COM objects, you need to figure out the correct offset in the vtable when calling methods on COM objects


see http://source.winehq.org/source/incl...dole2.idl#L303 ...and remember, 0,1 and 2 are IUnknown, so the first method in IPicture is 3 (The system.dll readme has example code for calling COM objects)


whhooooo... blimey. Nope, in way over my head - will give it another stab after the weekend :)
( getting an error 128 from the output of the 'e' option... of course finding the user-friendly message for code 128 is another circle of hell altogether )


128=ERROR_WAIT_NO_CHILDREN and that makes no sense, maybe you should post some of your code


You can use err.exe to get information on pretty much every error code in Windows.


Originally posted by kichik
You can use err.exe to get information on pretty much every error code in Windows.
except its 404

got off the vpn, but if I recall correctly - and yes, I know it's utterly wrong... even if I'm remembering and piecing this together right...


System::Call 'oleaut32::OleLoadPicturePath("path to bmp file", , , ,g "long guid thing", *i .r0) i.r1 ? e'


which I think means...
using the System plugin's Call routine,
make a call to from oleaut32.dll's OleLoadPicturePath procedure
with the arguments...
- path or URL to the file
- null
- null
- null
- the guid
- create a new 'pointer' which will hold the result, stick the pointer in $0
- stick the result of the call itself in $1
- get any error message, stick that on the stack

====

As for that err.exe thing - sounds useful, so I googled...
http://www.microsoft.com/downloads/d...displaylang=en

( says Exchange but a MSDN blog noted that it'll do the Win32 errors as well )

you need the types for every param, t for text (or w for wide strings) and i for DWORD/pointers


cool, thanks - I'll review and try again monday :)
I guess that means I have to explicitly use 'n' for null (instead of just leaving the parameter blank) as well


no, you can do "i,i,i" without specifying the actual value, or "i0,i0,i0" to show intent


alright, just poking at this offline a bit more...

I *think* I've got the picture interface bit working, then...


System::Call 'oleaut32::OleLoadPicturePath(w "<path>", i 0, i 0, i 0, g "{7BF80980-BF32-101A-8BBB-00AA00300CAB}", *i .r0) i .r1 ? e'

It returns a pointer/reference/thing to the interface, the result is zero (which I think means 'ok') and no error code is returned (well, also zero).

So now would come the time to get some data out of that interface. Instead of jumping straight into the deep that is the image handle, I figured I'd get the width of the bitmap first.

However, I then of course get stuck again :)

System::Call '$0->6(i .r0) i .r1 ? e'

6 = getWidth, as far as the VTable is concerned;
http://msdn.microsoft.com/en-us/library/ms680761(VS.85).aspx
At first I thought I was supposed to just call it as '->6()' and thus have the result in $1 . That crashes, though. However, specifying an out variable (i.r3) as a parameter doesn't do much either;

System::Call '$0->6(i .r3) i .r1 ? e' ; 6 = getWidth
Pop $2
; [$3][$1][$2] = [0][-2147467261][80]

Of course, that error code ($2 - 80) doesn't make sense.. again. But I might be reading err.exe's output wrong.

Anyway, I tried ::Get as well, but that got me an error DMLERRsomethingorother ..

I'll poke at it some more later -_-

the argument is a pointer to a OLE_XSIZE_HIMETRIC (whatever that is, lets hope its 4 bytes) so:

System::Call '$0->6(*i.r3)i.r1'

also, you can't use ?e with COM, you must check the return value, 0 = ok (in most cases, could be 1 (S_FALSE) also, negative numbers are errors, when you see them in the output from err.exe, they are the codes starting with S_ or E_ )


Function pre
nsDialogs::Create 1018
Pop $0
${NSD_CreateBitmap} 0 0 100% 100% ""
pop $9

!define IID_IPicture {7BF80980-BF32-101A-8BBB-00AA00300CAB}
!define ImagePath "$PICTURES\BuddyJesus.jpg"
var /GLOBAL pIPicture1 ;lets save it in a var so some other code does not overwrite it (I'm assuming you have a complicated page with lots of code)
System::Call 'oleaut32::OleLoadPicturePath(w "${ImagePath}", i 0, i 0, i 0, g "${IID_IPicture}", *i .r0)i.r1'
${If} $1 == 0
StrCpy $pIPicture1 $0 ;save pointer for later, we can't release it now because the image handle needs to stay valid
System::Call "$0->3(*i.r0)i.r1" ;IPicture->get_Handle
;might want to check $1 here before setting image
SendMessage $9 ${STM_SETIMAGE} ${IMAGE_BITMAP} $0
${EndIf}

nsDialogs::Show
${IfThen} $pIPicture1 <> 0 ${|} System::Call "$pIPicture1->2()" ${|} ;Release

FunctionEnd

page custom pre


if you need to resize the actual image control to fit the image, you need to call width and height and convert from himetric to pixels, I'm sure google can help out

Thanks!

Nope - don't think I would've gotten that far on monday - maybe on wednesday. I did get to the 'oh, dur, it's not a number' point *pats self on back*. I'll be going through your changes and try to grok it.. gotta get a handle on the belly of this (powerful) beast.

Thanks again!


Alright - spent some time sunday to turn it into a header file, it's in the wiki (along with a new nsDialogs category), stuck it in the production script and voila... works beautifully - thanks again!


Thanks for creating the nsDialogs category. It was really long due. All those other examples are really useful too.


Originally posted by kichik
Thanks for creating the nsDialogs category. It was really long due. All those other examples are really useful too.
No problem - we've been using NSIS for our installer for several years now and I like to contribute back wherever I can.

I just added a new page with some more minor snippets and created a some topics for a few other bits, that I hope will be helpful to other (budding) nsDialogs users;
http://nsis.sourceforge.net/NsDialogs_FAQ

I don't know for sure these are FAQ items per se, but they were things that I ran into or simply wondered about while moving over to nsDialogs.

Have to move on to some file-finding bits and pieces now, though, but part of that will involve nsDialogs again - will post the result of that as well.

Originally posted by Animaether
got off the vpn, but if I recall correctly - and yes, I know it's utterly wrong... even if I'm remembering and piecing this together right...


System::Call 'oleaut32::OleLoadPicturePath("path to bmp file", , , ,g "long guid thing", *i .r0) i.r1 ? e'


which I think means...
using the System plugin's Call routine,
make a call to from oleaut32.dll's OleLoadPicturePath procedure
with the arguments...
- path or URL to the file
- null
- null
- null
- the guid
- create a new 'pointer' which will hold the result, stick the pointer in $0
- stick the result of the call itself in $1
- get any error message, stick that on the stack

====


Thanks a lot for the nice piece of code, it helped me a lot

however I was wondering how do I add border to the image?

Regards

Quote:


You could also just add SS_BLACKFRAME, SS_WHITEFRAME or SS_GRAYFRAME to the style.

Stu


Originally posted by Afrow UK
You could also just add SS_BLACKFRAME, SS_WHITEFRAME or SS_GRAYFRAME to the style.
No, I think these will replace the content of the static/ control with a simple (filled) rectangle.

You should rather add the WS_BORDER style

Here is the solution published special for this THREAD.

http://nsis.sourceforge.net/NsDialogs_SetImageOLE



Originally Posted by zirnevis (Post 2679252) however I was wondering how do I add border to the image? Using an image editor such as Paint?