December 12, 2019, 02:05:23 am

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


DLL creation

Started by Brian, September 05, 2018, 05:28:49 am

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Brian

Hi,

I wonder if anyone knows how to create a DLL containing multiple images? I have just had a run-through with the sample DLL code, and it worked OK, but I don't know how to add images, and then retrieve them for use in an IWB program. Any ideas, anyone?

Brian

Andy

Brian,

Can you not have a resource file and add the images into it.

Then you could add / use LarryMc's "ExtractResource" in the dll?

https://www.ionicwind.com/forums/index.php?topic=5614.msg41457#msg41457

Maybe?

Andy.


Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

LarryMc

OK, you say you can create a DLL.
set it up as a project with a .rc file
in the .rc file make an entry for each image that looks like this
Code Select
201 BITMAP "\\img\\0001.bmp"
where 201 is a unique id number and
"\\img\\0001.bmp" is the name and path to the image.

Code Select
export load_bitmap
Const IMAGE_BITMAP = 0
Declare import, LoadImageA(hinst:int, lpszName:pointer, uType:int, cxDesired:int, cyDesired:int, fuLoad:int),uint

sub load_bitmap(hint:int,imgno:int,w:int,h:int),uint
string bname
uint hBitmap2
hBitmap2=0
bname="#"+ltrim$(str$(imgno+200))
hBitmap2 = LoadImageA(hInt, bname, IMAGE_BITMAP, w,h, 0)
return hBitmap2
endsub

The above code should also be part of your dll.
This little adjustment is so that you can start calling img #1 from your program with this number scheme.

====================================
as usual your dll would go in the same folder as your app
the following line goes at the top of your app
Code Select
DECLARE "Shape2LM.dll",load_bitmap(hint:int,imgno:int,w:int,h:int),uint

then load the bitmap with a call
Code Select
uint hBitmap2=load_bitmap(hint,1,w,h)

and that's the basics
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Brian

Larry,

Excellent - that's just what I needed. Right, here we go!

Brian

Brian

Larry, I keep getting this. Followed your instructions implicitly

Compiling...
a window frame.iwb
No Errors

Linking...
IWBasic Linker v1.11 Copyright © 2011 Ionic Wind Software
Unresolved external __imp_load_bitmap
Error: C:\Users\Public\Documents\IWBasic\projects\Hairdressing\a window frame.o - Unresolved extern __imp_load_bitmap
Error(s) in linking C:\Users\Public\Documents\IWBasic\projects\Hairdressing\a window frame.exe

Brian

LarryMc

you do know that in order to compile any app that uses a call to any dll you have to create a linking library.

I assumed you did

From the main menu of the IDE select Tools/Create Import Library
When the dialog opens find the dll you created and open it.
It will create a .lib with the same name as your dll and put it in your libs folder.

Now try to compile your app.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Brian

Larry,

I confess I hadn't done that. It now compiles fine, but doesn't show anything. I really want my image values to start at 1000. My .rc lines start at "1000 BITMAP" etc. Don't see why it shouldn't work with those values

Brian

LarryMc

without seeing your actual code and how you are using the handle to the bitmap I can't offer and further suggestion as to why it isn't working for you.
as for the numbering, you're correct; 200 or 1000 it doesn't matter.

are you actually getting a handle returned when you call load_bitmap?
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Brian

September 06, 2018, 01:32:55 pm #8 Last Edit: September 06, 2018, 01:45:55 pm by Brian Pugh
No. This line: UINT hBitmap2=load_bitmap(hint,1,50,50) returns a zero

Brian

These are my files that  am compiling. Had to rename the .rc with an extension of .txt

LarryMc

I'm not seeing why it's not working.

This code came from my custom button library.

question: why did you want your images in a separate dll instead of in your app itself?  Just curious.

LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

LarryMc

also, instead of putting that long full path name in your rc file.
just make a sub folder off your source file folder called img
and then type your rc entries like this
Quote1000 BITMAP "img\\arrow.bmp"
1001 BITMAP "img\\button.bmp"
1002 BITMAP "img\\custom.bmp"
1003 BITMAP "img\\help.bmp"
1004 BITMAP "img\\inc.bmp"
1005 BITMAP "img\\incx.bmp"
1006 BITMAP "img\\zoomin.bmp"
1007 BITMAP "img\\zoominx.bmp"
1008 BITMAP "img\\zoomout.bmp"
1009 BITMAP "img\\zoomoutx.bmp"
1010 BITMAP "img\\ICexclamation.bmp"
1011 BITMAP "img\\ICinfo.bmp"
1012 BITMAP "img\\ICquestion.bmp"
1013 BITMAP "img\\ICstop.bmp"


LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

fasecero

QuoteThis line: UINT hBitmap2=load_bitmap(hint,1,50,50) returns a zero


Which hinstance are you using? If the resource is hosted in the dll you have to use the dll's hinstance.

LarryMc

getting the hint value is the line of code that is missing
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Brian

Larry and Fasecero,

Thanks for your replies. I normally do embed my graphics into the exe, but there are so many in this program. I'm up to 500kb so far, and still more to add. And I am going to shorten the path name down when I have it figured out. It's certainly a good learning exercise, anyway!

Although, how do I get the hInt value?

Brian

fasecero

Code Select
DECLARE IMPORT, GetModuleHandle ALIAS GetModuleHandleA(lpModuleName AS POINTER),INT

sub load_bitmap(imgno:int,w:int,h:int),uint
string bname
uint hBitmap2
hBitmap2=0
bname="#"+ltrim$(str$(imgno+200))
hBitmap2 = LoadImageA(GetModuleHandle(0), bname, IMAGE_BITMAP, w,h, 0)
return hBitmap2
endsub


Didn't tested the code but it should work. I remember myself a long time ago asking this same question and I think Larry told me that there was a global variable holding this value but I couldn't find that post.

Brian

Nope - recompiled, made new lib file. Still hBitmap2 returning zero, and no image shown

Might just give up on it, but I would really know how to do it!

Brian

fasecero

This was a tough one. GetModuleHandle() return the executable hinstance even when it is called from the dll, didn't know that. The code below assumes that there is a 1001 bitmap resource

Dll
Code Select

EXPORT load_bitmap
CONST IMAGE_BITMAP = 0
Declare import, LoadImageA(hint:int, lpszName:pointer, uType:int, cxDesired:int, cyDesired:int, fuLoad:int),uint
DECLARE IMPORT, GetModuleHandle ALIAS GetModuleHandleA(lpModuleName AS POINTER),INT
DECLARE IMPORT, _GetLastError ALIAS GetLastError(),INT

SUB MAKEINTRESOURCE(n as WORD),POINTER
pointer pReturn = 0
_asm
lea eax,[ebp-4]
mov ebx,[ebp+8]
mov [eax],ebx
_endasm
RETURN pReturn
endsub

EXTERN _hinstance as uint

sub load_bitmap(imgno:int,w:int,h:int),uint
RETURN LoadImageA(_hinstance, MAKEINTRESOURCE(imgno), IMAGE_BITMAP, w,h, 0)
endsub


Test
Code Select

$include "windowssdk.inc"

$use "cfImages.lib"
DECLARE "cfImages.dll",load_bitmap(imgno:int,w:int,h:int),uint

WINDOW win
INT hInt
UINT hBitmap2

OPENWINDOW win,0,0,800,600,@MINBOX|@MAXBOX|@SIZE|@NOAUTODRAW,0,"Window",&win_handler
hBitmap2=load_bitmap(1001,50,50)
setcaption win,str$(hBitmap2)
SHOWIMAGE win,hBitmap2,@IMGBITMAP,50,50,50,50

WAITUNTIL ISWINDOWCLOSED(win)
END

SUB win_handler(),INT
SELECT @MESSAGE
CASE @IDCREATE
CENTERWINDOW win
CASE @IDCLOSEWINDOW
CLOSEWINDOW win
ENDSELECT
RETURN 0
ENDSUB

fasecero

After several changes I didn't realize that I posted an alternate DLL code. For simplicity, here's Larry's original dll with the only change required being changing the hinst

Code Select

EXPORT load_bitmap
CONST IMAGE_BITMAP = 0
Declare import, LoadImageA(hint:int, lpszName:pointer, uType:int, cxDesired:int, cyDesired:int, fuLoad:int),uint
DECLARE IMPORT, GetModuleHandle ALIAS GetModuleHandleA(lpModuleName AS POINTER),INT

EXTERN _hinstance as uint

sub load_bitmap(imgno:int,w:int,h:int),uint
string bname
uint hBitmap2
hBitmap2=0
bname="#"+ltrim$(str$(imgno))
hBitmap2 = LoadImageA(_hinstance, bname, IMAGE_BITMAP, w,h, 0)
return hBitmap2
endsub

Brian

September 08, 2018, 02:15:48 am #18 Last Edit: September 08, 2018, 04:09:57 am by Brian Pugh
Fasecero,

So which one do I use? And why do we need the hash symbol? Will be trying later today

Brian

Edit: Fasecero, your first solution works! Thank you

fasecero

Yeah, sorry for the confusion. You can use either of the two.

Brian

Fasecero,

Sorry to bother you again, but I have been messing trying to make a bitmap button from your code, but with no success so far

For simplicity, I've been using Load_PNG_FromFile. Any ideas?

Brian

fasecero

I believe that SETBUTTONBITMAPS should work just fine
Code Select
SETBUTTONBITMAPS w1,BUTTON_1,Load_PNG_FromFile(...),0,0

Otherwise can you upload an example so we can see what happens?

Brian

Well, as you can see, I didn't get very far

I can display the image, but as for making it a button . . .

Brian

fasecero

Here are two different ways to create a button with an image. Unfortunately RGNFROMBITMAP requires a .bmp from file or resource (too bad it doesn't accept an HBITMAP), so I can only show you how to make square buttons.

Code Select

$include "windowssdk.inc"
$include "cfImages.inc"

WINDOW win
UINT hCake

OPENWINDOW win,0,0,640,480,@MINBOX|@MAXBOX|@SIZE,0,"PNG as button",&win_handler
SETWINDOWCOLOR win,RGB(200,255,200)

hCake=Load_PNG_FromFile(GETSTARTPATH+"birthday cake.png",100,100,0xFFC8FFC8)
SHOWIMAGE win,hCake,@IMGBITMAP,270,50,100,100

' method #1
CONST BUTTON_1 = 1
CONTROL win,@RGNBUTTON,"",105,201,104,104,0x50000000,BUTTON_1
SETBUTTONBITMAPS win, BUTTON_1, hCake, hCake, hCake

' method #2
CONST BUTTON_2 = 2
CONTROL win,@SYSBUTTON,"",265,201,104,104,0x50000000,BUTTON_2
ButtonSetImage(win, BUTTON_2, hCake)

WAITUNTIL ISWINDOWCLOSED(win)
DELETEIMAGE hCake,@IMGBITMAP
END

SUB win_handler(),INT
SELECT @MESSAGE
CASE @IDCREATE
CENTERWINDOW win
CASE @IDCLOSEWINDOW
CLOSEWINDOW win
CASE @IDCONTROL
SELECT @CONTROLID
CASE BUTTON_1
CASE& BUTTON_2
IF @NOTIFYCODE = 0
/*button clicked*/
SETCAPTION(win,"You have just clicked one button")
ENDIF
ENDSELECT
ENDSELECT
RETURN 0
ENDSUB

SUB ButtonSetImage(WINDOW w, INT id, INT image)
INT handle = GetDlgItem(w.hwnd, id)
LONG style = GetWindowLong(handle,GWL_STYLE)
style = style | BS_BITMAP
SetWindowLong(handle,GWL_STYLE,style)
_SendMessage(handle, BM_SETIMAGE, IMAGE_BITMAP, image)
_SendMessage(handle, WM_CHANGEUISTATE, MAKELONG(UIS_SET, UISF_HIDEFOCUS), 0)
ENDSUB

Brian

Fasecero,

That set me looking for a way to remove the border, and this was the best I could do. There is no border on the bottom right button, and only shows a frame when you press it. The frame disappears when you press another button. Many thanks,

Brian