If you want to use COBOL in conjunction with C, you must take care to cooperate with the runtime system in how the screen is displayed.
In some cases, you don't need to worry about the runtime system, because 32-bit Windows manages everything. Generally speaking, this occurs when your C code displays data in its own window. For example, you can display and accept data from a dialog box without interacting with the runtime system (all you need is the handle of the runtime's window, which you have in "mswinsub.c").
In other cases, you'll need to cooperate with the runtime's message handler. For example, if you want to display a graphical object in the main application window, you must monitor "paint" messages to the runtime system and draw your object when appropriate. The general technique for doing this is called "subclassing." When you subclass a window, you instruct 32-bit Windows to pass all of its messages to your own message handler. Typically, your message handler acts on one or more messages and then passes all the messages to the original message handler. For detailed instructions on subclassing, see any 32-bit Windows programming text. The following is an example of a typical case.
Suppose that you want to intercept messages to the runtime system and pass them to a routine called "MyMsgHandler". You would first declare "MyMsgHandler" as a function designed to be called from 32-bit Windows:
LRESULT CALLBACK MyMsgHandler( HWND, UINT, WPARAM, LPARAM );
Next, in your start-up code, you would get the address of the ACUCOBOL-GT message handler and then direct 32-bit Windows to send messages to your handler instead. The code reads like this:
FARPROC lpfnMyMsgHandler, lpfnAcuWndProc; lpfnMyMsgHandler = MakeProcInstance((FARPROC) MyMsgHandler, hAcuInstance ); lpfnAcuWndProc = (FARPROC) GetWindowLong( hAcuWnd, GWL_WNDPROC ); SetWindowLong( hAcuWnd, GWL_WNDPROC, (long) lpfnMyMsgHandler );
At this point, all messages that 32-bit Windows would normally direct to the ACUCOBOL-GT main window procedure are instead received by "MyMsgHandler". Your message handler should intercept and act on the messages it cares about. At the end, it should pass each message on to the original message handler and return the result. This is usually done with a line that reads like this:
return CallWindowProc( lpfnAcuWndProc, hWnd, iMsg, wParam, lParam );
For reference, ACUCOBOL-GT for 32-bit Windows currently acts on the following messages:
WM_ACTIVATE | WM_LBUTTONUP |
WM_ACTIVATEAPP | WM_MBUTTONDBLCLK |
WM_CHAR | WM_MBUTTONDOWN |
WM_CLOSE | WM_MBUTTONUP |
WM_COMMAND | WM_MEASUREITEM |
WM_CREATE | WM_MOUSEMOVE |
WM_CTLCOLOR | WM_NCLBUTTONDBLCLK |
WM_CTLCOLORBTN | WM_NCLBUTTONDOWN |
WM_CTLCOLOREDIT | WM_NCPAINT |
WM_CTLCOLORLG | WM_PAINT |
WM_CTLCOLORLISTBOX | WM_PALETTECHANGED |
WM_CTLCOLORMSGBOX | WM_QUERYDRAGICON |
WM_CTLCOLORSCROLLBAR | WM_QUERYENDSESSION |
WM_CTLCOLORSTATIC | WM_QUERYNEWPALETTE |
WM_DESTROY | WM_RBUTTONDBLCLK |
WM_DRAWITEM | WM_RBUTTONDOWN |
WM_ENDSESSION | WM_RBUTTONUP |
WM_ERASEBKGND | WM_SETCURSOR |
WM_GETMINMAXINFO | WM_SETFOCUS |
WM_HSCROLL | WM_SIZE |
WM_INITMENU | WM_SIZING |
WM_INITMENUPOPUP | WM_SYSCHAR |
WM_KEYDOWN | WM_SYSCOLORCHANGED |
WM_KILLFOCUS | WM_SYSCOMMAND |
WM_LBUTTONDBLCLK | WM_TIMER |
WM_LBUTTONDOWN | WM_VSCROLL |
See the Visual C++ .NET documentation for details about these messages.