campo-sirio/include/xvtility.cpp
guy 4759abb8f4 applicat.cpp Aggiunto metodo pre_create per inizializzazioni di basso livello
golem.cpp     Migliorata gestione degli hook agli handler di finestra
msksheet.cpp  Eliminati molti sfarfallamenti duante cambio focus
relapp.cpp    Corretta gestione messaggio ED
sheet.cpp     Corretto posizionamento iniziale su righe disabilitate
xvtility.cpp  Migliorata gestione dell'event hook.


git-svn-id: svn://10.65.10.50/trunk@3328 c028cbd2-c16b-5b4b-a496-9718f37d4682
1996-08-05 09:43:06 +00:00

1139 lines
28 KiB
C++
Executable File

#include <applicat.h>
#include <colors.h>
#include <config.h>
#include <date.h>
#include <urldefid.h>
#include <utility.h>
#include <mask.h>
#if XVT_OS == XVT_OS_WIN
#include <windows.h>
#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
int MungeModuleHeader( HINSTANCE hInstance, BOOL fMunge );
#endif
#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
#define STRICT
#include <windows.h>
#include <ctl3d.h>
extern "C" {
WINDOW xvtwi_hwnd_to_window(HWND);
#include <statbar.h>
}
#include <controls.h>
short CHARX = 8;
short ROWY = GetSystemMetrics(SM_CYSCREEN) / 25;
short CHARY = 14;
short BASEY = 12;
const word WM_WAKEUP = RegisterWindowMessage("WAKEUP");
// 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];
HIDDEN HINSTANCE HInstance;
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 __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;
}
static BOOLEAN event_hook(HWND hwnd,
UINT msg,
UINT wparam,
ULONG lparam,
long* ret)
{
switch(msg)
{
case WM_SYSCOLORCHANGE:
Ctl3dColorChange();
break;
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
}
#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;
}
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);
}
// @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
long old_hook = xvt_vobj_get_attr(NULL_WIN,ATTR_EVENT_HOOK);
if (old_hook == 0)
xvt_vobj_set_attr(NULL_WIN,ATTR_EVENT_HOOK, (long)event_hook);
xvt_vobj_set_attr(NULL_WIN,ATTR_ERRMSG_HANDLER, (long)error_hook);
HInstance = (HINSTANCE)xvt_vobj_get_attr(NULL_WIN, ATTR_WIN_INSTANCE);
Ctl3dRegister(HInstance);
Ctl3dAutoSubclass(HInstance);
#endif
customize_colors();
init_controls();
}
else
{
#if XVT_OS == XVT_OS_WIN
// HINSTANCE _hInstance = (HINSTANCE)xvt_vobj_get_attr(NULL_WIN, ATTR_WIN_INSTANCE);
Ctl3dUnregister(HInstance);
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 stabar, plis");
#if XVT_OS == XVT_OS_WIN
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>
{
#if XVT_OS == XVT_OS_WIN
const TDate oggi(TODAY);
TString256 t(text);
t << '\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);
#endif
}
// @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>
{
#if XVT_OS == XVT_OS_WIN
statbar_set_title(_statbar, NULL);
#endif
}
///////////////////////////////////////////////////////////
// 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;
if (w)
{
if (_count == 0)
xvt_win_set_cursor(TASK_WIN, CURSOR_WAIT);
_count++;
}
else
{
_count--;
CHECK(_count >= 0, "end_wait without matching begin_wait");
if (_count == 0)
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;
}