Highlighted
Absent Member.
Absent Member.
2504 views

[archive] a problem with a structure for an api

[Migrated content. Thread originally posted on 07 January 2005]

Im trying to define this structure in cobol for an api, but im putting the pictures wrong, because the api returns strange data.

typedef struct _devicemode {
BCHAR dmDeviceName[CCHDEVICENAME];
WORD dmSpecVersion;
WORD dmDriverVersion;
WORD dmSize;
WORD dmDriverExtra;
DWORD dmFields;
union {
struct {
short dmOrientation;
short dmPaperSize;
short dmPaperLength;
short dmPaperWidth;
short dmScale;
short dmCopies;
short dmDefaultSource;
short dmPrintQuality;
};
POINTL dmPosition;
DWORD dmDisplayOrientation;
DWORD dmDisplayFixedOutput;
};

short dmColor;
short dmDuplex;
short dmYResolution;
short dmTTOption;
short dmCollate;
BYTE dmFormName[CCHFORMNAME];
WORD dmLogPixels;
DWORD dmBitsPerPel;
DWORD dmPelsWidth;
DWORD dmPelsHeight;
union {
DWORD dmDisplayFlags;
DWORD dmNup;
}
DWORD dmDisplayFrequency;
#if(WINVER >= 0x0400)
DWORD dmICMMethod;
DWORD dmICMIntent;
DWORD dmMediaType;
DWORD dmDitherType;
DWORD dmReserved1;
DWORD dmReserved2;
#if (WINVER >= 0x0500) || (_WIN32_WINNT >= 0x0400)
DWORD dmPanningWidth;
DWORD dmPanningHeight;
#endif
#endif /* WINVER >= 0x0400 */
} DEVMODE;

My definition:

01 DevOption.
05 dmDeviceName PIC x(32).
05 dmSpecVersion PIC 9(4) USAGE IS COMP-5.
05 dmDriverVersion PIC 9(4) USAGE IS COMP-5.
05 dmSize PIC 9(4) USAGE IS COMP-5.
05 dmDriverExtra PIC 9(4) USAGE IS COMP-5.
05 dmFields PIC 9(9) USAGE IS COMP-5.
05 dmOrientation PIC 9(4) USAGE IS COMP-5.
05 dmPaperSize PIC 9(4) USAGE IS COMP-5.
05 dmPaperLength PIC 9(4) USAGE IS COMP-5.
05 dmPaperWidth PIC 9(4) USAGE IS COMP-5.
05 dmScale PIC 9(4) USAGE IS COMP-5.
05 dmCopies PIC 9(4) USAGE IS COMP-5.
05 dmDefaultSource PIC 9(4) USAGE IS COMP-5.
05 dmPrintQuality PIC 9(4) USAGE IS COMP-5.
05 dmPosition.
10 Posx PIC 9(9) USAGE IS COMP-5.
10 Posy PIC 9(9) USAGE IS COMP-5.
05 dmDisplayOrientation PIC 9(9) USAGE IS COMP-5.
05 dmDisplayFixedOutput PIC 9(9) USAGE IS COMP-5.
05 dmColor PIC 9(4) USAGE IS COMP-5.
05 dmDuplex PIC 9(4) USAGE IS COMP-5.
05 dmYResolution PIC 9(4) USAGE IS COMP-5.
05 dmTTOption PIC 9(4) USAGE IS COMP-5.
05 dmCollate PIC 9(4) USAGE IS COMP-5.
05 dmFormName PIC 9(4) USAGE IS COMP-5.
05 dmLogPixels PIC 9(4) USAGE IS COMP-5.
05 dmBitsPerPel PIC 9(9) USAGE IS COMP-5.
05 dmPelsWidth PIC 9(9) USAGE IS COMP-5.
05 dmPelsHeight PIC 9(9) USAGE IS COMP-5.
05 dmDisplayFlags PIC 9(9) USAGE IS COMP-5.
05 dmNup PIC 9(9) USAGE IS COMP-5.
05 dmDisplayFrequency PIC 9(9) USAGE IS COMP-5.
05 dmICMMethod PIC 9(9) USAGE IS COMP-5.
05 dmICMIntent PIC 9(9) USAGE IS COMP-5.
05 dmMediaType PIC 9(9) USAGE IS COMP-5.
05 dmDitherType PIC 9(9) USAGE IS COMP-5.
05 dmReserved1 PIC 9(9) USAGE IS COMP-5.
05 dmReserved2 PIC 9(9) USAGE IS COMP-5.
05 dmPanningWidth PIC 9(9) USAGE IS COMP-5.
05 dmPanningHeight PIC 9(9) USAGE IS COMP-5.

More information about the structure:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_8nle.asp

Can anyone help me? :confused:

Thank you
0 Likes
7 Replies
Highlighted
Absent Member.
Absent Member.

RE: [archive] a problem with a structure for an api

One thing to be careful of is that when you see data types short or long in win32 api, it means that it is signed. If you see a ushort , ulong or dword it means unsigned. So, for short use PIC S9(5) COMP-5 and for long use PIC S9(9) COMP-5. Also, you can try using USAGE SIGNED-SHORT and USAGE SIGNED-LONG.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] a problem with a structure for an api

Dan is right, a couple of comments though;

First of all, if you choose to use SIGNED-SHORT and SIGNED-LONG, you must compile with -Dw32 -Dl4 to get the correct data allocation / alignment.

Another issue, and that does not only apply in this case, but in any case, so anyone who do API integration, please listen up.

It turns out that in some cases, the numbers returned from API functions has so many digits that the PIC S9(9) COMP-5 (LONG) . This is possible because;

a Long is 4 byte, in hex 4 bytes are: FF FF FF FF, if we translate this to decimals, we get:

4 294 967 295

Or 10 digits, e.g. the most significant digit will be lost, and the number will be invalid. This is due to truncation rules by the picture clause.

Some will object and say that this number is MAX DWORD, not MAX INT, and they are right, but even so, if we divide this by 2 to get MAX INT (which is the same as MAX LONG on 32bit systems) we get:

2 147 483 646 / 2 147 483 646-

and we are still at 10 digits...

SHORT fortunately has a max of:

65 535

which fits neatly into the PIC S9(5) COMP-5 clause.

What I propose you do in cases where you work on structures from the WinAPI is to use the:

PIC X(n) COMP-N.

clause instead, the nice thing about this is that the 'n' in this case always represents a byte, e.g. it makes the mapping to Windows datatypes very straight forward once you know how many bytes the type takes. E.g., if you are talking with a C developer he/she won't have a clue what you are talking about when you ask them how many digits to put in the PIC clause, but if you ask them for the datasize of their datatype, they will answer promptly (or if not, should find another job).
Here is a simple overview to begin with:

DWORD, LONG, INT allocates 4 bytes, e.g. PIC X(4) COMP-N.

WORD, SHORT allocates 2 bytes, e.g. PIC X(2) COMP-N.

BYTE, CHAR allocates 1 byte, e.g. PIC X.

Also note that you may see any of these basic datatypes prefixed by a LP, this LP means it is a pointer to a dataarea containing data of the type then mentioned. The LP is what you should size your COBOL datatype after then, not the datatype suffixing the LP. E.g. if you see this:

LPWORD

You should translate this to:

PIC X(4) COMP-N.

Not:

PIC X(2) COMP-N.

Because LP, being short for LongPointer allocates 4 bytes, and what you get is LP, e.g. the memory address of the dataitem, not the value.

LP corresponds to COBOL 'ADDRESS OF' or 'BY REFERENCE'. LP is always positive or NULL.

Now, the observant reader will object that this is neat, as long as there are no question about negative numbers. Correct, a negative number would for a datatype of COMP-N type be represented as a very high number, that is between:

2 147 483 646 and 4 294 967 295

one fact to state in this, is that I have to this date, yet to have found any Windows API structure containing members that may be set to a negative number. What I know this far is that negative numbers may be received as a result value from a function call, but never seen a structure member containing this. Also, as far as function result returns, it also applies to these that they use to be low numbers, e.g. I cannot remember any being more than 9 digits.

So, for your example, I would propose to redo the structure, changing all the datatypes corresponding to my list above and you should be set.

I also notice you do not do the transition of the union. You know that UNION corresponds to COBOL REDEFINES?

You may notice the IFDEFs on windows versions underneath? You don't have anything similar to this in COBOL, and many other languages for that matter, which is why it is important for you to set the group member

dmSize

correctly before using the group. And to set this properly, you have to check what OS your application is running on, e.g. Win98, WinNT, Win2K or WinXP...

Go ahead and give it a try, if you get stuck again, post your changes here and I will help you in.

Finally, may I ask why you want to access this structure directly? The current version of ACUCOBOL-GT provides features to manipulate most of these members via the WIN$PRINTER interface, also note that changes you do to this structure will not be reflected in the runtime's own copy unless you fire off a windows message indicating changes to the Win spooler settings.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] a problem with a structure for an api

Hi Gisle,
Great information, thank you. This is very timely too, because I have the acucobol plug-in for ApiViwer 2004 working, but I was undecided about whether to use COMP-5 or COMP-N for data types. I was unsure because I read in the acucobol documentation, as you pointed out, that COMP-N will not reflect negative numbers. You also point out that many win32 api functions do not use negative numbers, so would you recommend that the plug-in translate using COMP-N or COMP-5 ? I wish there was a way in ApiViewer to specifify a setting for this so the user could choose, but I don't see one. I will email the author to ask.

Here's the translation I get from Acucobol ApiViewer plug-in for DEVMODE structure when using COMP-N:


01 DEVMODE.
   05 dmDeviceName PIC X(32).
   05 dmSpecVersion PIC PIC X(2) COMP-N.
   05 dmDriverVersion PIC PIC X(2) COMP-N.
   05 dmSize PIC PIC X(2) COMP-N.
   05 dmDriverExtra PIC PIC X(2) COMP-N.
   05 dmFields PIC PIC X(4) COMP-N.
   05 dmOrientation PIC PIC X(2) COMP-N.
   05 dmPaperSize PIC PIC X(2) COMP-N.
   05 dmPaperLength PIC PIC X(2) COMP-N.
   05 dmPaperWidth PIC PIC X(2) COMP-N.
   05 dmScale PIC PIC X(2) COMP-N.
   05 dmCopies PIC PIC X(2) COMP-N.
   05 dmDefaultSource PIC PIC X(2) COMP-N.
   05 dmPrintQuality PIC PIC X(2) COMP-N.
   05 dmColor PIC PIC X(2) COMP-N.
   05 dmDuplex PIC PIC X(2) COMP-N.
   05 dmYResolution PIC PIC X(2) COMP-N.
   05 dmTTOption PIC PIC X(2) COMP-N.
   05 dmCollate PIC PIC X(2) COMP-N.
   05 dmFormName PIC X(32).
   05 dmUnusedPadding PIC PIC X(2) COMP-N.
   05 dmBitsPerPel PIC PIC X(2) COMP-N.
   05 dmPelsWidth PIC PIC X(4) COMP-N.
   05 dmPelsHeight PIC PIC X(4) COMP-N.
   05 dmDisplayFlags PIC PIC X(4) COMP-N.
   05 dmDisplayFrequency PIC PIC X(4) COMP-N.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] a problem with a structure for an api

Looks great Dan,

couple of notes though. In your translation you have:

05 dmFormName PIC X(32).
05 dmUnusedPadding PIC PIC X(2) COMP-N.


I cannot find this "dmUnusedPadding", but you have omitted "dmLogPixels.

Why is that?

Also, note that the statements inside the #if(WINVER...) should be used too, if you execute on the appropriate platform. But, my guess is that if you prior to the call to whatever api function you want to use this with, set the dmSize like this:

SET dmSize TO SIZE OF DEVMODE, you should get this working.

As for COMP-N vs COMP-5, there is an alternative that will allow COMP-5 to work too, that is if you turn off range checking (compile with -Dz), this might be okay if it does not impact other parts of your source.

Note that you *do* get negative numbers with COMP-N too, but it has the odditty that you have to check the high values for it.

If I were you, I would default to COMP-N and have a comment for each translation that the developer should care to check if any of the values returned may be negative, in which case the developer may want to choose using COMP-5 instead.

Good work!
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] a problem with a structure for an api

Thanks to Both for the efforts and information, you bring light in a lots of doubts in Api programation.

Im working now to implement the structure and see if works. Im trying to change the screen resolution with the api ChangeDisplaySettings.

Some questions, Why you put pic pic? comp-n must be defined like a picture of "pic x(n) comp-n"?

Sorry for some questions but I started with cobol six month ago and some things still strange to me. :rolleyes:

Thanks a lot again.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] a problem with a structure for an api

Woops, I didn't notice the PIC PIC, that was a mistake, sorry about that, should be just PIC. 😛

Gisle, the DEVMODE structure information comes from ApiViewers database, unfortunately I don't have control over the definition, my plug-in can only do the translation. So, although it's a helpful tool, it will still be a good idea to look at the msdn documentation for double-checking.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] a problem with a structure for an api

Great work anyhow!

Thanks Dan.
0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.