1195 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1195 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #define XVT_INCL_NATIVE
 | |
| 
 | |
| #include <applicat.h>
 | |
| #include <colors.h>
 | |
| #include <config.h>
 | |
| #include <controls.h>
 | |
| #include <mask.h>
 | |
| #include <urldefid.h>
 | |
| #include <utility.h>     
 | |
|  
 | |
| #include <statbar.h> 
 | |
| 
 | |
| #if XVT_OS == XVT_OS_SCOUNIX
 | |
| extern "C" { long nap(long period); }
 | |
| #endif
 | |
| 
 | |
| // ERROR HOOK che intercetta errori XVT
 | |
| // put breakpoint here
 | |
| 
 | |
| BOOLEAN error_hook(XVT_ERRMSG err, DATA_PTR)
 | |
| {
 | |
|   const XVT_ERRSEV sev = xvt_errmsg_get_sev_id(err);
 | |
| #ifdef DBG
 | |
|   return FALSE;
 | |
| #else
 | |
|   return sev < SEV_ERROR;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| #if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32
 | |
| 
 | |
| #ifndef ATTR_WIN_USE_CTL3D
 | |
| #include <ctl3d.h>
 | |
| #endif
 | |
| #endif
 | |
| 
 | |
| HIDDEN HINSTANCE HInstance;  
 | |
| const word WM_WAKEUP = RegisterWindowMessage("WAKEUP");
 | |
| 
 | |
| 
 | |
| static BOOLEAN event_hook(HWND hwnd,
 | |
|                           UINT msg,
 | |
|                           UINT wparam,
 | |
|                           ULONG lparam,
 | |
|                           long* ret)
 | |
| {
 | |
|   switch(msg)     
 | |
|   {      
 | |
| #ifndef ATTR_WIN_USE_CTL3D
 | |
|   case WM_SYSCOLORCHANGE:
 | |
|     Ctl3dColorChange();
 | |
|     break;
 | |
| #endif    
 | |
|   case WM_MENUCHAR:
 | |
|     if (wparam > ' ' && wparam <= 'z')
 | |
|     {
 | |
|       WINDOW win = cur_win();
 | |
|       if (win != NULL_WIN)
 | |
|       {      
 | |
| //        TWindow* w = (TWindow*)xvt_vobj_get_data(win);
 | |
|         const KEY key = toupper(wparam)+K_CTRL;
 | |
| //        w->on_key(key);
 | |
|         dispatch_e_char(win, key);
 | |
|         *ret = 2 << 8;
 | |
|       }  
 | |
|     }   
 | |
|     break;  
 | |
|   case WM_KEYDOWN:
 | |
|     if (wparam == VK_F1)
 | |
|     {    
 | |
|       if ((lparam & (1<<29)) == 0)             // Il tasto alt non e' premuto
 | |
|       {      
 | |
|         KEY k = K_F1;
 | |
|         int sc = GetAsyncKeyState(VK_CONTROL); // Stato del tasto control 
 | |
|         if (sc & 1) k += K_CTRL;
 | |
|         
 | |
|         int ss = GetAsyncKeyState(VK_SHIFT);   // Stato del tasto shift 
 | |
|         if (ss & 1) k += K_SHIFT;
 | |
| 
 | |
|         WINDOW win = cur_win();
 | |
|         if (win != NULL_WIN)
 | |
|           dispatch_e_char(win, k);
 | |
|       }  
 | |
|     }
 | |
|     break;
 | |
|   default:  
 | |
|     if (msg == WM_WAKEUP && wparam == main_app().waiting())
 | |
|       main_app().wake_up();
 | |
|     break;
 | |
|   }    
 | |
| 
 | |
|   return TRUE; // Continua col processo normale
 | |
| }
 | |
| 
 | |
| #if XVT_OS == XVT_OS_WIN
 | |
| #include <string.h>
 | |
| #include <ctype.h>
 | |
| #pragma hdrstop
 | |
| #include "prochook.h"
 | |
| #define MAX_PATH 260    // This really should be in WINDOWS.H, but is
 | |
|                         // inexplicably hard-coded into the data structures
 | |
| 
 | |
| extern "C" { WINDOW xvtwi_hwnd_to_window(HWND); }
 | |
| 
 | |
| short CHARX = 8;
 | |
| short ROWY = -GetSystemMetrics(SM_CYSCREEN) / 25;    // Not so good!
 | |
| short CHARY = 14;
 | |
| short BASEY = 12;
 | |
| 
 | |
| // By Matt Pietrek                           
 | |
| //########################################################################
 | |
| // Code that does the real work
 | |
| //########################################################################                          
 | |
| 
 | |
| //
 | |
| // Central function that modifies a module table to trick the loader
 | |
| // into letting a second instance of a multiple data segment program run.
 | |
| //
 | |
| int MungeModuleHeader( HINSTANCE hInstance, BOOL fMunge )
 | |
| { 
 | |
|     HMODULE hModuleSel;
 | |
|     LPSTR lpszModName, lpszFileName;
 | |
|     BYTE cbModuleName;
 | |
|     static BOOL fResidentNamesMunged = FALSE;
 | |
|     
 | |
|     hModuleSel = SELECTOROF(    // Convert the HINSTANCE to an HMODULE
 | |
|         GlobalLock(GetModuleHandle((LPSTR)MAKELP(0,hInstance))));
 | |
| 
 | |
|     if ( hModuleSel == 0 )      // Make sure we succeeded.
 | |
|         return 0;
 | |
| 
 | |
|     //
 | |
|     // First, we'll take care of the resident names table
 | |
|     //
 | |
|     if ( FALSE == fResidentNamesMunged )
 | |
|     {
 | |
|         // Make pointers to the module name in the resident names table
 | |
|         lpszModName = (LPSTR)MAKELP(hModuleSel,
 | |
|                                     *(WORD FAR *)MAKELP(hModuleSel, 0x26) );
 | |
| 
 | |
|         // Get the module name length, and advance to the actual string
 | |
|         cbModuleName = *lpszModName++;   // First byte is a length byte
 | |
|         
 | |
|         // Convert the first uppercase letter of the modulename to lowercase
 | |
|         while ( cbModuleName )
 | |
|         {
 | |
|             if ( isupper(*lpszModName) )
 | |
|             {
 | |
|                 *lpszModName = tolower(*lpszModName); break;
 | |
|             }
 | |
|             cbModuleName--; lpszModName++;
 | |
|         }
 | |
|         
 | |
|         if ( cbModuleName == 0 )    // Make sure we succeeded
 | |
|             return 0;
 | |
| 
 | |
|         // Remember that we've done this, so that we don't bother doing
 | |
|         // it in the future.
 | |
|         fResidentNamesMunged = TRUE;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Now, we'll turn our attention to the module file name in the OFSTRUCT
 | |
|     //
 | |
|     lpszFileName = (LPSTR)MAKELP(hModuleSel,
 | |
|                                  *(WORD FAR *)MAKELP(hModuleSel, 0x0A));
 | |
| 
 | |
|     // Position to the end of the filename. First byte is a length byte
 | |
|     lpszFileName += *lpszFileName - 1;
 | |
| 
 | |
|     // If we're munging, added 0x30 to the last character value, otherwise
 | |
|     // subtract 0x30.  0x30 is chosen completely at random.
 | |
|     if ( fMunge )
 | |
|         *lpszFileName += 0x30;
 | |
|     else
 | |
|         *lpszFileName -= 0x30;
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| //########################################################################
 | |
| // This section watches calls to LoadModule and munges the EXE's module
 | |
| // database as needed.
 | |
| //########################################################################
 | |
| 
 | |
| HIDDEN NPHOOKCHILD npHookLoadModule = 0;
 | |
| HIDDEN char szOurFileName[MAX_PATH];
 | |
| 
 | |
| HINSTANCE
 | |
| WINAPI
 | |
| __export MultInst95LoadModule( LPCSTR lpszModuleName,
 | |
|                                LPVOID lpvParameterBlock )
 | |
| {
 | |
|     HINSTANCE retValue;
 | |
| 
 | |
|     // Uppercase the name of the module name that was passed to LoadModule
 | |
|     char szNewFileName[MAX_PATH];
 | |
|     lstrcpy( szNewFileName, lpszModuleName );
 | |
|     strupr( szNewFileName );
 | |
| 
 | |
|     // Compare the incoming filename to our EXE's module name.  If they
 | |
|     // don't match, we don't need to bother munging the module database
 | |
|     BOOL fSecondInstance = strstr(szOurFileName, szNewFileName) ? TRUE:FALSE;
 | |
| 
 | |
|     // Unhook our LoadModule hook so that we can call the real LoadModule
 | |
|     ProcUnhook( npHookLoadModule );
 | |
| 
 | |
|     // Munge module database if needed
 | |
|     if ( fSecondInstance )
 | |
|         MungeModuleHeader( HInstance, TRUE );
 | |
| 
 | |
|     // Call the original LoadModule code
 | |
|     retValue = LoadModule( lpszModuleName, lpvParameterBlock );
 | |
| 
 | |
|     // Unmunge module database if needed
 | |
|     if ( fSecondInstance )
 | |
|         MungeModuleHeader( HInstance, FALSE );
 | |
| 
 | |
|     // Reinstall our LoadModule hook so that we see future loads
 | |
|     ProcHook( npHookLoadModule );
 | |
|     
 | |
|     return retValue;
 | |
| }
 | |
| 
 | |
| BOOL deny_another_instance()
 | |
| { 
 | |
|   if ( !npHookLoadModule )
 | |
|       return FALSE;
 | |
| 
 | |
|   SetProcRelease( npHookLoadModule );
 | |
|   npHookLoadModule = 0;
 | |
|     
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| BOOL allow_another_instance()
 | |
| { 
 | |
| #ifdef DBG
 | |
|   const bool noMunge = getenv("NOMUNGE") != NULL;
 | |
|   
 | |
|   if (noMunge) 
 | |
|     return FALSE;
 | |
| #endif
 | |
|           
 | |
|   if ( npHookLoadModule )
 | |
|       return TRUE;
 | |
| 
 | |
|   // Get the EXE's filename into a global string variable and uppercase it
 | |
|   GetModuleFileName( HInstance, szOurFileName, sizeof(szOurFileName) );
 | |
|   strupr( szOurFileName );
 | |
| 
 | |
|   // Create a MakeProcInstance thunk so that our callback function
 | |
|   // will always be using the correct DS selector
 | |
|   FARPROC lpfnMPI
 | |
|       = MakeProcInstance( (FARPROC)MultInst95LoadModule, HInstance );
 | |
| 
 | |
|   if ( !lpfnMPI )
 | |
|       return FALSE;
 | |
| 
 | |
|   // Call PROCHOOK.DLL to hook calls to LoadModule
 | |
|   npHookLoadModule = SetProcAddress(  (FARPROC)LoadModule,
 | |
|                                       lpfnMPI, FALSE );
 | |
|     
 | |
|   return (BOOL)npHookLoadModule;
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Calcola dimensioni e posizione di un controllo contenuto nella finestra
 | |
| //
 | |
| // @rdesc Ritorna il rettangolo
 | |
| RCT& resize_rect(
 | |
|   short x,        // @parm Coordinata x del controllo (espresso in caratteri)
 | |
|   short y,        // @parm Coordinata y del controllo (espresso in caratteri)
 | |
|   short dx,       // @parm Larghezza del controllo (espresso in caratteri)
 | |
|   short dy,       // @parm Altezza del controllo (espresso in caratteri)
 | |
|   WIN_TYPE wt,    // @parm Tipo di controllo da creare
 | |
|   WINDOW parent)  // @parm Identificatore della finestra padre
 | |
| {
 | |
|   static RCT r;      
 | |
|   
 | |
|   if (parent != TASK_WIN)
 | |
|   {
 | |
|     if (xvt_vobj_get_type(parent) == W_PLAIN) // Mask with Toolbar
 | |
|     {
 | |
|       if (y >= 0) 
 | |
|       {
 | |
|         const TMask* m = (const TMask*)xvt_vobj_get_data(parent);
 | |
|         if (parent != m->toolwin())
 | |
|           y++;
 | |
|       }  
 | |
|       if (x > 0 || (wt != WO_TE && x == 0))
 | |
|       { 
 | |
|         RCT pc; xvt_vobj_get_client_rect(parent, &pc);                   // Get parent window size
 | |
|         const int width = pc.right;               
 | |
|         const int tot = 80*CHARX;
 | |
|         if (width > tot) x += (width-tot) / (CHARX<<1);
 | |
|       }
 | |
|     }
 | |
|     wt = WC_EDIT;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     if (ROWY <= 0)         // Not yet initialized
 | |
|     {
 | |
|       RCT pc; xvt_vobj_get_client_rect(TASK_WIN, &pc);
 | |
|       ROWY = (pc.bottom - pc.top) / 23;
 | |
|     }  
 | |
|   }
 | |
| 
 | |
|   switch (wt)
 | |
|   {
 | |
|   case WC_EDIT :
 | |
|     r.left   = (x+1)*CHARX;
 | |
|     r.top    = y*ROWY;
 | |
|     r.right  = dx*CHARX;
 | |
|     r.bottom = (CHARY << 1) - BASEY;
 | |
|     if (dy > 1)
 | |
|       r.bottom += ROWY*(dy-1);
 | |
|     break;
 | |
|   case W_DOC:
 | |
|     r.left   = x * CHARX;
 | |
|     r.top    = y * ROWY;
 | |
|     r.right  = dx * CHARX;
 | |
|     r.bottom = dy * CHARY;
 | |
|     break;
 | |
|   default:
 | |
|     r.left   = x * CHARX;
 | |
|     r.top    = y * ROWY;
 | |
|     r.right  = (dx+2)*CHARX;
 | |
|     r.bottom = dy*ROWY-1;
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   if (x < 0 || y < 0 || dx <= 0 || dy <= 0)
 | |
|   {
 | |
|     RCT pc;
 | |
|     if (parent == NULL_WIN) parent = TASK_WIN;
 | |
|     xvt_vobj_get_client_rect(parent, &pc);     // Get parent window size
 | |
|     const short MAXX = pc.right;
 | |
|     const short MAXY = pc.bottom;
 | |
| 
 | |
|     if (x < 0)
 | |
|     {
 | |
|       x = -x;
 | |
|       if (wt != WC_EDIT && x == 1) x = 11;
 | |
|       if (x > 10)
 | |
|       {
 | |
|         const int num = x/10 -1;
 | |
|         const int tot = x%10;
 | |
|         const int spc = (MAXX - tot*r.right) / (tot+1);
 | |
|         r.left = spc + num*(spc+r.right);
 | |
|       }
 | |
|       else
 | |
|         r.left = MAXX - r.right - x*CHARX;
 | |
|     }
 | |
| 
 | |
|     if (y < 0)
 | |
|     {
 | |
|       y = -y;
 | |
|       if (wt != WC_EDIT && y == 1) y = 11;
 | |
|       if (y > 10)
 | |
|       {
 | |
|         const int num = y/10 -1;
 | |
|         const int tot = y%10;
 | |
|         const int spc = (MAXY - tot*r.bottom) / (tot+1);
 | |
|         r.top = spc + num*(spc+r.bottom);
 | |
|       }
 | |
|       else
 | |
|         r.top = MAXY - r.bottom - (y-1)*ROWY;
 | |
|     }
 | |
| 
 | |
|     if (dx <= 0) r.right = MAXX + dx*CHARX;
 | |
|     else r.right += r.left;
 | |
|     if (dy <= 0) r.bottom = MAXY + dy*ROWY;
 | |
|     else r.bottom += r.top;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     r.right += r.left;
 | |
|     r.bottom += r.top;
 | |
|   }
 | |
|   return r;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Emette un suono di default
 | |
| void beep()
 | |
| { xvt_scr_beep(); }
 | |
| 
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Event Handling
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TEvent_manager
 | |
| {             
 | |
|   enum { MAX = 16 };
 | |
|   WINDOW _w[MAX];
 | |
|   EVENT _e[MAX];
 | |
|   int _begin, _end;
 | |
|   
 | |
| public:  
 | |
|   TEvent_manager() : _begin(0), _end(0) {}
 | |
|   void push(WINDOW win, const EVENT& event);
 | |
|   void pop();
 | |
| };
 | |
| 
 | |
| HIDDEN TEvent_manager EM;
 | |
| 
 | |
| void TEvent_manager::push(WINDOW w, const EVENT& e)
 | |
| {    
 | |
|   CHECK(w, "You shouldn't send events to NULL_WIN!");
 | |
|   _w[_end] = w;
 | |
|   _e[_end] = e;
 | |
|   const int next = (_end+1) % MAX;
 | |
|   if (next == _begin)
 | |
|     warning_box("Hey, clicca piu' piano!");
 | |
|   else  
 | |
|     _end = next;  
 | |
| }
 | |
| 
 | |
| void TEvent_manager::pop()
 | |
| {
 | |
|   if (_begin != _end)
 | |
|   {
 | |
|     const int i = _begin;
 | |
|     _begin = (++_begin) % MAX;                     // Other events may occur!
 | |
|     xvt_win_dispatch_event(_w[i], &_e[i]);
 | |
|   }  
 | |
|   
 | |
|   WINDOW cw = cur_win();
 | |
|   if (cw != NULL_WIN)
 | |
|   {
 | |
|     TWindow* w = (TWindow*)xvt_vobj_get_data(cw);
 | |
|     CHECK(w != NULL, "Can't idle NULL window");
 | |
|     w->on_idle();
 | |
|   }  
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Processa tutti gli eventi rimasti in coda
 | |
| void do_events()
 | |
| {
 | |
|   xvt_app_process_pending_events();
 | |
|   EM.pop();
 | |
| #if XVT_OS == XVT_OS_SCOUNIX
 | |
|   nap(20);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Permette di convertire un evento carattere in un codice carattere premuto
 | |
| //
 | |
| // @rdesc Ritorna il codice del carattere corrispondente all'evento
 | |
| KEY e_char_to_key(
 | |
|   const EVENT* ep) // @parm Evento da codificare
 | |
| 
 | |
|   // @comm Viene controllato se l'evento e' un e_car e viene tradotto, in caso
 | |
|   //       controrio viene emesso un segnale d'errore.
 | |
| {
 | |
|   CHECK(ep->type == E_CHAR, "I can't convert a Non-E_CHAR event to a key");
 | |
| 
 | |
|   KEY key = ep->v.chr.ch;
 | |
|   if (key < K_INS || key > K_HELP)
 | |
|   {
 | |
|     if (ep->v.chr.shift && (key < ' ' || key >= K_UP)) key += K_SHIFT;
 | |
|     if (ep->v.chr.control && key >=  ' ') key += K_CTRL;
 | |
|   }
 | |
|   return key;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Simula un evento
 | |
| 
 | |
| void dispatch_event(
 | |
|   WINDOW win,      // @parm Finestra destinataria dell'evento
 | |
|   const EVENT& e,  // @parm Evento da generare
 | |
|   bool post) 
 | |
| { 
 | |
|   if (post)
 | |
|     EM.push(win, e);
 | |
|   else
 | |
|     xvt_win_dispatch_event(win, (EVENT*)&e);
 | |
| }
 | |
| 
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Simula la scelta di una voce di menu
 | |
| void dispatch_e_menu(
 | |
|   WINDOW win,    // @parm Finestra che contiene il menu
 | |
|   MENU_TAG item) // @parm Voce del menu da selezionare
 | |
| 
 | |
|   // @xref <f dispatch_e_char> <f dispatch_e_scroll>
 | |
| {
 | |
|   EVENT e; memset(&e, 0, sizeof(e));
 | |
|   e.type = E_COMMAND;
 | |
|   e.v.cmd.tag = item;
 | |
|   e.v.cmd.shift = e.v.cmd.control = 0;
 | |
|   dispatch_event(win, e, TRUE);
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Simula la scelta di una combinazione di caratteri
 | |
| void dispatch_e_char(
 | |
|   WINDOW win,  // @parm Finestra che contiene il menu
 | |
|   KEY key)     // @parm Combinazione di caratteri da utilizzare
 | |
| 
 | |
|   // @xref <f dispatch_e_menu> <f dispatch_e_scroll>
 | |
| {
 | |
|   EVENT e; memset(&e, 0, sizeof(e));
 | |
| 
 | |
|   e.type = E_CHAR;
 | |
| 
 | |
|   if (key > K_CTRL)  
 | |
|   { e.v.chr.control = TRUE; key -= K_CTRL;  }
 | |
|   
 | |
|   if (key > K_SHIFT) 
 | |
|   { e.v.chr.shift   = TRUE; key -= K_SHIFT; }
 | |
|   
 | |
|   e.v.chr.ch = short(key);
 | |
| 
 | |
|   dispatch_event(win, e, TRUE);
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Simula uno scroll all'interno di una finestra
 | |
| void dispatch_e_scroll(
 | |
|   WINDOW win,  // @parm Finestra nella quale operare
 | |
|   KEY key)     // @parm Tasto utilizzato per lo scroll nella finestra
 | |
| 
 | |
|   // @xref <f dispatch_e_menu> <f dispatch_e_char>
 | |
| {
 | |
|   EVENT e; memset(&e, 0, sizeof(e));
 | |
|   EVENT_TYPE& t = e.type;
 | |
|   SCROLL_CONTROL& w = e.v.scroll.what;
 | |
|   short& p = e.v.scroll.pos;
 | |
| 
 | |
|   w = SC_NONE;
 | |
| 
 | |
|   switch(key)
 | |
|   {
 | |
|   case K_HOME:
 | |
|     t = E_HSCROLL;
 | |
|     w = SC_THUMB;
 | |
|     p = 0;
 | |
|     break;
 | |
|   case K_LHOME:
 | |
|     t = E_VSCROLL;
 | |
|     w = SC_THUMB;
 | |
|     p = 0;
 | |
|     break;
 | |
|   case K_UP:
 | |
|     t = E_VSCROLL;
 | |
|     w = SC_LINE_UP;
 | |
|     break;
 | |
|   case K_DOWN:
 | |
|     t = E_VSCROLL;
 | |
|     w = SC_LINE_DOWN;
 | |
|     break;
 | |
|   case K_BTAB:
 | |
|     t = E_HSCROLL;
 | |
|     w = SC_PAGE_UP;
 | |
|     break;
 | |
|   case K_TAB:
 | |
|     t = E_HSCROLL;
 | |
|     w = SC_PAGE_DOWN;
 | |
|     break;
 | |
|   case K_PREV:
 | |
|     t = E_VSCROLL;
 | |
|     w = SC_PAGE_UP;
 | |
|     break;
 | |
|   case K_NEXT:
 | |
|     t = E_VSCROLL;
 | |
|     w = SC_PAGE_DOWN;
 | |
|     break;
 | |
|   case K_LEFT:
 | |
|     t = E_HSCROLL;
 | |
|     w = SC_LINE_UP;
 | |
|     break;
 | |
|   case K_RIGHT:
 | |
|     t = E_HSCROLL;
 | |
|     w = SC_LINE_DOWN;
 | |
|     break;
 | |
|   default:
 | |
|     break;
 | |
|   };
 | |
| 
 | |
|   if (w != SC_NONE) 
 | |
|     dispatch_event(win, e, FALSE);
 | |
| }    
 | |
| 
 | |
| void set_xvt_hooks()
 | |
| {
 | |
|   xvt_vobj_set_attr(NULL_WIN,ATTR_ERRMSG_HANDLER, (long)error_hook);
 | |
|   xvt_vobj_set_attr(NULL_WIN,ATTR_WIN_PM_DRAWABLE_TWIN, TRUE);
 | |
| 
 | |
| #if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32
 | |
|   xvt_vobj_set_attr(NULL_WIN, ATTR_EVENT_HOOK, (long)event_hook); 
 | |
| 
 | |
| #ifdef ATTR_WIN_USE_CTL3D
 | |
|   xvt_vobj_set_attr(NULL_WIN, ATTR_WIN_USE_CTL3D, TRUE);
 | |
| #endif  
 | |
| 
 | |
|   long twin_style = WSF_ICONIZABLE | WSF_CLOSE | WSF_SIZE;  
 | |
|   const int scx = GetSystemMetrics(SM_CXSCREEN);
 | |
|   if (scx == 640 && get_os_type() == os_Windows95)
 | |
|   {
 | |
|     const int scy = GetSystemMetrics(SM_CYSCREEN);
 | |
|     const int bcx = GetSystemMetrics(SM_CXFRAME); 
 | |
|     const int bcy = GetSystemMetrics(SM_CYFRAME);
 | |
|     static RCT rct;
 | |
|     rct.left   = -bcx;
 | |
|     rct.top    = GetSystemMetrics(SM_CYCAPTION)-bcy-1;
 | |
|     rct.right  = scx+bcx;
 | |
|     rct.bottom = scy+bcy;
 | |
|     xvt_vobj_set_attr(NULL_WIN, ATTR_WIN_PM_TWIN_STARTUP_RCT, long(&rct));
 | |
|   }
 | |
|   else
 | |
|     twin_style |= WSF_MAXIMIZED;  
 | |
|   
 | |
|   xvt_vobj_set_attr(NULL_WIN,ATTR_WIN_PM_TWIN_STARTUP_STYLE, twin_style);
 | |
| 
 | |
| #endif
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Stabilisce i parametri standard dei controlli
 | |
| void customize_controls(
 | |
|   bool on) // @parm Permette di inizializzare (TRUE) o scaricare (FALSE) i parametri
 | |
| {    
 | |
|   if (on)
 | |
|   {
 | |
| #if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32
 | |
| 
 | |
| #ifndef ATTR_WIN_USE_CTL3D
 | |
|     HInstance = (HINSTANCE)xvt_vobj_get_attr(NULL_WIN, ATTR_WIN_INSTANCE);
 | |
|     Ctl3dRegister(HInstance);
 | |
|     Ctl3dAutoSubclass(HInstance);
 | |
| #endif    
 | |
| 
 | |
| #endif    
 | |
| 
 | |
|     customize_colors();
 | |
|     init_controls();
 | |
|   }
 | |
|   else
 | |
|   {       
 | |
| #if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32
 | |
| #ifndef ATTR_WIN_USE_CTL3D
 | |
|     Ctl3dUnregister(HInstance);
 | |
| #endif    
 | |
|     deny_another_instance();
 | |
| #endif      
 | |
|     free_controls();
 | |
|   }
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di settare il font attivo nella finestra
 | |
| void xvt_set_font(
 | |
|   WINDOW win,         // @parm Finestra nella quale settare il font
 | |
|   const char* family, // @parm Nome del font da settare
 | |
|   int style,          // @parm Stile da applicare al font
 | |
|   int dim)            // @parm Dimensione del font
 | |
| {
 | |
|   CHECK(win != NULL_WIN, "Can't set the font in a NULL window");
 | |
| 
 | |
|   if ((family == NULL || *family == '\0') && 
 | |
|       (style == XVT_FS_NONE || style == XVT_FS_BOLD) &&
 | |
|       dim == 0)
 | |
|   {
 | |
|     xvt_dwin_set_font(win, xvt_default_font(style != XVT_FS_NONE));
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     XVT_FNTID font = xvt_dwin_get_font(TASK_WIN);                     
 | |
|     if (family && *family)    xvt_font_set_family(font, (char*)family);
 | |
|     if (dim != 0)             xvt_font_set_size(font, dim);
 | |
|     if (style != XVT_FS_NONE) xvt_font_set_style(font, style);
 | |
| 
 | |
|     if(!xvt_font_is_mapped(font))        
 | |
|       xvt_font_map(font, win);
 | |
|     
 | |
|     xvt_dwin_set_font(win, font);  
 | |
|     xvt_font_destroy(font);
 | |
|   }  
 | |
| }
 | |
| 
 | |
| void xvt_draw_rect(WINDOW win, const RCT& rect, COLOR lt, COLOR rb, short depth)
 | |
| {
 | |
|   RCT r = rect;
 | |
| 
 | |
|   CPEN pen;
 | |
|   pen.width = 1;
 | |
|   pen.pat = PAT_SOLID;
 | |
|   pen.style = P_SOLID;
 | |
|   pen.color = lt;
 | |
| 
 | |
|   for (short d = 0; d < depth;)
 | |
|   {
 | |
|     xvt_dwin_set_cpen(win, &pen);
 | |
| 
 | |
|     PNT p;      // Current vertex of the rectangle
 | |
| 
 | |
|     bool drawn = FALSE;
 | |
|     if (lt != MASK_BACK_COLOR)
 | |
|     {
 | |
|       p.h = r.left; p.v = r.bottom;
 | |
|       xvt_dwin_draw_set_pos(win, p);
 | |
| 
 | |
|       p.v = r.top;
 | |
|       xvt_dwin_draw_line(win, p);
 | |
|       p.h = r.right;
 | |
|       xvt_dwin_draw_line(win, p);
 | |
|       drawn = TRUE;
 | |
|     }
 | |
| 
 | |
|     if (rb != MASK_BACK_COLOR)
 | |
|     {
 | |
|       if (pen.color != rb)
 | |
|       {
 | |
|         pen.color = rb;
 | |
|         xvt_dwin_set_cpen(win, &pen);
 | |
|       }
 | |
|       if (!drawn)
 | |
|       {
 | |
|         p.h = r.right; p.v = r.top;
 | |
|         xvt_dwin_draw_set_pos(win, p);
 | |
|       }
 | |
|       p.v = r.bottom;
 | |
|       xvt_dwin_draw_line(win, p);
 | |
|       p.h = r.left;
 | |
|       xvt_dwin_draw_line(win, p);
 | |
|     }
 | |
| 
 | |
|     if (++d < depth)
 | |
|     {
 | |
|       r.left++; r.top++;
 | |
|       r.right--; r.bottom--;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di creare una finestra
 | |
| //
 | |
| // @rdesc Ritorna l'identificatore della finestra creata
 | |
| WINDOW xvt_create_window(
 | |
|   WIN_TYPE wt,           // @parm Tipo di finestra da creare
 | |
|   short x,               // @parm Coordinata x della finestra (espresso in caratteri)
 | |
|   short y,               // @parm Coordinata y della finestra (espresso in caratteri)
 | |
|   short dx,              // @parm Larghezza della finestra (espresso in caratteri)
 | |
|   short dy,              // @parm Altezza della finestra (espresso in caratteri)
 | |
|   const char* caption,   // @parm Titolo da assegnare alla finestra
 | |
|   int menu,              // @parm Menu della finestra (definito nelle risorse, 0=senza)
 | |
|   WINDOW parent,         // @parm Identificatore della finestra padre
 | |
|   long flags,            // @parm Attributi della finestra
 | |
|   EVENT_HANDLER eh,      // @parm Funzioni per la gestione degli eventi diretti alla finestra
 | |
|   long app_data)         // @parm Puntatore alla classe C++ che gestisce la finestra
 | |
| 
 | |
| {
 | |
|   RCT& rect = resize_rect(x, y, dx, dy, wt, parent);
 | |
| 
 | |
|   if (wt == WD_MODAL) wt = W_DOC;
 | |
|   WINDOW win = xvt_win_create(wt,
 | |
|                               &rect,
 | |
|                               (char*)caption,
 | |
|                               menu, parent,
 | |
|                               flags,
 | |
|                               EM_ALL, eh,
 | |
|                               app_data);
 | |
| 
 | |
|   CHECK(win, "Can't create a window: XVT error");
 | |
| 
 | |
| #if XVT_OS == XVT_OS_WIN
 | |
|   static bool to_set = TRUE;
 | |
|   HWND hwnd = (HWND)xvt_vobj_get_attr(win, ATTR_NATIVE_WINDOW);
 | |
|   if (to_set)
 | |
|   {
 | |
|     word style = GetClassWord(hwnd, GCW_STYLE);
 | |
|     style |= CS_BYTEALIGNCLIENT;
 | |
|     SetClassWord(hwnd, GCW_STYLE, style);
 | |
|     to_set = FALSE;
 | |
|   }
 | |
| #endif
 | |
| 
 | |
|   return win;
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di creare i controlli all'interno di una finestra
 | |
| //
 | |
| // @rdesc Ritorna la finestra del controllo
 | |
| WINDOW xvt_create_control(
 | |
|   WIN_TYPE wt,          // @parm Tipo di controllo da creare
 | |
|   short x,              // @parm Coordinata x del control
 | |
|   short y,              // @parm Coordinata y del control
 | |
|   short dx,             // @parm Larghezza della control
 | |
|   short dy,             // @parm Altezza della control
 | |
|   const char* caption,  // @parm Titolo da assegnare alla control
 | |
|   WINDOW parent,        // @parm Identificatore della finestra padre
 | |
|   long flags,           // @parm Attributi della finestra
 | |
|   long app_data,        // @parm Puntatore alla classe C++ che gestisce la finestra
 | |
|   int id)               // @parm Indentificatore del controlllo
 | |
| {
 | |
|   RCT r = resize_rect(x, y, dx, dy, wt, parent);
 | |
|   while (*caption == '@') caption += 2;
 | |
|   WINDOW win = xvt_ctl_create(wt, &r, (char*)caption, parent,
 | |
|                               flags, app_data, id);
 | |
|   if (win == NULL_WIN)
 | |
|     fatal_box("Can't create control %d: '%s'", id, caption);
 | |
| 
 | |
|   return win;
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Restituisce il titolo della finestra
 | |
| //
 | |
| // @rdesc Stringa contenente il titolo della finestra
 | |
| const char* xvt_get_title(
 | |
|   WINDOW win) // @parm Finestra della quale si vuole conoscere il titolo
 | |
| 
 | |
|   // @xref <f xvt_set_title>
 | |
| {
 | |
|   xvt_vobj_get_title(win, __tmp_string, 80);
 | |
|   return __tmp_string;
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di assegnare il titolo ad una finestra
 | |
| void xvt_set_title(
 | |
|   WINDOW win,      // @parm Finestra a cui assegnare il titolo
 | |
|   const char* cap) // @parm Titolo da assegnare
 | |
| 
 | |
|   // @xref <f xvt_get_title>
 | |
| {
 | |
|   xvt_vobj_set_title(win, (char*)cap);
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di abilitare il focus su un controllo
 | |
| void xvt_set_front_control(
 | |
|   WINDOW win)  // @parm Finestra nella quale abilitare il focus
 | |
| {
 | |
|   xvt_scr_set_focus_vobj(win);
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di togliere il focus da un controllo
 | |
| void xvt_kill_focus(
 | |
|   WINDOW win)  // @parm Finestra nella quale togliere il focus
 | |
| {
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di abilitare o disabilitare un controllo
 | |
| void xvt_enable_control(
 | |
|   WINDOW win, // @parm Finestra all'interno della quale abilitare il controllo
 | |
|   bool on)    // @parm Abilita (TRUE) o disabilita (FALSE) il controllo
 | |
| {
 | |
|   xvt_vobj_set_enabled(win, on);
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di gestire un check box all'interno di una finestra
 | |
| void xvt_check_box(
 | |
|   WINDOW win, // @parm Finestra all'interno della quale abilitare il check box
 | |
|   bool on)    // @parm Permette di inizializzare (TRUE) o scaricare (FALSE) i parametri
 | |
| {
 | |
|   xvt_ctl_set_checked(win, on);
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di controllare se un controllo e' stato selezionato
 | |
| //
 | |
| // @rdesc Ritorna i seguenti valori:
 | |
| //
 | |
| // @flag TRUE | Se il controllo e' stato selezionato
 | |
| // @flag FALSE | Se il controllo non e' stato selezionato
 | |
| bool xvt_get_checked_state(
 | |
|   WINDOW win) // @parm Finestra di cui si vuole conoscere lo stato
 | |
| {
 | |
|   return xvt_ctl_is_checked(win) ? TRUE : FALSE;
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di gestire un radio button all'interno di una finestra
 | |
| void xvt_check_radio_button(
 | |
|   WINDOW win,         // @parm Finestra all'interno della quale abilitare il radio button
 | |
|   const WINDOW* ctls, // @parm Array di stringhe contenenti le scelte del radiobutton
 | |
|   int count)          // @parm Numero di elementi del radiobutton
 | |
| {
 | |
|   xvt_ctl_check_radio_button(win, (WINDOW*)ctls, count);
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di controllare lo stato di un radiobutton
 | |
| //
 | |
| // @rdesc Ritorna il numero dell'elemento del radiobutton selezionato
 | |
| int xvt_get_checked_radio(
 | |
|   const WINDOW* ctls, // @parm Array di stringhe contenenti le scelte del radiobutton
 | |
|   int count)          // @parm Numero di elemnti del radiobutton
 | |
| 
 | |
| {
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di cambiare il colore di sfondo di un controllo
 | |
| void xvt_set_ctrl_back_color(
 | |
|   WINDOW win, // @parm Finestra di cui si vuole cambiare lo sfondo
 | |
|   COLOR col)  // @parm Colore dello sfondo
 | |
| {
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Gestione Status bar
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| HIDDEN WINDOW _statbar = NULL_WIN;
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di creare la barra di stato del programma
 | |
| //
 | |
| // @rdesc Ritorna l'identificatore della barra di stato creata
 | |
| WINDOW xvt_create_statbar()
 | |
| 
 | |
|   // @xref <f xvt_statbar_set> <f xvt_statbar_refresh>
 | |
| {
 | |
|   CHECK(_statbar == NULL_WIN, "Onli uan statbar, plis");
 | |
| 
 | |
| #if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32
 | |
|   const int prop_count = 4;
 | |
|   char* prop_list[prop_count+1] =
 | |
|   {
 | |
|     "Status bar",
 | |
|     "HEIGHT=24",
 | |
|     "TASK_WIN",
 | |
|     "FIELD_OFFSET=24",
 | |
|     NULL
 | |
|     };
 | |
| 
 | |
|   _statbar = statbar_create(0, 0, 600, 1024, 800, prop_count, prop_list,
 | |
|                             TASK_WIN, 0, 0, "");
 | |
|   CHECK(_statbar, "Can't create the status bar");
 | |
|   
 | |
|   statbar_set_fontid(_statbar, xvt_default_font());
 | |
| 
 | |
| #endif
 | |
| 
 | |
|   return _statbar;
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di settare una finestra con la barra di stato
 | |
| void xvt_statbar_set(
 | |
|   const char* text, // @parm Testo da inserire nella barra di stato
 | |
|   bool def)         // @parm (default FALSE)
 | |
| 
 | |
|   // @comm Nella barra di stato vi e' sempre presente la data del sistema
 | |
|   //
 | |
|   // @xref <f xvt_create_statbar> <f xvt_statbar_refresh>
 | |
| {                    
 | |
|   CHECK(_statbar, "NULL statbar");
 | |
| 
 | |
|   const TDate oggi(TODAY);
 | |
|   TString t(31);
 | |
|   t << text << '\t' << oggi.string() << " - " << main_app().title();
 | |
|   if (def)                                          
 | |
|     statbar_set_default_title(_statbar, (char*)(const char*)t);
 | |
|   statbar_set_title(_statbar, (char*)(const char*)t);
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di cambiare il titolo alla barra di stato presente
 | |
| void xvt_statbar_refresh()
 | |
| 
 | |
|   // @xref <f xvt_create_statbar> <f xvt_statbar_set>
 | |
| {
 | |
|   CHECK(_statbar, "NULL statbar");
 | |
|   statbar_set_title(_statbar, NULL);
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////                      
 | |
| // Test menu
 | |
| ///////////////////////////////////////////////////////////                      
 | |
| 
 | |
| HIDDEN bool test_menu_tag(MENU_ITEM* mi, MENU_TAG tag)
 | |
| {              
 | |
|   while (mi->tag)
 | |
|   {
 | |
|     if (mi->tag == tag) return TRUE;
 | |
|     if (mi->child != NULL) 
 | |
|     {
 | |
|       const bool ok = test_menu_tag(mi->child, tag);
 | |
|       if (ok) return TRUE;
 | |
|     }  
 | |
|     mi++;
 | |
|   }  
 | |
|   return FALSE;
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Controlla se e' esiste una voce del menu'
 | |
| //
 | |
| // @rdesc Ritorna i seguenti valori
 | |
| //
 | |
| // @flag TRUE | Se esiste la voce di menu'
 | |
| // @flag FALSE | Se non esiste la voce di menu'
 | |
| bool xvt_test_menu_tag(
 | |
|   MENU_TAG tag) // @parm Menu' nel quale cercare la voce
 | |
| 
 | |
| {                      
 | |
|   MENU_ITEM *mi = xvt_menu_get_tree(TASK_WIN);
 | |
|   const bool ok = test_menu_tag(mi, tag);
 | |
|   xvt_res_free_menu_tree(mi);
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di convertire in attributi grafici i codici caratteri usati
 | |
| //       dalle funzioni di stampa
 | |
| //
 | |
| // @rdesc Ritorna il codice del colore convertito in attributo grafico
 | |
| COLOR trans_color(
 | |
|   char c) // @parm Codice carattere da convertire
 | |
| {          
 | |
|   COLOR col;
 | |
|   switch (c) 
 | |
|   {
 | |
|   case 'b': 
 | |
|     col = COLOR_BLUE; break;
 | |
|   case 'c': 
 | |
|     col = COLOR_CYAN;      break;
 | |
|   case 'd': 
 | |
|     col = COLOR_DKGRAY;    break;
 | |
|   case 'g': 
 | |
|     col = COLOR_GREEN;     break;
 | |
|   case 'k': 
 | |
|     col = COLOR_GRAY;      break;
 | |
|   case 'l': 
 | |
|     col = COLOR_LTGRAY;    break;
 | |
|   case 'm': 
 | |
|     col = MASK_BACK_COLOR; break;
 | |
|   case 'n': 
 | |
|     col = COLOR_BLACK;     break;
 | |
|   case 'r':
 | |
|     col = COLOR_RED;       break;
 | |
|   case 'v': 
 | |
|     col = COLOR_MAGENTA;   break;
 | |
|   case 'w': 
 | |
|     col = COLOR_WHITE;     break;
 | |
|   case 'y': 
 | |
|     col = COLOR_YELLOW;    break;
 | |
|   default: 
 | |
|     CHECK(0,"trans_color: Undefined color"); break;
 | |
|   }
 | |
|   return col; 
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| // @func HIDDEN void | set_cursor | Cambia il cursore del mouse
 | |
| HIDDEN void set_cursor(
 | |
|      bool w) // @parm Indica il tipo di cursore da utilizzare:
 | |
|              //
 | |
|              // @flag TRUE | Cursore a clessidra per le wait
 | |
|              // @flag FALSE | Cursore a frecca normale
 | |
| { 
 | |
|   static int _count = 0; 
 | |
|   static WINDOW _win = NULL_WIN;
 | |
|   
 | |
|   if (w) 
 | |
|   {
 | |
|     if (_count == 0)
 | |
|     {
 | |
|       _win = cur_win();
 | |
|       if (_win == NULL_WIN)
 | |
|         _win = TASK_WIN;
 | |
|       xvt_win_set_cursor(_win, CURSOR_WAIT);
 | |
|     }  
 | |
|     _count++; 
 | |
|   }     
 | |
|   else 
 | |
|   {
 | |
|     _count--;
 | |
|     CHECK(_count >= 0, "end_wait without matching begin_wait");
 | |
|     if (_count == 0)
 | |
|     {   
 | |
|       WINDOW cur = cur_win();
 | |
|       if (cur == _win)
 | |
|         xvt_win_set_cursor(_win, CURSOR_ARROW);
 | |
|       else  
 | |
|         xvt_win_set_cursor(TASK_WIN, CURSOR_ARROW);
 | |
|     }  
 | |
|   }  
 | |
| }
 | |
| 
 | |
| void begin_wait()
 | |
| { set_cursor(TRUE); }
 | |
| 
 | |
| void end_wait()
 | |
| { set_cursor(FALSE); }
 | |
| 
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di converitire lo stile del pattern in attributi grafici da
 | |
| //       codici carattere.
 | |
| //
 | |
| // @rdesc Ritorna il pattern convertito
 | |
| PAT_STYLE trans_brush(
 | |
|   char p) // @parm Codice carattere da convertire
 | |
| {
 | |
|   switch (p)
 | |
|   {
 | |
|   case 'n' :  
 | |
|     return PAT_NONE;  
 | |
|   case 'h' :  
 | |
|     return PAT_HOLLOW;
 | |
|   case 's' :  
 | |
|     return PAT_SOLID;
 | |
|   case '-' :  
 | |
|     return PAT_HORZ;   
 | |
|   case '|' :  
 | |
|     return PAT_VERT;
 | |
|   case '/' :  
 | |
|     return PAT_FDIAG;  
 | |
|   case '\\': 
 | |
|     return PAT_BDIAG;
 | |
|   case 'X' :  
 | |
|     return PAT_DIAGCROSS;
 | |
|   case '+' :  
 | |
|     return PAT_CROSS;    
 | |
|     default  : 
 | |
|     CHECK(0,"trans_brush: Undefined pattern"); break;
 | |
|   }
 | |
|   return PAT_NONE; 
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Permette di convertire lo stile della penna da codice carattere
 | |
| //
 | |
| // @rdesc Ritorna lo stilo convertito
 | |
| PEN_STYLE trans_pen(
 | |
|   char p) // @parm Codice carattere da convertire
 | |
| {    
 | |
|   PEN_STYLE ps = P_SOLID;
 | |
|   switch (p)
 | |
|   {
 | |
|   case 'n' : 
 | |
|     ps = P_SOLID; break;
 | |
|   case '.' : 
 | |
|     ps = P_DOT; break;
 | |
|   case '-' : 
 | |
|     ps = P_DASH; break;
 | |
|   default: 
 | |
|     CHECK(0, "trans_pen: Undefined pattern"); break;
 | |
|   }
 | |
|   return ps;
 | |
| }                          
 | |
| 
 |