campo-sirio/include/xvtility.cpp
guy b7b5f606a8 applicat.* Aggiunta l'utilissima TSkeleton_app per creare semplici applicazioni
bafgn006.uml Migliorata maschera di gestione Golem
default.url  La voce 'Editor' del menu e' diventata 'Editors' per i Golem
golem.cpp    Migliorata maschera di gestione Golem
maskfld.*    Aggiunto il metodo TButton_field::set_icon
xvtility.cpp Corretta gestione del tasto F1


git-svn-id: svn://10.65.10.50/trunk@5354 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-10-13 14:04:22 +00:00

1193 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)
{
const KEY key = toupper(wparam)+K_CTRL;
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 & 0x8000) k += K_CTRL;
int ss = GetAsyncKeyState(VK_SHIFT); // Stato del tasto shift
if (ss & 0x8000) 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;
}