FoxPress – Marzo 2005

 

Haz aplicaciones multi-tarea

 

 

 tareas.prg

Por Eddy Maue

 

Durante la ejecución de una aplicación ciertas tareas  pueden consumir bastante tiempo. Como por ejemplo la búsqueda de ficheros en un disco, las llamadas a un servicio web o esperar a que una página sea cargada en memoria.

Esa espera, puede ser desagradable para ti y para el usuario. ¿ Por qué no ejecutar sobre un proceso separado vuestra aplicación? Windows es un sistema multitarea y la función Createprocess del kernel32.Dll permite realizar la ejecución de una tarea sobre un proceso separado de vuestra aplicación.

Para hacer eso, crea un nuevo proyecto. Dale el nombre de vuestra tarea y transformalo en ejecutable.

En vuestro proyecto reemplazar la llamada a vuestra tarea por:

ExecProcess("x:\MaTache.exe",p1,p2,...,pn)

De esta manera la tarea se ejecutará sobre un proceso separado de vuestra aplicación.

 

* Adaptado por Eddy Maue
* Decembre le 23,2004
* = execprocess("c:\MonExecutable.exe","1","2")
* possibilidad de hasta 17 parametros
*
* retourne -1 si la tâche est exécutée
* retourne 0 si la tache n'est pas  exécutée

Function ExecProcess
   Lparameters cFile,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p17
   Local ;
      i As Integer

   For i = 2 To Parameters()
      cTransform = "transform(p"+Transform(i)+")"
      m.cFile = m.cFile + " '"+&cTransform+"' "

   Endfor


   #Define NORMAL_PRIORITY_CLASS 32
   #Define IDLE_PRIORITY_CLASS 64
   #Define HIGH_PRIORITY_CLASS 128
   #Define REALTIME_PRIORITY_CLASS 1600

   * Return code from WaitForSingleObject() if
   * it timed out.
   #Define WAIT_TIMEOUT 0x00000102

   * This controls how long, in milli secconds, WaitForSingleObject()
   * waits before it times out. Change this to suit your preferences.
   #Define WAIT_INTERVAL 200

   Declare Integer CreateProcess In kernel32.Dll ;
      INTEGER lpApplicationName, ;
      STRING lpCommandLine, ;
      INTEGER lpProcessAttributes, ;
      INTEGER lpThreadAttributes, ;
      INTEGER bInheritHandles, ;
      INTEGER dwCreationFlags, ;
      INTEGER lpEnvironment, ;
      INTEGER lpCurrentDirectory, ;
      STRING @lpStartupInfo, ;
      STRING @lpProcessInformation

   Declare Integer WaitForSingleObject In kernel32.Dll ;
      INTEGER hHandle, Integer dwMilliseconds

   Declare Integer CloseHandle In kernel32.Dll ;
      INTEGER hObject

   Declare Integer GetLastError In kernel32.Dll


   * STARTUPINFO is 68 bytes, of which we need to
   * initially populate the 'cb' or Count of Bytes member
   * with the overall length of the structure.
   * The remainder should be 0-filled
   Start = long2str(68) + Replicate(Chr(0), 64)

   * PROCESS_INFORMATION structure is 4 longs,
   * or 4*4 bytes = 16 bytes, which we'll fill with nulls.
   process_info = Replicate(Chr(0), 16)


   * Call CreateProcess, obtain a process handle. Treat the
   * application to run as the 'command line' argument, accept
   * all other defaults. Important to pass the start and
   * process_info by reference.
   RetCode = CreateProcess(0, m.cFile+Chr(0), 0, 0, 1, ;
      NORMAL_PRIORITY_CLASS, 0, 0, @Start, @process_info)

   * Unable to run, exit now.
   If RetCode = 0
      =Messagebox("Error occurred. Error code: ", GetLastError())
      Return 0
   Endif

   Local lTerminer
   Do While !lTerminer
      * Use timeout of TIMEOUT_INTERVAL msec so the display
      * will be updated. Otherwise, the VFP window never repaints until
      * the loop is exited.
      If !WaitForSingleObject(RetCode, WAIT_INTERVAL) != WAIT_TIMEOUT
         DoEvents
      Else
         lTerminer = .T.
         * Show a message box when we're done.
         * Close the process handle afterwards.
         RetCode = CloseHandle(RetCode)
         return -1
      Endif
   Enddo


   ********************
Function long2str
   ********************
   * Passed : 32-bit non-negative numeric value (m.longval)
   * Returns : ASCII character representation of passed
   *           value in low-high format (m.retstr)
   * Example :
   *    m.long = 999999
   *    m.longstr = long2str(m.long)

   Parameters m.longval

   Private i, m.retstr

   m.retstr = ""
   For i = 24 To 0 Step -8
      m.retstr = Chr(Int(m.longval/(2^i))) + m.retstr
      m.longval = Mod(m.longval, (2^i))
   Next

   Return m.retstr


   *******************
Function str2long
   *******************
   * Passed:  4-byte character string (m.longstr)
   *   in low-high ASCII format
   * returns:  long integer value
   * example:
   *   m.longstr = "1111"
   *   m.longval = str2long(m.longstr)

   Parameters m.longstr
   Private i, m.retval

   m.retval = 0
   For i = 0 To 24 Step 8
      m.retval = m.retval + (Asc(m.longstr) * (2^i))
      m.longstr = Right(m.longstr, Len(m.longstr) - 1)
   Next
   

Return m.retval

 

 

 

FoxPress – Marzo de 2005