News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Another little toy (barber pole)

Started by NoCforMe, January 01, 2023, 06:08:25 PM

Previous topic - Next topic

NoCforMe

So now I have a packaging problem with this project.

The problem is that the barber-pole control requires some resources, two bitmap files. I'm loading these via a resource (.rc) file that gets converted to an .obj file.

Problem #1: Now I have two files that need to be linked instead of just one. OK, fine. My first move was to look for a tool that could combine multiple object files into one. Turns out such a thing probably doesn't exist. (This was covered in this thread here a few years ago.) I did find an online tool that said it could merge OBJ files; I tried it, but the linker said the file was corrupted. So scratch that. (* See below for more info.)

OK, so I took Hutch's suggestion from that thread and created a library with the BP control code and the BP resource. Linked it.

Problem #2: That doesn't work: the control initialization code failed when it tried to load the bitmap resources ("The specified resource type cannot be found in the image file"), even though the resource was in the library. And no, I don't have anything at all in my code with the same resource IDs (400 & 401).

Alright then; so I went back to just using .obj files. I have the following files:

  • BPcontrol.obj: the control code
  • BP_resources.obj: the bitmap resources
  • BPtest.obj: the testbed program code
  • VisualStyles.obj: the magic resource that gives the less-ugly look to everything

Tried linking all 4 of those together (this is to create the demo testbed program).

Problem #3: it linked, but the linker threw a warning:

VisualStyles.obj : warning LNK4059: BP_resources.obj already specified; additional resource file ignored

So I got a working demo program, but one with ugly "old-style" buttons. Yuck. It looks like the linker only allows you to have one single resource file per .exe? is that right? Seems like a ridiculous restriction.

So how do I package both the control code (BPcontrol.obj) and the resources it needs (BP_resources.obj) together so the user can easily include the control in their program?

I got around before this by putting the Visual Styles junk (xpmanifest.xml) into the resource file. But that's the wrong way to do it, because this resource should be put in for the final executable, not as part of the control.

Help!

p.s.: I found something in this Stack Overflow post that seems to confirm what I suspected about putting resources in a static library:

QuoteNote that you can't lib in object files created with cvtres. If multiple object files are provided, lib complains as though as multiple .res files were given; if a single object file is provided, lib does not complain, but the linker simply ignores the embedded resource data in the lib file.
Assembly language programming should be fun. That's why I do it.

biscuits

Embed the icons in .data rather than putting them in the .rc file? I don't have an example to show you, but I know that it is possible.

fearless

Quote from: NoCforMe on January 03, 2023, 12:25:51 PM
does just returning TRUE, as you suggested, do that?
Yes

And I also embed resources as static data declarations in libraries. I use Hutch's bin2db/bin2dbex (found in the masm32 install folder) to convert images to data. Then you can use something like vortex's functions to load bitmaps from memory - using the address of the static resource. I think this is the relevant post: https://masm32.com/board/index.php?topic=4642.msg49923#msg49923

biscuits

Quote from: fearless on January 03, 2023, 03:15:04 PM
And I also embed resources as static data declarations in libraries. I use Hutch's bin2db/bin2dbex (found in the masm32 install folder) to convert images to data. Then you can use something like vortex's functions to load bitmaps from memory - using the address of the static resource. I think this is the relevant post: https://masm32.com/board/index.php?topic=4642.msg49923#msg49923
Yes! Thats where I read about embedding resources in the data section. Exactly the sort of thing that I was referring to. I was going to search for this later, unil I saw your posting, fearless.

NoCforMe

#19
Our minds apparently run in the same gutters; that's exactly what I'm doing now. I was all set to write my own "DB generator" when I realized there's one in the MASM tools folder. I'm converting the BMPs to DBs (not that big, doable), then using CreateBitmapIndirect() to "open" them.

Screw the resource compiler anyhow.
Assembly language programming should be fun. That's why I do it.

hutch--

Its actually a good technique if you want to make resources much harder to find as you cannot just acces the resource with a resource hacker.

If security is not the issue, you can embed resources in the resource section with the following.

20 RCDATA "toolbar.png"

NoCforMe

Hutch, did you read my post above? I can't use resources with a library at all; just doesn't work. (The library says it puts them in the .obj but it doesn't.)

And I can't have more than one resource file for the .exe, so the .exe builder can't use any resources either. So I'm stuck doing things this way.

Are you talking about putting 20 RCDATA "toolbar.png" in an .rc file and converting it? That won't work for me for the reasons I gave above. Unless I'm missing something here.
Assembly language programming should be fun. That's why I do it.

hutch--

The DB format works fine in a library module, I added the comments about 20 RCDATA "toolbar.png" as not everyone knows how to use it.

Strangely enough, there is good reason why I produced the tool to convert either data or code to DB format, I am pleased you have found one of them.  :biggrin:

NoCforMe

"The DB format works fine in a library module". What do you mean? In an .asm file, right? but one that's going to get put into a library? I already told you: I cannot use a library here.
Assembly language programming should be fun. That's why I do it.

hutch--

 :biggrin:

The basics are, if you can read a DB format block ANYWHERE in code, it will work, in an EXE, DLL, Library module or even as a remote file, its just bytes. I have missed what your compliants is here.  :rolleyes:

NoCforMe

Well, OK. Moving on here: I've encoded both bitmaps as data (DBs), and have a loader coded for them which (apparently) loads successfully, using CreateBitmapIndirect(). At least it gives back a handle and not an error. But the bitmaps don't render at all, so now I'm in the swamp: am I working with DDBs here? or DIBs? top-down? bottom-up?

First strange thing is that I produced both bitmaps with the same tool (Paint Shop Pro), yet they have different headers: one uses the BITMAPCORHEADER format, while the other uses the BITMAPINFOHEADER format. So I have code to handle both formats. But how do I know whether I'm creating a DDB or a DIB?

The bitmap stuff in GDI makes my head hurt ...
Assembly language programming should be fun. That's why I do it.

hutch--

If you can tolerate quirky work arounds, write the DB data to a temp file then load it as an external file.

jj2007

Quote from: NoCforMe on January 03, 2023, 12:57:19 PM
So now I have a packaging problem with this project.

The problem is that the barber-pole control requires some resources, two bitmap files. I'm loading these via a resource (.rc) file that gets converted to an .obj file.
...
p.s.: I found something in this Stack Overflow post that seems to confirm what I suspected about putting resources in a static library:

QuoteNote that you can't lib in object files created with cvtres. If multiple object files are provided, lib complains as though as multiple .res files were given; if a single object file is provided, lib does not complain, but the linker simply ignores the embedded resource data in the lib file.

From the same SOF post:

QuoteThe only thing you need to do to use resources (images, dialogs, etc...) in a static library in Visual C++ (2008), is include the static library's associated .res file in your project. This can be done at "Project settings/Linker/Input/Additional dependencies".

With this solution, the resources of the static library are packed into the .exe, so you don't need an extra DLL. Regrettably, Visual Studio does not include the .res file automatically as it does for the .lib file (when using the "project dependencies"-feature), but I think this small extra step is acceptable.

I have looked for a very long time for this solution, and now it surprises me it is that simple. The only problem is that it is totally undocumented.

It is an interesting problem, and I wonder whether polib has a solution for assembler programmers :cool:

fearless

Actually I got the wrong function and post. It was Vortex though, and it was his CreateBmpFromMem function: http://www.masmforum.com/board/index.php?topic=16267.msg134453#msg134453

I adapted it slightly to create a version that doesn't require the hWin param as it creates a DC to use to create the bitmap and return that bitmap handle:
https://github.com/mrfearless/ModernUI/blob/master/ModernUI/MUICreateBitmapFromMemory.asm

And I adapted a CreateIconFromData function from Donkey as well: http://www.masmforum.com/board/index.php?topic=16267.msg134434#msg134434
https://github.com/mrfearless/ModernUI/blob/master/ModernUI/MUICreateIconFromMemory.asm


I use that function in the checkbox control to load the static icons that are stored in https://github.com/mrfearless/ModernUI/blob/dd20260d03bc0be68cd8921eced697a83442d6b4/Controls/ModernUI_Checkbox/ModernUI_Checkbox_Icons.asm

https://github.com/mrfearless/ModernUI/blob/dd20260d03bc0be68cd8921eced697a83442d6b4/Controls/ModernUI_Checkbox/ModernUI_Checkbox.asm#L600

fearless

Also it occurred to me that the barber pole bitmaps could be made smaller and used with CreatePatternBrush (https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createpatternbrush) to paint that image / fill the control with that image. You can also use it with PatBlt function.

You could also do one barberpole bitmap each for vertical or horizontal and depending on orientation of control as specified by some property or message or custom style on creation you can switch brushes and fill the control with the proper image.