Programmatically add cursor resource to Exe/Dll with UpdateResource api?

Get help with using AutoHotkey and its commands and hotkeys
gwarble
Posts: 220
Joined: 30 Sep 2013, 15:01

Programmatically add cursor resource to Exe/Dll with UpdateResource api?

30 Jun 2015, 22:51

Taking the function ReplaceIcon() (or ReplaceAhkIcon(), care of fincs and Pulover) I'm trying to create a comparable ReplaceCursor() to use UpdateResource API to add cursors to exe (or dll)

Any help greatly appreciated:

Code: [Select all] [Expand] [Download] (ReplaceCursor.ahk)GeSHi © Codebox Plus



called with something like:

Code: [Select all] [Download] GeSHi © Codebox Plus

 module := DllCall("BeginUpdateResource", "str", ExeName, "uint", 0, "ptr")
Loop, Cursors\*.cur
{
SplitPath, A_LoopFileFullPath,,,,CursorName
ReplaceCursor(module, A_LoopFileFullPath, CursorName)
}
DllCall("EndUpdateResource", "ptr", module, "uint", 0)

The equivalent ReplaceIcon() works as expected, i'm assuming i'm missing a size difference but can't figure it out
Thanks in advance
- gwarble

Edit: the changes from working function for icons include RT_CURSOR = 1, RT_GROUP_CURSOR = 12, the second byte checked for 2 for cursor instead of 1 for icon... What i can't figure out is there are 4 bytes ahead of the BITMAPINFOHEADER that are the X and Y hotspots of the cursor i need to compensate for...

Edit: some details here: http://www.skynet.ie/~caolan/publink/wi ... resfmt.txt
Cursor resources are very much like icon resources. They are formed
in groups with the components preceding the header. This header also
employs a fixed-length component index that allows random access of
the individual components. The structure of the cursor header is as
follows:

[Resource header (type = 12)]

struct CursorHeader {
WORD wReserved; // Currently zero
WORD wType; // 2 for cursors
WORD cwCount; // Number of components
WORD padding; // filler for DWORD alignment
};

The next portion is repeated for each component resource, and starts
on a DWORD boundary.

struct ResourceDirectory {
WORD wWidth;
WORD wHeight;
WORD wPlanes;
WORD wBitCount;
DWORD lBytesInRes;
WORD wNameOrdinal; // Points to component
WORD padding; // filler for DWORD alignment
};

Each cursor component is also similar to each icon component. There
is, however, one significant difference between the two: cursors
have the concept of a `hotspot' where icons do not. Here is the
component structure:

[Resource header (Type = 1)]

struct CursorComponent {
short xHotspot;
short yHotspot;
}
[Monochrome XOR mask]
[Monochrome AND mask]

These masks are bitmaps copied from the .CUR file. The main
difference from icons in this regard is that cursors do not have
color DIBs used for XOR masks like cursors. Although the bitmaps are
monochrome and do not have DIB headers or color tables, the bits are
still in DIB format with respect to alignment and direction. See the
SDK Reference for more information on DIB formats.
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
gwarble
Posts: 220
Joined: 30 Sep 2013, 15:01

Re: Programmatically add cursor resource to Exe/Dll with UpdateResource api?

08 Jul 2015, 12:21

Any of you experts have any words of wisdom or advice on what i should be researching to make sense of this?


One or more RESDIR structures immediately follow the NEWHEADER structure in the .res file. The ResCount member of the NEWHEADER structure specifies the number of RESDIR structures. Note that the RESDIR structure consists of either an ICONRESDIR structure or a CURSORDIR structure followed by the Planes, BitCount, BytesInRes, and IconCursorId members. If the RESDIR structure contains information about a cursor, the first two WORDs the resource compiler writes to the RT_CURSOR resource are the xHotSpot and yHotSpot members of the LOCALHEADER structure.


Edit: see last post for structure definitions instead
Last edited by gwarble on 08 Sep 2016, 21:39, edited 1 time in total.
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
gwarble
Posts: 220
Joined: 30 Sep 2013, 15:01

Re: Programmatically add cursor resource to Exe/Dll with UpdateResource api?

25 Jan 2016, 17:35

bumping in the hopes of some help, I still haven't figured this out
thanks
- joel
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
gwarble
Posts: 220
Joined: 30 Sep 2013, 15:01

Re: Programmatically add cursor resource to Exe/Dll with UpdateResource api?

01 Aug 2016, 16:38

this is my "tried for a year and failed" bump, anyone have any suggestions on what I should look in to?

i'd love to build my EitherMouse executable programmatically with new versions of ahk rather than mess around with Resource Hacker, but can't figure out how to add the cursors!

thanks
- joel
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
gwarble
Posts: 220
Joined: 30 Sep 2013, 15:01

Re: Programmatically add cursor resource to Exe/Dll with UpdateResource api?

08 Sep 2016, 20:10

I'm just going to add as much info as I can in the hopes someone knows what I'm doing wrong... I'll also edit out a couple bits of misinformation above (re: differing struct sizes between ico and cur)

So far, I'm keeping it integer based for simplicity, once working it should be trivial to change to named resources
I have the cursor resources enumerated, next available integer used for the cursor (or multiple images if the cursor file has them)
I get the Cursor Group resource created, pointing to the correct cursor image resources (ordinal number: in ResHacker)

but, I can't get the cursor size (width and height) to come out right in the Group resource, usually I'm getting 8224x8224 instead of 32x32 and a color depth of 1, and I think its because of the difference between cursors and icons seen here but I can't make sense of what to do about the difference (since it appears the file format and resource format both have the difference):

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus


also the cursor resource itself has the right size of 32x32 but no image...

Here's a sample script if you care to try:

Code: [Select all] [Expand] [Download] (Resource_AddCursor_Test.ahk)GeSHi © Codebox Plus



i still need to figure out how to prepend the bitmap data with the 4 bytes for hotspot x and y... and maybe i need to recreate the resource header from the data in the file format header as I'm reading now they may be different
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
gwarble
Posts: 220
Joined: 30 Sep 2013, 15:01

Re: Programmatically add cursor resource to Exe/Dll with UpdateResource api?

14 Dec 2016, 14:03

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
gwarble
Posts: 220
Joined: 30 Sep 2013, 15:01

Re: Programmatically add cursor resource to Exe/Dll with UpdateResource api?

24 Jul 2017, 19:12

Bumping this up in case any new viewers can help me out with this... I think most if not all resource types can now be read to and written from Exe's and Dll's with AHK except cursors. I would greatly appreciate any advice, tips, solutions, links, etc to help me understand what I'm missing to accomplish this.
Thanks in advance,
- joel
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
Helgef
Posts: 2483
Joined: 17 Jul 2016, 01:02
Contact:

Re: Programmatically add cursor resource to Exe/Dll with UpdateResource api?

25 Jul 2017, 07:51

Edit: I'm talking about the code in the second codebox in this post :wave:

Hello gwarble, I have minimum contribution. However, browsing the code i noticed

Code: [Select all] [Download] GeSHi © Codebox Plus

Loop, % ids._MaxIndex()

I thought it was an error, the docs says MaxIndex(), not _MaxIndex, but, it seems both are ok. Then I also noticed that ids is always emtpy, at least here on 64 bit 1.1.26.00. Maybe it doesn't matter. I don't know anything about this.
Checking a in Resource_Cursor_EnumNames() I notice that DllCall("EnumResourceNames", "ptr", hModule, "ptr", RT_CURSOR:=1, "ptr", pEnumFunc, "uint", 0) fails and sets the LastError to:

Code: [Select all] [Download] GeSHi © Codebox Plus

ERROR_RESOURCE_TYPE_NOT_FOUND
1813 (0x715)
The specified resource type cannot be found in the image file.

Good luck.


Spoiler
gwarble
Posts: 220
Joined: 30 Sep 2013, 15:01

Re: Programmatically add cursor resource to Exe/Dll with UpdateResource api?

25 Jul 2017, 14:22

Sweet, thanks Helgef!
You're right, it seems I'm not enumerating them properly and MaxIndex() is always an empty string... hmm
I will experiment further with this bit of info, thanks
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
gwarble
Posts: 220
Joined: 30 Sep 2013, 15:01

Re: Programmatically add cursor resource to Exe/Dll with UpdateResource api?

25 Jul 2017, 17:45

Alright this seems to get rid of the ERROR_RESOURCE_TYPE_NOT_FOUND error, but my MaxIndex is still 0...
It does successfully add the Cursor resource item(s) depending on how many are in the .cur file, and adds the Cursor Group resource item, but the data is wrong for the color depth/resolution:

Code: [Select all] [Download] GeSHi © Codebox Plus

12336 x 12336 (4 colors) - Ordinal name: 0
0 x 0 (1 colors) - Ordinal name: 0
while it should be

Code: [Select all] [Download] GeSHi © Codebox Plus

32 x 32 (2 colors) - Ordinal name: 27
48 x 48 (2 colors) - Ordinal name: 28


Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus




Here is a useful program to compile with a cursor resource so running it shows the cursor:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
qwerty12
Posts: 449
Joined: 04 Mar 2016, 04:33
GitHub: qwerty12

Re: Programmatically add cursor resource to Exe/Dll with UpdateResource api?

27 Jul 2017, 17:21

gwarble wrote:It does successfully add the Cursor resource item(s) depending on how many are in the .cur file, and adds the Cursor Group resource item, but the data is wrong for the color depth/resolution


After reading the useful Wikipedia page on the ico/cur file format and the code of this project, I wrote an AutoHotkey script that does appear to successfully add cursor resources to a given exe file, but it doesn't do the deletion or enumeration etc. of what the code you posted was doing. But I also didn't understand what was going on there, either, so there's that.

Code: [Select all] [Expand] [Download] (Untitled.ahk)GeSHi © Codebox Plus



After changing Test.ahk to load the cursor from a numbered resource, compiling it, running the script above to add the cursor resources and then running Test.exe, my cursor did change:

Code: [Select all] [Expand] [Download] (Test.ahk)GeSHi © Codebox Plus

Last edited by qwerty12 on 28 Jul 2017, 09:47, edited 4 times in total.
gwarble
Posts: 220
Joined: 30 Sep 2013, 15:01

Re: Programmatically add cursor resource to Exe/Dll with UpdateResource api?

27 Jul 2017, 18:21

nice!

thanks for the links and code example... it was successful on my end as well...
It also made apparent a bug in ResHack, as inspecting the data after adding it reports as a 1 color cursor... and the previous ones i've added in ResHack itself say 2 colors, even though the cursor is really 32 bit (True color with alpha, so is that 16.8mil colors?) Icons report correctly in ResHack but not cursors... anyway long story short that at least tells me that reshack is not a good method to check if the data is being added correctly for this bit. The resolution and ordinal number do report correctly so you definitely fixed something.

Since the enumeration part is working above, I'm hoping that after studying your code and links I'll be able to merge the two and make some more progress! Thanks again
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
qwerty12
Posts: 449
Joined: 04 Mar 2016, 04:33
GitHub: qwerty12

Re: Programmatically add cursor resource to Exe/Dll with UpdateResource api?

27 Jul 2017, 19:39

gwarble wrote:thanks for the links and code example... it was successful on my end as well...


No problem, and good to hear :-)

I made a mistake in the function: f.RawRead(&curData+4, dwSize) should be f.RawRead(&curData+4, dwSize-4) :oops:

It also made apparent a bug in ResHack, as inspecting the data after adding it reports as a 1 color cursor... and the previous ones i've added in ResHack itself say 2 colors, even though the cursor is really 32 bit (True color with alpha, so is that 16.8mil colors?) Icons report correctly in ResHack but not cursors... anyway long story short that at least tells me that reshack is not a good method to check if the data is being added correctly for this bit. The resolution and ordinal number do report correctly so you definitely fixed something.


I might be off with the colours - while XN Resource Editor says the added cursors are all 2 colour (which is what bColorCount taken straight from the cursor file says for all of them), Resource Hacker says the added cursors are 4 colour. I'm not sure which one to believe. Though, odds are, I've messed up somewhere. If I figure it out, I'll come back :-)

I edited my post above and addressed three things:

  • Apparently, wPlanes must always be 1
  • The language ID was wrong - it should be 0 to reflect the cursors' language neutrality
  • I managed to get both XN Resource Editor and Resource Hacker to show 2 colours for the cursors, but I have no idea if wBitCount was calculated correctly to do this. I don't know anything about the bitmap file format

Good luck!
Last edited by qwerty12 on 27 Jul 2017, 21:11, edited 2 times in total.
gwarble
Posts: 220
Joined: 30 Sep 2013, 15:01

Re: Programmatically add cursor resource to Exe/Dll with UpdateResource api?

27 Jul 2017, 19:45

Totally kludged together and its working... after two years i have a way (proof of concept at least) to build new EitherMouse binaries on new releases of AHK without using ResourceHacker! Very cool

Still need to make sense of it all to wrap it into a nice library for general PE cursor resource management, deletions, etc but thanks guys for the help getting it functioning!

The MaxIndex problem i think is related to named vs integer resources, still investigating, but the enumeration is working for the individual cursor resources, and named groups works for me

Other than that i was clearly not managing the bytes properly

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
gwarble
Posts: 220
Joined: 30 Sep 2013, 15:01

Re: Programmatically add cursor resource to Exe/Dll with UpdateResource api?

28 Jul 2017, 11:05

Edits noted, thanks again!

Its good that its at least reporting in ResHack the same as a cursor added thru itself, but I wouldn't worry about the color depth showing wrong since when used you can clearly see the cursor has more than 2 colors
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .

Return to “Ask For Help”

Who is online

Users browsing this forum: DaveF, divanebaba, Gilaade, Rohwedder, tijger and 63 guests