Cobol Foro

Cobol Foro (https://www.cobolforo.es/index.php)
-   PowerCOBOL (ActiveX, v4 - v11) (https://www.cobolforo.es/forumdisplay.php?f=9)
-   -   [Compilador] Processo/EXE ativo (https://www.cobolforo.es/showthread.php?t=1802)

Joseg 5 de noviembre de 2024 16:51

Processo/EXE ativo
 
Olá

Como saber en Powercobol se um processo esta ativo?

Gracias
Jose

fastpho 5 de noviembre de 2024 21:11

Hola @Joseg , si estas buscando saber si una appxxx.exe esta ejecutandose dos formas :
una con el control ocx ScriptControl
Código COBOL:
  1.  
  2.  ENVIRONMENT     DIVISION.
  3.  DATA            DIVISION.
  4.  WORKING-STORAGE SECTION.
  5.  01 scriptCode1   pic x(500).
  6.  PROCEDURE       DIVISION.
  7.               MOVE SPACES TO scriptCode1.
  8.               string    
  9.                    'Sub MYProgram() ' vbCRLF        
  10.                    ' Set objWMI = GetObject("winmgmts:\.
  11. ootcimv2")' vbCRLF
  12.                    ' Set colProcesses = objWMI.ExecQuery("SELECT * FROM Win32_Process WHERE Name = ""ElsisGestion.exe"" ") ' vbCRLF
  13.                    ' If colProcesses.Count = 0 Then' vbCRLF
  14.                    '    MsgBox "El programa no se está ejecutando"' vbCRLF
  15.                    ' Else' vbCRLF
  16.                    '    MsgBox "El programa se está ejecutando"' vbCRLF
  17.                    ' End If'     vbCRLF
  18.                    'End Sub' vbCRLF                                        
  19.                    delimited by size into scriptCode1
  20.               end-string.
  21.  
  22.       INVOKE scriptControl1 "Reset".
  23.       INVOKE scriptControl1 "AddCode" USING scriptCode1.
  24.       INVOKE scriptControl1 "ExecuteStatement" USING "MYProgram".
  25.  
  26.      
  27.              

Otra forma es buscando la ventana del appxxx.exe con api de windows : GetTopWindow , GetWindow , GetWindowTextA
Código COBOL:
  1.  special-names.
  2.         symbolic constant
  3.             gw_hwndfirst    is 0
  4.             gw_hwndnext     is 2
  5.         .
  6.  data division.
  7.  working-storage section.
  8.  01 get-this-window-handle.
  9.         05  this-window-handle          pic s9(9)   comp-5  value 0.
  10.         05  filler                      pic x(12)           value spaces.
  11.        
  12.  01 title-bar-search-string         pic x(1025)         value spaces.
  13.  01 title-bar-index                 pic 9(9)    comp-5  value 0.
  14.  
  15.  01 child-window-handle             pic s9(9)   comp-5  value 0.
  16.  01 parent-window-handle            pic s9(9)   comp-5  value 0.
  17.  
  18.  01 length-of-title-bar-buffer      pic s9(9)   comp-5.
  19.  01 title-bar-buffer-max            pic s9(9)   comp-5.
  20.  01 title-bar-buffer                pic x(1025)         value spaces.              
  21.        
  22.  01 hwnd-type                       pic 9(9)    comp-5.
  23.            
  24.  01     null-value                      pic s9(9)   comp-5  value 0.
  25.  
  26.  linkage section.
  27.  01 title-bar-string                pic x(1024).
  28.  01 found-window-sw                 pic 9(4)    comp-5.
  29.  01 found-window-handle             pic s9(9)   comp-5.
  30.  01 return-value                    pic s9(9)   comp-5.
  31.    
  32.  procedure division using title-bar-string, found-window-sw, found-window-handle, return-value.
  33.         move 0 to return-value
  34.         move 0 to found-window-sw
  35.         move 0 to found-window-handle
  36.        
  37.         compute title-bar-buffer-max = function length(title-bar-buffer)
  38. *      
  39. * Let's make sure they passed the title bar string
  40. *
  41.         if title-bar-string not > " "
  42.             move 1 to return-value
  43.             exit program
  44.         end-if
  45. *
  46. * Let's get the handle of this window
  47. *
  48.         call "GetTopWindow" with STDCALL using
  49.             by value null-value
  50.             returning this-window-handle
  51. *
  52. * Now, let's find the length of the search string
  53. *
  54.         move title-bar-string to title-bar-search-string
  55.         perform varying title-bar-index from 1025 by -1
  56.                 until title-bar-search-string(title-bar-index:1) not = " "
  57.             continue
  58.         end-perform
  59. *
  60. * Now, let's get the first window
  61. *
  62.         move gw_hwndfirst to hwnd-type
  63.         call "GetWindow" with STDCALL using
  64.             by value this-window-handle
  65.             by value hwnd-type
  66.             returning child-window-handle
  67.         if child-window-handle = 0
  68.             move 3 to return-value
  69.             exit program
  70.         end-if
  71.        
  72.         move gw_hwndnext to hwnd-type  
  73. *
  74. * Now, let's see if this is the target window, if not, loop through all open windows
  75. *
  76.         perform until child-window-handle = 0
  77. *
  78. * Let's get the title bar text of this window
  79. *
  80.             call "GetWindowTextA" with STDCALL using
  81.                 by value child-window-handle
  82.                 by reference title-bar-buffer              
  83.                 by value title-bar-buffer-max
  84.                 returning length-of-title-bar-buffer        *> Note, the length returned does NOT include the NULL byte
  85. *
  86. * If the window has a title bar, is it the one we're looking for?
  87. *              
  88.             if length-of-title-bar-buffer > 0
  89.                 if title-bar-search-string(1:title-bar-index) = title-bar-buffer(1:title-bar-index)
  90.                     move 1 to found-window-sw
  91.                     move child-window-handle to found-window-handle
  92.                     move 0 to return-value
  93.                     exit program
  94.                 end-if
  95.             end-if
  96. *
  97. * Get the next window
  98. *
  99.             move child-window-handle to this-window-handle
  100.            
  101.             call "GetWindow" with STDCALL using
  102.                 by value this-window-handle
  103.                 by value hwnd-type
  104.                 returning child-window-handle
  105.        
  106.         end-perform
  107. *
  108. * Didn't find the window
  109. *
  110.         move 0 to return-value
  111.         move 0 to found-window-sw
  112.         move 0 to found-window-handle
  113.         exit program

Saludos ...

Kuk 5 de noviembre de 2024 22:46

@Joseg,

Código COBOL:
  1.  ENVIRONMENT     DIVISION.
  2.  DATA            DIVISION.
  3.  WORKING-STORAGE SECTION.
  4.  01  DWORD       typedef pic s9(9) comp-5.
  5.  01  ULONG_PTR   typedef pic  9(9) comp-5.
  6.  01  LONG        typedef pic s9(9) comp-5.
  7.  01  HANDLE      typedef pic s9(9) comp-5.
  8.  
  9. *>---------------------------------------------
  10.  01  TH32CS_SNAPPROCESS      type DWORD value h"02".
  11. *>---------------------------------------------
  12.  
  13.  01  PROCESSENTRY32.
  14.      05  dwSize              type DWORD.
  15.      05  cntUsage            type DWORD.
  16.      05  th32ProcessID       type DWORD.
  17.      05  th32DefaultHeapID        pointer.
  18.      05  th32ModuleID        type DWORD.
  19.      05  cntThreads          type DWORD.
  20.      05  th32ParentProcessID type DWORD.
  21.      05  pcPriClassBase      type LONG.
  22.      05  dwFlags             type DWORD.
  23.      05  szExeFile           pic x(1000).
  24.      
  25.  01  snapshot                type HANDLE.
  26.  
  27.  01  returnCode              type DWORD.
  28.  
  29.  PROCEDURE       DIVISION.
  30.  
  31.      call "CreateToolhelp32Snapshot" with stdcall using by value TH32CS_SNAPPROCESS
  32.                                                          by value 0
  33.                                                          returning snapshot
  34.      
  35.      move length of PROCESSENTRY32 to dwSize
  36.      
  37.      call "Process32First" with stdcall using by value snapshot
  38.                                               by reference PROCESSENTRY32
  39.                                               returning returnCode
  40.      
  41.      if  returnCode = 0
  42.          call "GetLastError" with stdcall returning returnCode
  43.          
  44.          display "GetLastError: ", returnCode
  45.          
  46.          exit program
  47.      end-if
  48.      
  49.      perform until returnCode = 0
  50.          if  szExeFile(1:8) = "Main.exe" *> resto a nulos
  51.              INVOKE pow-self "DisplayMessage" USING "Bingo!" 64
  52.          end-if
  53.                  
  54.          INVOKE CmList1 "AddString" USING szExeFile
  55.          
  56.          call "Process32Next" with stdcall using by value snapshot
  57.                                                  by reference PROCESSENTRY32
  58.                                                  returning returnCode
  59.      end-perform

Joseg 7 de noviembre de 2024 11:01

Muchas gracias a todos por vuestra ayuda. :amigo:

Eu pretendia fazer isto: https://www.tek-tips.com/threads/set...g-pid.1820890/
Apenas consegui fazer em "C" e Windev. Em anexo o código em "C".

Pero la idea era la siguiente: Con el número PID y no el título de la ventana (el título es dinámico), maximizar un programa de terceros y hacerse visible.

Código CPP:
  1. #include <windows.h>
  2. #include <tlhelp32.h>
  3. #include <iostream>
  4. #include <cstdlib>
  5.  
  6. BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
  7.     DWORD processId;
  8.     GetWindowThreadProcessId(hwnd, &processId);
  9.  
  10.     // Verificar se o PID corresponde e se a janela é visível
  11.     if (processId == static_cast<DWORD>(lParam) && IsWindowVisible(hwnd)) {
  12.         // Maximizar e trazer a janela para o primeiro plano
  13.         ShowWindow(hwnd, SW_MAXIMIZE);
  14.         SetForegroundWindow(hwnd);
  15.         return FALSE; // Parar a enumeração
  16.     }
  17.  
  18.     return TRUE; // Continuar a enumeração
  19. }
  20.  
  21. void MaximizeMainApplicationWindow(DWORD pid) {
  22.     EnumWindows(EnumWindowsProc, static_cast<LPARAM>(pid));
  23. }
  24.  
  25. int main(int argc, char* argv[]) {
  26.     if (argc != 2) {
  27.         std::cerr << "Usage: " << argv[0] << " <PID>" << std::endl;
  28.         return 1;
  29.     }
  30.  
  31.     DWORD pid = std::atoi(argv[1]);
  32.     MaximizeMainApplicationWindow(pid);
  33.  
  34.     return 0;
  35. }

Kuk 7 de noviembre de 2024 12:33

@Joseg, desde que descubrí cómo hacer funcionar el CALL BY VALUE en PowerCOBOL, absolutamente todo lo que se puede hacer en C, también se puede hacer en PowerCOBOL!

Así que, este código C también se puede convertir en PowerCOBOL! ;)

Joseg 7 de noviembre de 2024 18:00

Cita:

Citación del post de Kuk (Mensaje 9619)
@Joseg, desde que descubrí cómo hacer funcionar el CALL BY VALUE en PowerCOBOL, absolutamente todo lo que se puede hacer en C, también se puede hacer en PowerCOBOL!

Así que, este código C también se puede convertir en PowerCOBOL! ;)

Admito que todo es posible ...pero no pude hacerlo, tampoco tengo mucha experiencia en llamadas a la API de WINDOWS.
Por ejemplo, esta función "&& IsWindowVisible(hwnd))" no devolvió el resultado correcto. Debo estar haciendo algo mal.

Código COBOL:
  1. CALL 'IsWindowVisible' USING BY VALUE HWND
  2. IF RETURN-CODE = 1
  3.    CALL 'ShowWindow' USING BY REFERENCE HWND,
  4.                                             BY VALUE 3   *> SW_MAXIMIZE
  5.    CALL 'SetForegroundWindow' USING BY REFERENCE HWND
  6.    IF RETURN-CODE = 1
  7.       DISPLAY "Janela trazida para frente com sucesso."
  8.   ELSE
  9.       DISPLAY "Falha ao trazer a janela para frente."
  10.    END-IF
  11. ELSE
  12.    DISPLAY "Janela não está visível."
  13. END-IF
José

Kuk 7 de noviembre de 2024 21:58

@Joseg, acabo de probarlo y funciona:

Lo primero, creas un fichero nuevo en el directrio del proyecto y lo llamas EnumWindowsProc. Luego lo añades en el proyecto (import) y le pegas el siguiente contenido:

Código COBOL:
  1.  IDENTIFICATION DIVISION.
  2.  PROGRAM-ID. "EnumWindowsProc".
  3.  ENVIRONMENT     DIVISION.
  4.  DATA            DIVISION.
  5.  WORKING-STORAGE SECTION.
  6.  01  SW_MAXIMIZE          PIC S9(9) COMP-5 VALUE 3.
  7.  
  8.  01  P1                   POINTER.
  9.  01  HWND REDEFINES P1    PIC S9(9) COMP-5.
  10.  01  P2                   POINTER.
  11.  01  LPARAM REDEFINES P2  PIC S9(9) COMP-5.
  12.  
  13.  01  processId            PIC S9(9) COMP-5.
  14.  01  isVisble             PIC S9(9) COMP-5.
  15.  
  16.  LINKAGE SECTION.
  17.  77  PARM1                PIC S9(9) COMP-5.
  18.  77  PARM2                PIC  9(9) COMP-5.
  19.  
  20.  01  RETURN-VALUE         PIC  9(9) COMP-5.
  21.  
  22.  PROCEDURE DIVISION WITH STDCALL USING PARM1, PARM2 RETURNING RETURN-VALUE.
  23.      
  24.      MOVE FUNCTION ADDR(PARM1) TO P1
  25.      MOVE FUNCTION ADDR(PARM2) TO P2
  26.      
  27.      CALL "GetWindowThreadProcessId" WITH STDCALL USING BY VALUE HWND
  28.                                                         BY REFERENCE processId
  29.                                                        
  30.      CALL "IsWindowVisible" WITH STDCALL USING BY VALUE HWND RETURNING isVisble
  31.      
  32.      IF  processId = LPARAM AND
  33.          isVisble NOT = 0
  34.          CALL "ShowWindow"          WITH STDCALL USING BY VALUE HWND, SW_MAXIMIZE
  35.          CALL "SetForegroundWindow" WITH STDCALL USING BY VALUE HWND
  36.          
  37.          MOVE 0 TO RETURN-VALUE
  38.      
  39.      ELSE
  40.          MOVE 1 TO RETURN-VALUE
  41.      END-IF
  42.      
  43.      GOBACK
  44.      .
  45.          

No olvides de añadirle la directiva ALPHAL(WORD) en las propiedades.

Luego desde donde quieras haces algo así (yo lo hago en el evento Click de un botón, recogiendo un PID desde CmText):

Código COBOL:
  1.  ENVIRONMENT     DIVISION.
  2.  DATA            DIVISION.
  3.  WORKING-STORAGE SECTION.
  4.  01  ptr-EnumWindowsProc    procedure-pointer.
  5.  01  num-ptr redefines ptr-EnumWindowsProc pic s9(9) comp-5.
  6.  
  7.  01  pid         pic s9(9) comp-5.
  8.  PROCEDURE       DIVISION.
  9.  
  10.      move pow-numeric of CmText1 to pid
  11.      
  12.      set ptr-EnumWindowsProc to entry "EnumWindowsProc@8"
  13.      
  14.      call "EnumWindows" with stdcall using by value num-ptr
  15.                                            by value pid

Ya nos cuentas qué tal ;)

Joseg 8 de noviembre de 2024 10:46

Perfecto :amigo:. Kuk entiendes mucho de esto !!
Gracias.

José

Kuk 8 de noviembre de 2024 17:58

@Joseg, de nada, para eso estamos :beber:

El problema era que oficialmente Fujitsu COBOL no trabaja con BY VALUE, pero de esta manera "hackeamos" el compilador quitándole este handicap y hacemos funcionar los CALL BY VALUE. Y con esta solución podemos reescribir el Windows por completo si queremos :rofl:

Kuk 10 de noviembre de 2024 16:57

@Joseg, he encontrado otra manera de hacerlo funcionar sin pasar por PROCEDURE-POINTER, lo cual me hace suponer que funcionaría incluso en PowerCOBOL v3 (que no tiene PROCEDURE-POINTER):

Código COBOL:
  1.  ENVIRONMENT     DIVISION.
  2.  DATA            DIVISION.
  3.  WORKING-STORAGE SECTION.
  4.  01  pid         pic s9(9) comp-5.
  5.  01  hModule     pic s9(9) comp-5.
  6.  01  pAddress    pic s9(9) comp-5.
  7.  
  8.  PROCEDURE       DIVISION.
  9.  
  10.      move pow-numeric of CmText1 to pid
  11.          
  12.      call "GetModuleHandleA" with stdcall using by value h"00" returning hModule
  13.          
  14.      call "GetProcAddress" with stdcall using by value hModule
  15.                                               by content "_EnumWindowsProc@8" & x"00"
  16.                                               returning pAddress
  17.      
  18.      call "EnumWindows" with stdcall using by value pAddress
  19.                                            by value pid

Funciona perfectamente, lo que pasa es que aquí uso WinAPI para obtener la dirección de la función.

A ver si un día lo pruebo en PowerCOBOL v3, debería funcionar, salvo que haya algún imprevisto.

Joseg 11 de noviembre de 2024 10:30

Buenos días Kuk :)

Se compila sin errores, pero el programa no se ejecuta.
Dando el mensaje:
EXCEPTION_ACCESS_VIOLATION(C0000005)

¿El programa "EnumWindowsProc" no tiene cambios?

Gracias,
José

Kuk 11 de noviembre de 2024 10:47

@Joseg, a lo mejor no le has pasado ningún Nº de PID, porque a mi me funciona sin fallos.

También haz "Rebuild ALL" por si acaso. Aveces falla si no recompilamos por completo el proyecto (para refrescar todos los cachés, el Build es incremental).

No, en "EnumWindowsProc" no he hecho ningún cambio.

Joseg 11 de noviembre de 2024 11:59

Cita:

Citación del post de Kuk (Mensaje 9627)
@Joseg, a lo mejor no le has pasado ningún Nº de PID, porque a mi me funciona sin fallos.

También haz "Rebuild ALL" por si acaso. Aveces falla si no recompilamos por completo el proyecto (para refrescar todos los cachés, el Build es incremental).

No, en "EnumWindowsProc" no he hecho ningún cambio.

Fiz "RebuildAll"
Powercobol 9.0

Código COBOL:
  1.      call "GetProcAddress" with stdcall using by value hModule
  2.                                               by content "EnumWindowsProc@8" & X"00"
  3.                                               returning pAddress

---> returning pAddress ---> pAddress = 0

Gracias

Kuk 11 de noviembre de 2024 12:46

@Joseg, es que el nombre que le pones no es correcto. Desde fuera se le añade un guion bajo, por eso en vez de EnumWindowsProc@8 debe ser _EnumWindowsProc@8, por eso no te funciona. Copia y pega el código que puse yo tal cual y verás que funciona. ;)

fastpho 11 de noviembre de 2024 13:19

Hola @Kuk , esto es buenisimo por que desde powercobol 5.0
no puedo usar procedure-pointer , habia intentado de
muchas formas poder llamar a una funcion y realizar un
callback , con este procediemiento ahora puedo
muchas gracias.

Probe el ejemplo de llamar a un .exe por Procees_id y me funciono
perfecto.

Saludos ...

Joseg 11 de noviembre de 2024 13:30

Cita:

Citación del post de Kuk (Mensaje 9629)
@Joseg, es que el nombre que le pones no es correcto. Desde fuera se le añade un guion bajo, por eso en vez de EnumWindowsProc@8 debe ser _EnumWindowsProc@8, por eso no te funciona. Copia y pega el código que puse yo tal cual y verás que funciona. ;)

Primero probé _EnumWindowsProc@8, pero igualmente sin éxito.
Estoy haciendo esta llamada desde una DLL, ¿solo funciona si la llamo desde un EXE?

Gracias

fastpho 11 de noviembre de 2024 13:41

Hola @Joseg , probe desde una dll y me funciono :mola::mola:
Saludos

Kuk 11 de noviembre de 2024 13:44

1 Archivos Adjunto(s)
@Joseg, has probado copiando mi código tal cual? A lo mejor hay algún pequeño error en alguna parte. Es muy raro que no te funcione, no tiene "explicación científica" y nos funciona a 2 personas... :piensa:
Si funciona en un EXE, en una DLL debe funcionar con más razón porque las DLLs son pensadas para compartir funciones, los EXE son los puntos de entrada (que lo pueden hacer también pero es más raro). En este caso con el EXE egenrado por PowerCOBOL va sujeto al Run-Time, tiene siempre expuesto el punto de entrada MAINFORM. Y si hay funciones añadidas por nosotros, también aparecen:

[ATTACH=CONFIG]1007[/ATTACH]

@fastpho, no sabía que PowerCOBOL v5 no tenía tampoco PROCEDURE-POINTER. Me alegro de que te sirva el invento :bien:

Joseg 11 de noviembre de 2024 16:51

1 Archivos Adjunto(s)
Cita:

Citación del post de Kuk (Mensaje 9633)
@Joseg, has probado copiando mi código tal cual? A lo mejor hay algún pequeño error en alguna parte. Es muy raro que no te funcione, no tiene "explicación científica" y nos funciona a 2 personas... :piensa:
Si funciona en un EXE, en una DLL debe funcionar con más razón porque las DLLs son pensadas para compartir funciones, los EXE son los puntos de entrada (que lo pueden hacer también pero es más raro). En este caso con el EXE egenrado por PowerCOBOL va sujeto al Run-Time, tiene siempre expuesto el punto de entrada MAINFORM. Y si hay funciones añadidas por nosotros, también aparecen:

[ATTACH=CONFIG]1007[/ATTACH]

@fastpho, no sabía que PowerCOBOL v5 no tenía tampoco PROCEDURE-POINTER. Me alegro de que te sirva el invento :bien:


Ok, usaré la primera forma. Llamarlo vía EXE funciona, vía DLL no funciona en absoluto.

Kuk 11 de noviembre de 2024 21:05

@Joseg, mea culpa, es que hay un detalle importante! Efectivamente, no puede funcionar TAL CUAL en una DLL porque GetModuleHandleA, si no le damos nombre del módulo sino que le pasamos un NULO, devuelve el hModule del EXE que se cargó inicialmente (el Main, vamos). Así que luego GetProcAddress, aunque lo llamamos en una DLL, le pasamos el hModule que obtuvimos del EXE, y evidentemente no encuentra "EnumWindowsProc", (a no ser que también esté presente en el EXE).

Por lo tanto, si lo queremos hacer SOLO en una DLL, lo que hay que hacer es pasarle a GetModuleHandleA el nombre de la DLL en parámetro en vez de un NULO. Es decir, reemplazar:
Código COBOL:
  1. call "GetModuleHandleA" with stdcall using by value h"00" returning hModule

por
Código COBOL:
  1. call "GetModuleHandleA" with stdcall using by content "RgestAPI.dll" returning hModule

O si no, dejar el fichero "EnumWindowsProc" en el EXE y no meterlo en la DLL. De hecho es por eso que a @fastpho le ha funcionado, seguro que ha dejado el fichero "EnumWindowsProc" en el EXE pero hizo la llamada a GetProcAddress en la DLL pasándole el hModule del EXE que obtuvo llamando a GetModuleHandleA con el parámetro a NULO (h"00").

No sé si me he explicado bien.

fastpho 11 de noviembre de 2024 21:35

1 Archivos Adjunto(s)
@Kuk , en el .EXE deje "EnumWindowsProc" y en la .DLL
solamente me ti y funciono
Código COBOL:
  1.     move pow-numeric of CmText1 to pid.
  2.      
  3.          
  4.      call "GetModuleHandleA" with stdcall using by value 0 returning hModule
  5.          
  6.      call "GetProcAddress" with stdcall using by value hModule
  7.                                               by content "_EnumWindowsProc@8" & X"00"
  8.                                               returning pAddress
  9.                                               display "pAddress: " , pAddress.
  10.      
  11.      call "EnumWindows" with stdcall using by value pAddress
  12.                                            by value pid
Pero viendo el error de @Joseg le inserte el "EnumWindowsProc" a la .DLL y seguia funcionando
Luego quite del .EXE y el EnumWindows y lo deje en la .DLL y efectivamente no funciono
Espero a ver sido claro
Saludos[ATTACH=CONFIG]1009[/ATTACH]

fastpho 11 de noviembre de 2024 23:25

@Kuk, efectivamente para usar una .DLL , y colocar el EnumWindowsProc en ella , se debe llamar pasandole un valor por contenido
Código COBOL:
  1.      MOVE "SFAC03.DLL" & x"00" TO  String-DLL.
  2.          
  3. *    call "GetModuleHandleA" with stdcall using by value 0 returning hModule
  4.       call "GetModuleHandleA" with stdcall using by CONTENT String-DLL  returning hModule
  5.      DISPLAY "hModule: " , hModule.  
Funciona correctamente
Gracias
Saludos ...

Joseg 12 de noviembre de 2024 12:31

Cita:

Citación del post de Kuk (Mensaje 9635)
@Joseg, mea culpa, es que hay un detalle importante! Efectivamente, no puede funcionar TAL CUAL en una DLL porque GetModuleHandleA, si no le damos nombre del módulo sino que le pasamos un NULO, devuelve el hModule del EXE que se cargó inicialmente (el Main, vamos). Así que luego GetProcAddress, aunque lo llamamos en una DLL, le pasamos el hModule que obtuvimos del EXE, y evidentemente no encuentra "EnumWindowsProc", (a no ser que también esté presente en el EXE).

Por lo tanto, si lo queremos hacer SOLO en una DLL, lo que hay que hacer es pasarle a GetModuleHandleA el nombre de la DLL en parámetro en vez de un NULO. Es decir, reemplazar:
Código COBOL:
  1. call "GetModuleHandleA" with stdcall using by value h"00" returning hModule

por
Código COBOL:
  1. call "GetModuleHandleA" with stdcall using by content "RgestAPI.dll" returning hModule

O si no, dejar el fichero "EnumWindowsProc" en el EXE y no meterlo en la DLL. De hecho es por eso que a @fastpho le ha funcionado, seguro que ha dejado el fichero "EnumWindowsProc" en el EXE pero hizo la llamada a GetProcAddress en la DLL pasándole el hModule del EXE que obtuvo llamando a GetModuleHandleA con el parámetro a NULO (h"00").

No sé si me he explicado bien.

Ahora si!!! Dominas completamente este tema!!!
También estudiaré un poco sobre el tema. El uso de la API de Windows puede ayudar en muchos escenarios.

Gracias

Kuk 12 de noviembre de 2024 14:54

@Joseg, no es que me lo sepa todo de memoria, ni falta que hace. Como decía, el problema era que el compilador de Fujitsu no funciona BY VLUE. Pero engañándolo como lo hacemos, sí que funciona. Y en tal caso podemos hacer cualquier cosa, todo lo que se hace en C se puede hacer en PowerCOBOL. El resto es ver la documentación ;)


La franja horaria es GMT +2. Ahora son las 02:41.

Powered by: vBulletin, Versión 3.8.7
Derechos de Autor ©2000 - 2026, Jelsoft Enterprises Ltd.