Highlighted
Absent Member.
Absent Member.
1033 views

Translate a Windows API Call to COBOL

[Migrated content. Thread originally posted on 06 January 2012]

Hello,
I am trying to translate the following API structure so I can call it in my cobol program.
LRESULT WINAPI SendMessageTimeout(
__in HWND hWnd,
__in UINT Msg,
__in WPARAM wParam,
__in LPARAM lParam,
__in UINT fuFlags,
__in UINT uTimeout,
__out_opt PDWORD_PTR lpdwResult
);
Basically, I'm trying to broadcast a WM_SETTINGCHANGE message with lParam set to the string "Environment" in order to process a registry change involving an environment variable. See this link for more info:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682653%28v=vs.85%29.aspx


I've got the portion completed that sets the variables, but can't seem to broadcast a message to update windows.

Any help here would be great.

Thanks

Dave
0 Likes
1 Reply
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: Translate a Windows API Call to COBOL

Hi Dave,

I'm not sure how far you have gotten with this, so this answer may be overly complete.

The first thing to do is to look more carefully at the documentation for SendMessageTimeout, to see what the valid values for the different parameters are. For example, the value of hWnd can be the handle to a window, or 0xffff to broadcast this message to all top-level windows (which is probably what you want).

The msg parameter needs to be the value of WM_SETTINGCHANGE. According to this page, the value is 0x001A. That same page also describes the appropriate values for wParam and lParam.

For wParam, (quoting from the link above): "When an application sends this message, this parameter must be NULL." So the value is 0.

For lParam, this needs to be a pointer to the string "Environment".

Going back to the description of SendMessageTimeout, fuFlags can be one or more of several values. I don't know what behavior you want exactly, but (for example) if you want to specify both ABORTIFHUNG (0x0002) and BLOCK (0x0001), you would add these values to get 0x0003.

For uTimeout, specify the timeout in milliseconds. According to the documentation, this can cause your application to hang for quite a while! Again, I'm not sure how many top-level windows you have, or how long you can afford to wait. This value will probably require some experimentation.

Finally, for lpdwResult, you can pass a DWORD variable to get the result of the message. I'm not sure this would make much sense in your case. But you may decide differently.

How should you describe these variables in COBOL? Well, there are two possibilities.

The first possibility is to write a small C function and either link it into the runtime, or link it as a DLL and call it. Because most (or all) of the parameters for this function will be the for all of your COBOL calls, you can hard-code those values in your C function, and not worry about data types. For example:

#include
int
callSendMessageTimeout(void)
{
    HWND hWnd = HWND_BROADCAST;
    UINT msg = WM_SETTINGCHANGE;
    WPARAM wParam = 0;
    char *env = "Environment";
    LPARAM lParam = (LPARAM) env;
    UINT fuFlags = 0;  // Or specify the value(s) you want
    UINT uTimeout = 100;  // Or specify the value you want
    DWORD dwResult;

    return SendMessageTimeout(hWnd, msg, wParam, lParam, fuFlags, uTimeout, *dwResult);
}


Alternately, if you want to call SendMessageTimeout from COBOL, you can define the variables as follows (though I have not tried this, and am not 100% confident that it is correct):

    01  send-message-timeout-group.
        03  hwnd    unsigned-int.
        03  msg     unsigned-int.
        03  wparam  unsigned-int.
        03  env-string pic x(12).
        03  lparam  pointer.
        03  flags   unsigned-int.
        03  timeout unsigned-int.
        03  result  unsigned-int.
        03  presult pointer.


In your procedure division, do the following:

    move H#FFFF to hwnd
    move H#1A to msg
    move 0 to wparam
    move "Environment" to env-string
    inspect env-string replacing trailing space by low-values
    set lparam to address of env-string
    move h#3 to flags   *> Set to the value you want
    move 100 to timeout *> Set to the value you want
    set presult to address of result
    call "SendMessageTimeout" using hwnd, msg, wparam, lparam, flags, timeout, presult


Note that I did not test this, and some parameters may be off a little. You can read more about mapping C to COBOL types in the ACU doc set (the Interoperability manual, Chapter 3, Working with Windows Technologies). I have done things slightly differently than described in that chapter.

I hope this helps!
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.