- NSIS Discussion
- nsDialogs, NSD_CreateBitmap, NSD_SetImage - JPEG support?
Archive: nsDialogs, NSD_CreateBitmap, NSD_SetImage - JPEG support?
Animaether
6th February 2009 10:34 UTC
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.
kichik
6th February 2009 14:17 UTC
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.
Animaether
6th February 2009 15:28 UTC
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 :)
Takhir
6th February 2009 16:18 UTC
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
Animaether
6th February 2009 16:51 UTC
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*
Anders
6th February 2009 17:09 UTC
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
Anders
6th February 2009 17:21 UTC
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)
Animaether
6th February 2009 19:06 UTC
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 )
Anders
6th February 2009 19:22 UTC
128=ERROR_WAIT_NO_CHILDREN and that makes no sense, maybe you should post some of your code
kichik
6th February 2009 19:26 UTC
You can use err.exe to get information on pretty much every error code in Windows.
Anders
6th February 2009 19:37 UTC
Originally posted by kichik
You can use err.exe to get information on pretty much every error code in Windows.
except its 404
Animaether
6th February 2009 19:43 UTC
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 )
Anders
6th February 2009 19:52 UTC
you need the types for every param, t for text (or w for wide strings) and i for DWORD/pointers
Animaether
7th February 2009 08:41 UTC
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
Anders
7th February 2009 14:21 UTC
no, you can do "i,i,i" without specifying the actual value, or "i0,i0,i0" to show intent
Animaether
7th February 2009 15:01 UTC
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 -_-
Anders
7th February 2009 15:09 UTC
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_ )
Anders
7th February 2009 15:26 UTC
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
Animaether
8th February 2009 11:49 UTC
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!
Animaether
9th February 2009 10:57 UTC
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!
kichik
10th February 2009 20:36 UTC
Thanks for creating the nsDialogs category. It was really long due. All those other examples are really useful too.
Animaether
14th February 2009 00:45 UTC
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.
zirnevis
11th July 2010 07:56 UTC
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
MSG
11th July 2010 12:42 UTC
Quote:
Afrow UK
11th July 2010 16:23 UTC
You could also just add SS_BLACKFRAME, SS_WHITEFRAME or SS_GRAYFRAME to the style.
Stu
Wizou
11th July 2010 18:06 UTC
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
baby123
6th January 2013 14:26 UTC
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? |