controls.cpp Corretta gestione palette dei colori execp.cpp Tentativo inutile di migliorare focus dopo lancio applicazioni mask.cpp Corretto metodo focus_field per maschere chiuse msksheet.cpp Migliorata getione ricerche dentro agli sheet git-svn-id: svn://10.65.10.50/trunk@3304 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			226 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			226 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <stdio.h>
 | |
| #include <xvt.h>
 | |
| 
 | |
| #if XVT_OS == XVT_OS_SCOUNIX
 | |
| #include <sys/fcntl.h>
 | |
| #include <sys/wait.h>
 | |
| #endif
 | |
| 
 | |
| #if XVT_OS == XVT_OS_WIN
 | |
| #define STRICT
 | |
| #include <windows.h>
 | |
| #include <toolhelp.h>
 | |
| #include <hlapi_c.h>
 | |
| #endif
 | |
| 
 | |
| #include <applicat.h>
 | |
| #include <execp.h> 
 | |
| #include <prefix.h>
 | |
| #include <utility.h>
 | |
| #include <window.h>
 | |
| #include <extcdecl.h>
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Controlla se il processo puo' essere eseguito
 | |
| //
 | |
| // @rdesc Ritorna i seguenti valori:
 | |
| //
 | |
| // @flag TRUE | Se l'applicazione puo' essere eseguita
 | |
| // @flag FALSE | Se l'applicazione non puo' essere eseguita
 | |
| bool TExternal_app::can_run() const
 | |
| 
 | |
| // @comm Se si opera sotto Windows si controlla se vi sono risorse necessarie
 | |
| //       per l'esecuzione del processo, altrimenti viene tornato sempre TRUE.
 | |
| {                    
 | |
| #if XVT_OS == XVT_OS_WIN
 | |
|   const TFixed_string p(_path);           
 | |
|   const bool big = p.find("cg0") == 0 && p.right(2) == "-1";
 | |
|   const int richieste = big ? 50 : 15;
 | |
|   const int libere = GetFreeSystemResources(GFSR_SYSTEMRESOURCES);
 | |
|   return libere >= richieste;
 | |
| #else
 | |
|   return TRUE;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Esegue il processo
 | |
| //
 | |
| // @rdesc Ritorna il codice di uscita del processo (-1 in caso di errore).
 | |
| word TExternal_app::run(
 | |
|   bool async,  // @parm Per eseguire il processo in parallelo (default FALSE)
 | |
|   bool utente) // @parm Permette di inserire il nome dell'utente nella riga 
 | |
|   //       di comando(default TRUE)
 | |
| 
 | |
|   // @comm Se <p asyn> e' FALSE aspetta che termini il processo in esecuzione prima di iniziare il nuovo
 | |
| 
 | |
| {
 | |
|   TString256 path(_path);                                  
 | |
|   
 | |
|   if (utente)
 | |
| #if XVT_OS == XVT_OS_WIN
 | |
|     path << " /u" << user();
 | |
| #else
 | |
|   path << " -u" << user();
 | |
| #endif    
 | |
|   
 | |
|   _error = 0;
 | |
|   _exitcode =  0;
 | |
| 
 | |
|   // save cwd
 | |
|   xvt_fsys_save_dir();
 | |
| 
 | |
| #if XVT_OS == XVT_OS_WIN
 | |
|   if (can_run())
 | |
|   {                
 | |
|     TFilename dir(_path); 
 | |
|     
 | |
|     dir = dir.path();
 | |
|     if (dir.not_empty())
 | |
|     {
 | |
|       DIRECTORY d;
 | |
|       
 | |
|       if (xvt_fsys_convert_str_to_dir((char *) (const char *) dir, &d))
 | |
|         xvt_fsys_set_dir(&d);
 | |
|     }
 | |
|     main_app().begin_wait();
 | |
|     HL_LOGOUT();
 | |
|     _exitcode = WinExec((char*)(const char*)path, SW_SHOW);
 | |
| 
 | |
|     if (_exitcode >= 32)
 | |
|     {        
 | |
|       if (!async)
 | |
|       {                            
 | |
|         TTemp_window tw(TASK_WIN);
 | |
|         if (utente) 
 | |
|         {
 | |
|           tw.iconize();
 | |
|           tw.deactivate();
 | |
|         }  
 | |
|         
 | |
|         HTASK child = NULL;
 | |
|         TASKENTRY te; te.dwSize = sizeof(TASKENTRY); 
 | |
|         for (bool ok = TaskFirst(&te); ok; ok = TaskNext(&te))
 | |
|           if (te.hInst == (HINSTANCE)_exitcode)
 | |
|           {
 | |
|             child = te.hTask;
 | |
|             break;
 | |
|           }  
 | |
|         
 | |
|         // Warning! child could be NULL if you run that beast called Foxpro        
 | |
|         
 | |
|         main_app().wait_for((word)child); 
 | |
|         for (byte i = 0; main_app().waiting() == (word)child; i++)
 | |
|         {
 | |
|           if (i == 0 && ok && TaskFindHandle(&te, child) == FALSE) 
 | |
|             break;
 | |
|           xvt_app_process_pending_events();
 | |
|         }
 | |
|         
 | |
|         if (utente) 
 | |
|         {
 | |
|           tw.maximize();
 | |
|           tw.activate();             
 | |
|           xvt_app_process_pending_events();
 | |
|         }  
 | |
|       }
 | |
|       xvt_statbar_refresh();
 | |
|     }  
 | |
|     main_app().end_wait();
 | |
|   } else _exitcode = 1;
 | |
| 
 | |
|   _error = _exitcode;
 | |
|   switch (_exitcode)
 | |
|   {
 | |
|   case 0:          
 | |
|   case 1:
 | |
|     error_box("Risorse insufficienti per eseguire '%s'", (const char*)_path); break;
 | |
|   case 2:
 | |
|   case 3:
 | |
|     error_box("Impossibile trovare '%s'", (const char*)_path); break;
 | |
|   case 16:
 | |
|     error_box("'%s' e' gia' in esecuzione", (const char*)_path); break;
 | |
|   default:
 | |
|     if (_exitcode < 32 && _exitcode != 8)
 | |
|       error_box("Impossibile eseguire '%s':\nErrore %u", (const char*)_path, _exitcode); 
 | |
|     else
 | |
|     {
 | |
|       if (_exitcode != 8) _error = 0;
 | |
|       _exitcode = 0;  
 | |
|     }  
 | |
|     break;
 | |
|   }  
 | |
| #else
 | |
| 
 | |
|   switch (fork())
 | |
|   {
 | |
|   case -1:
 | |
|     _error = errno;
 | |
|     _exitcode = -1;
 | |
|     break;
 | |
|   case 0:
 | |
|     const char* s = strdup(path);
 | |
|     char* p = strchr(s, ' ');
 | |
|     if (p) *p = '\0';
 | |
|     const char* pathn = strdup(s);
 | |
|     const char* args[21];
 | |
|     int i = 0;
 | |
|     args[i++] = pathn;
 | |
|     while ((i < 20) && (p))
 | |
|     {
 | |
|       s = p + 1;
 | |
|       p = strchr(s, ' ');
 | |
|       if (p) *p = '\0';
 | |
|       args[i++] = strdup(s);
 | |
|     }
 | |
|     args[i] = NULL;
 | |
|     for (i = 3; i < _NFILE; i++) fcntl(i,F_SETFD,1);
 | |
|     // execvp( path, NULL);
 | |
|     execvp ( pathn , args );
 | |
|     exit ( -1 );
 | |
|   default:
 | |
|     if(wait(&_exitcode) == -1)
 | |
|     {
 | |
|       error_box("Impossibile eseguire '%s':\nErrore %d", (const char*)_path, _exitcode);
 | |
|       _exitcode = -1;
 | |
|     }
 | |
|     else _exitcode = _exitcode >> 8;
 | |
|     break;
 | |
|   }
 | |
|   _error = errno;
 | |
|   xvt_app_escape(XVT_ESC_CH_REFRESH);
 | |
| 
 | |
| #endif
 | |
| 
 | |
|   // restore cwd
 | |
|   xvt_fsys_restore_dir();
 | |
| 
 | |
|   // update counts
 | |
|   if (_exitcode == 0)
 | |
|     _count++;
 | |
| #if XVT_OS == XVT_OS_WIN    
 | |
|   // Ignora volutamente il return code da HL_LOGIN(). Se va bene riprende il posto
 | |
|   // altrimenti fa lo stesso. Infatti puo' capitare con una chiave di rete, che
 | |
|   // nel lasso di tempo trascorso dalla HL_LOGOUT() dell'applicazione chiamata,
 | |
|   // a questa HL_LOGIN() [approssimativamente qualche decimo di secondo], qualche altro
 | |
|   // programma si inserisca, occupando magari anche l'ultimo posto disponibile.
 | |
|   // Quindi se si  verificasse tale sfigatissima condizione, sicuramente
 | |
|   // non ci saranno piu' posti liberi nell'HL_server: il programma comunque non
 | |
|   // puo' interrompersi a meta'; ecco perche il valore di ritorno di HL_LOGIN viene
 | |
|   // ignorato.
 | |
|   HL_LOGIN(ModAd, DONT_CARE, REFKEY, VERKEY);
 | |
| #endif
 | |
|   return _exitcode;
 | |
| }
 | |
| 
 | |
| TExternal_app::TExternal_app(const char* p)
 | |
| {
 | |
|   _path =  p;
 | |
|   _count = 0;
 | |
|   _error = 0;
 | |
|   _exitcode =  0;
 | |
| }
 |