Rapinto, en princpio lo que intento es simular MDI Form en PowerCOBOL.
En realidad, cada Form en PowerCOBOL se compone de:
- Una WindowForm que es la que contiene SystemMenu, Border etc.
- Un Frame (Frame de C++, loadable. No hablo de CmFrame), que es en el que realmente ponemos los controles.
Pero a nivel del compilador en modo Diseño, nosotros pensamos que es un Form. Si en en un Form haces GetParent, obtienes el hwnd del ParentForm.
Lo que yo hago para simular MDI, es ChildForm.SetParent = ParentForm.hwnd y asi el ParentForm se hace Container del ChildForm. El problema es que cuando haces click en ChildForm, el ParentForm pierde focus, y vice versa.
Hablé con gente de C++/Delphi + WinAPI. Me dijeron que en este caso hay que hacer subclassing de la ventana. Es decir:
- Definir propia procedure equivalente a CallWindowProc y posicionar un PROCEDURE-POINTER MyWndProc.
- Obtener PROCEDURE-POINTER de CallWindowProc actual, el que actualmente es llamado por el Window:
- En el evendo Window.Opened
Código COBOL:
******** MyWndProc. Va a ser llamado por Windows, por eso tiene STDCALL
IDENTIFICATION DIVISION.
PROGRAM-ID. MyWndProc.
WORKING-STORAGE SECTION.
01 PTR-OldWndProc IS EXTERNAL PIC S9(9) COMP-5.
LINKAGE SECTION.
01 LNK-RESULT PIC S9(9) COMP-5.
01 LNK-HWND PIC S9(9) COMP-5.
01 LNK-MSG PIC S9(9) COMP-5.
01 LNK-WPARAM PIC 9(9) COMP-5.
01 LNK-LPARAM PIC S9(9) COMP-5.
PROCEDURE DIVISION WITH STDCALL USING LNK-HWND LNK-MSG LNK-WPARAM LNK-LPARAM RETURNING LNK-RESULT.
IF LNK-MSG = <<LOST FOCUS MESSAGE>> NO ME ACURDO EXACTAMENTE
MOVE 0 TO LNK-MSG
END-IF
CALL "CallWindowProc" WITH STDCALL USING BY VALUE PTR-OldWndProc
BY VALUE LNK-HWND
BY VALUE LNK-MSG
BY VALUE LNK-WPARAM
BY VALUE LNK-LPARAM
RETURNING LNK-RESULT.
EXIT PROGRAM.
END PROGRAM MyWndProc.
Código COBOL:
******** MainForm.Opened
WORKING-STORAGE SECTION.
01 WS-HWND PIC S9(9) COMP-5.
01 ParentHWND PIC S9(9) COMP-5.
01 PTR-OldWndProc IS EXTERNAL PIC S9(9) COMP-5.
01 PPTR REDEFINES PTR-OldWndProc PROCEDURE-POINTER.
01 PTR-MyWndProc PROCEDURE-POINTER.
PROCEDURE DIVISION.
MOVE "hwnd" OF POW-SELF TO WS-HWND
CALL "GetParent" WITH STDCALL USING BY VALUE LNK-HWND
RETURNING ParentHWND.
CALL "GetWindowLong" WITH STDCALL USING BY VALUE ParentHWND
BY VALUE GWL_WNDPROC
RETURNING PPTR.
SET PTR-MyWndProc TO ENTRY "MyWndProc"
CALL "SetWindowLong" WITH STDCALL USING BY VALUE ParentHWND
BY VALUE GWL_WNDPROC
BY VALUE PTR-MyWndProc
RETURNING PPTR.
Rui, el codigo no es exacto, lo acabo de escribir de memoria (estoy en el trabajo). Pero entenderas lo que hago. Es sustiuir CallWindoProc por MyWndProc, camptar WindowMessage, si es desactivar Focus visual, muevo 0, y llamo default CallWindoProc con PTR-OldWndProc.
A ver que opians.