Home › Forums › TWAIN Classic › How to fit a TW_FIX32 value into a TW_ONEVALUE
- This topic has 3 replies, 2 voices, and was last updated 16 years ago by alvise.
- AuthorPosts
ICAP_XRESOLUTION is a TW_FIX32 type. The documentation (page 9-493) says it can be passed to the scanner through a TW_ONEVALUE container.
Accordingly, I’ve set TW_ONEVALUE.ItemType = TWON_FIX32. But how can I fit the resolution (a TW_FIX32 type) into TW_ONEVALUE.Item as long as this latter is a TW_UINT32 and not a TW_FIX32 ???
I have supposed that in this case TW_ONEVALUE.Item was a pointer to ICAP_XRESOLUTION, and I’ve filled it with the address of the TW_FIX32 structure, but a TWCC_BADVALUE is returned as soon I do a MSG_SET to the Source.
Any help ? Thanks, Alvise.
for things like this i usually go look at someone else’s code. the toolkit is a good place to start, but dosadi’s cTwain is better in my opinion but maybe that’s just that I find their code easier to read. There was at one point a pretty sample on neatcpp.com in a zip named NCTwainClient but last time I checked their site was gone.
Off the top of my head it sounds like you’re doing what you should but I’d have to go look at my code to be sure of it or pull out a sample. If Dosadi’s ctwain sample doesn’t show you the way to sent it post back and I’ll dig out some code.
On the side – if you’re going to be using Kodak scanners (or Hp’s commercial drivers or a hadful of others that support what I’m going to mention) I would skip the whole setting caps one-by-one approach and switch to a profile based approach using EnableDsUiOnly and CustomDsData. I mention it in every thrid or forth post so you should be able to peice together what I’m talking about if it is interesting to you.
.
Hi Gabe, following your suggestion I had a closer look at the free EzTwain package that comes from Dosadi and I discovered how to fit a TW_FIX32 into the Item member of a TW_CONTAINER structure. It’s very simple.
Since the Item is a doubleword (32 bit) and each member of the TW_FIX32 structure is a single word (16 bit), simply memcpy 16+16 into 32 bit when setting the capability, and memcopy 32 bit into 16+16 when getting the capability (in C or C++ it needs appropriate casting, of course).
The EzTwain source code also shows that whatever the capability (TW_UINTxx or TW_FIX32), the function named “TWAIN_SetCapOneValue” gets the capability parameter as a long (=32 bit), then assigns it to Item with the simple assignment operator (=). Very clever.
And also this demostrates that when using a TW_FIX32 type, you can deal with it as if it were a regular long type as long as the Frac member is zero. In fact Frac is set in the upper 16 bit of the long, and Whole in the lower 16 bit.
Well, once I understood how to deal with TW_FIX32 into the Item member of a TW_CONTAINER structure, I have decided to get the current value of the ICAP_XRESOLUTION of my Avision 820C scanner, just to see what it looks like, and subsequently try to set my own value.
The DG_CONTROL, DAT_CAPABILITY, MSG_GET triplet works fine but the TW_FIX32 resolution value that I get looks like this:
resolution.Whole = 0;
resolution.Frac = 600;Since the default resolution of the Avision 820C scanner is 600 dpi, it is evident that the two members of the structure have been exchanged. Ahhh, this is why every time I try to SET the resolution I get a TWCC_BADVALUE condition code in return ! (I thought).
But to make things short, whatever combination of Whole and Frac values I try to set into my scanner, the return status is always the same: bad value.
So I am currently desperate, but will not surrender.
For those who are interested: I further investigated the container that is passed from the Data Source to the application (MSG_GET) and vice-versa (MSG_SET).
When I look into memory at the address allocated for the TWON_ONEVALUE container during the MSG_GET of ICAP_XRESOLUTION I can see:
0x02580000
0xXXXX0007where the first doubleword is Frac+Whole, and the preceeding word (0x0007) is TWTY_FIX32 twain type. Frac, the upper word, is 0x0258 (=600 dpi) and I already said in my previous post that Whole and Frac get exchanged. The word 0xXXXX that preceedes the container is not part of it, but for the sake of completeness its values is 0x0032.
When I allocate the container to perform a MSG_SET of the ICAP_XRESOLUTION, on the contrary, the memory looks like this:
0x000000C8
0xXXXX0007(0x00C8 = 200 dpi) and when I call the DSM entry point I invariably get a TWCC_BADVALUE return code, even if I exchange the words in the Item (0x00C80000) to mimic the MSG_GET arrangement.
By manually changing the contents of the memory, I discovered that the only way to receive the TW_OK status when returning from a call to the DSM entry point, is to set 0xXXXX to the exact same value that it is set when returning from a MSG_GET (0x0032). Any other value makes the MSG_SET fail.
Nonetheless, returning an OK twain status when returning from such a call, the resolution is supposed to be set to the new value… but as I make a successive query (with a further MSG_GET), the resolution is still set to 600 dpi (with Whole and Frac exchanged).
- AuthorPosts