campo-sirio/include/xvtility.cpp
guy b108a12dba Corretti errori neele stampe w
git-svn-id: svn://10.65.10.50/trunk@64 c028cbd2-c16b-5b4b-a496-9718f37d4682
1994-08-26 13:07:24 +00:00

831 lines
18 KiB
C++
Executable File

#include <applicat.h>
#include <colors.h>
#include <urldefid.h>
#include <utility.h>
#if XVT_OS == XVT_OS_SCOUNIX
extern "C" {long nap(long period);}
#endif
// FATAL_HOOK che intercetta errori fatali XVT
// put breakpoint here
void fatal_hook()
{
#ifdef DBG
int dummy = 0;
dummy++;
#endif
}
#if XVTWS == WMWS
short CHARX = 8;
short CHARY = 8;
short COLX = 8;
short ROWY = 8;
COLOR MASK_BACK_COLOR = COLOR_WHITE;
COLOR NORMAL_COLOR = COLOR_BLACK;
COLOR NORMAL_BACK_COLOR = COLOR_WHITE;
COLOR DISABLED_COLOR = COLOR_GRAY;
COLOR DISABLED_BACK_COLOR = COLOR_WHITE;
COLOR FOCUS_COLOR = COLOR_BLACK;
COLOR FOCUS_BACK_COLOR = COLOR_WHITE;
#else
#include <windows.h>
HIDDEN COLORREF COLOR2RGB(COLOR c)
{
const byte red = byte((c >> 16) & 0xFF);
const byte gre = byte((c >> 8) & 0xFF);
const byte blu = byte(c & 0xFF);
return RGB(red, gre, blu);
}
HIDDEN COLOR RGB2COLOR(COLORREF c)
{
const byte red = byte(c & 0xFF);
const byte gre = byte((c >> 8) & 0xFF);
const byte blu = byte((c >> 16) & 0xFF);
return MAKE_COLOR(red, gre, blu);
}
extern "C" {
WINDOW xvtwi_hwnd_to_window(HWND);
#include <statbar.h>
}
#include <controls.h>
short COLX = 8;
short ROWY = GetSystemMetrics(SM_CYSCREEN) / 25;
short CHARX = 8;
short CHARY = 14;
HIDDEN LOGFONT NormalLogFont =
{
CHARY-3, CHARX,
0, 0,
300, FALSE, FALSE, FALSE,
OEM_CHARSET,
OUT_CHARACTER_PRECIS,
CLIP_DEFAULT_PRECIS,
PROOF_QUALITY,
VARIABLE_PITCH | FF_SWISS,
NULL
};
HIDDEN HFONT NormalFont = CreateFontIndirect(&NormalLogFont);
COLOR MASK_BACK_COLOR = MAKE_COLOR(0,128,128);
COLOR NORMAL_COLOR = COLOR_BLACK;
COLOR NORMAL_BACK_COLOR = COLOR_LTGRAY;
COLOR DISABLED_COLOR = COLOR_GRAY;
COLOR DISABLED_BACK_COLOR = MASK_BACK_COLOR;
HIDDEN COLORREF MaskColor = COLOR2RGB(MASK_BACK_COLOR);
HIDDEN HBRUSH MaskBrush = CreateSolidBrush(MaskColor);
HIDDEN COLORREF FocusForeColor = COLOR2RGB(COLOR_BLACK); // GetSysColor(COLOR_HIGHLIGHTTEXT);
HIDDEN COLORREF FocusBackColor = COLOR2RGB(COLOR_CYAN); // GetSysColor(COLOR_HIGHLIGHT);
HIDDEN HBRUSH FocusBrush = CreateSolidBrush(FocusBackColor);
COLOR FOCUS_COLOR = RGB2COLOR(FocusForeColor);
COLOR FOCUS_BACK_COLOR = RGB2COLOR(FocusBackColor);
HIDDEN COLORREF NormalForeColor = COLOR2RGB(NORMAL_COLOR);
HIDDEN COLORREF NormalBackColor = COLOR2RGB(NORMAL_BACK_COLOR);
HIDDEN HBRUSH NormalBrush = CreateSolidBrush(NormalBackColor);
HIDDEN BOOLEAN event_hook(HWND hwnd,
UINT msg,
UINT wparam,
ULONG lparam,
long* ret)
{
switch(msg)
{
case WM_CTLCOLOR:
{
const word type = HIWORD(lparam);
if (type == CTLCOLOR_LISTBOX || type == CTLCOLOR_EDIT ||
type == CTLCOLOR_MSGBOX)
{
HWND hwnd = LOWORD(lparam);
HDC hdc = wparam;
if (!IsWindowEnabled(hwnd)) // Campo disabilitato
{
if (type != CTLCOLOR_MSGBOX)
{
SetTextColor(hdc, NormalForeColor);
SetBkColor(hdc, MaskColor);
}
*ret = MaskBrush;
return TRUE;
}
bool focus = GetFocus() == hwnd;
if (type != CTLCOLOR_MSGBOX)
{
SetTextColor(hdc, focus ? FocusForeColor : NormalForeColor);
SetBkColor(hdc, focus ? FocusBackColor : NormalBackColor);
}
*ret = focus ? FocusBrush : NormalBrush;
return TRUE;
}
}
break;
case WM_COMMAND:
{
const word notify = HIWORD(lparam);
if (notify == EN_KILLFOCUS || notify == EN_SETFOCUS)
{
HWND hwnd = LOWORD(lparam); // Ridisegna BENE il campo
InvalidateRect(hwnd, NULL, TRUE);
}
}
break;
case WM_KEYDOWN:
if (wparam == VK_PRIOR || wparam == VK_NEXT ||
wparam == VK_UP || wparam == VK_DOWN )
{
char name[16];
GetClassName(hwnd, name, 5);
if (stricmp(name, "Edit") == 0)
{
KEY key;
switch(wparam)
{
case VK_PRIOR:
wparam = K_PREV; break;
case VK_NEXT:
key = K_NEXT; break;
case VK_UP:
key = K_UP; break;
case VK_DOWN:
key = K_DOWN; break;
default:
key = 0; break;
}
if (key > 0)
{
WINDOW w = cur_win();
if (w != NULL_WIN)
dispatch_e_char(w, key);
}
}
}
break;
case WM_MENUCHAR:
{
WINDOW w = cur_win();
if (w != NULL_WIN)
{
const KEY key = toupper(wparam)+K_CTRL;
dispatch_e_char(w, key);
}
}
break;
default:
break;
}
return FALSE;
}
#endif
RCT& resize_rect(short x, short y, short dx, short dy, WIN_TYPE wt, WINDOW parent)
{
static RCT r;
if (parent != TASK_WIN)
{
if (get_window_type(parent) == W_PLAIN) // Mask with Toolbar
{
if (y >= 0) y++;
if (x >= 0 && wt != WO_TE)
{
const int width = (int)get_value(NULL_WIN, ATTR_SCREEN_WIDTH);
if (width > 640) x += (width-640) / (2*COLX);
}
}
wt = WC_EDIT;
}
#if XVT_OS == XVT_OS_WIN
switch (wt)
{
case WC_EDIT :
r.left = (x+1)*COLX;
r.top = y*ROWY;
r.right = dx*CHARX;
r.bottom = CHARY+3;
if (dy > 1)
r.bottom += ROWY*(dy-1);
break;
case W_DOC:
r.left = x * COLX;
r.top = y * ROWY;
r.right = dx * CHARX;
r.bottom = dy * CHARY;
break;
default:
r.left = x * COLX;
r.top = y * ROWY;
r.right = (dx+2)*COLX;
r.bottom = dy*ROWY-1;
break;
}
#else
r.left = x * CHARX;
r.top = y * CHARY;
r.right = dx * CHARX;
r.bottom = dy * CHARY;
#endif
if (x < 0 || y < 0 || dx <= 0 || dy <= 0)
{
RCT pc;
if (parent == NULL_WIN) parent = TASK_WIN;
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*COLX;
}
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*COLX;
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;
}
void beep()
{ xvt_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)
{
_w[_end] = w;
_e[_end] = e;
_end = (++_end) % MAX;
CHECKD(_end != _begin, "Too many events queued: max. ", MAX);
}
void TEvent_manager::pop()
{
if (_begin != _end)
{
const int i = _begin;
_begin = (++_begin) % MAX; // Other events may occur!
dispatch_event(_w[i], &_e[i]);
}
}
void do_events()
{
process_events();
EM.pop();
#if XVT_OS == XVT_OS_SCOUNIX
nap(20);
#endif
}
KEY e_char_to_key(const EVENT* ep)
{
CHECK(ep->type == E_CHAR, "Can't convert to key a Non-E_CHAR event");
KEY key = ep->v.chr.ch;
if (key < K_INS || key > K_HELP)
{
if (ep->v.chr.shift && !isprint(key)) key += K_SHIFT;
if (key >= ' ' && ep->v.chr.control) key += K_CTRL;
}
return key;
}
void dispatch_e_char(WINDOW win, KEY key)
{
EVENT e;
e.type = E_CHAR;
if (key > 10000) { e.v.chr.control = TRUE; key -= K_CTRL; }
else e.v.chr.control = FALSE;
if (key > 1000) { e.v.chr.shift = TRUE; key -= K_SHIFT; }
else e.v.chr.shift = FALSE;
e.v.chr.ch = short(key);
// dispatch_event(win, &e);
EM.push(win, e);
}
void dispatch_e_scroll(WINDOW win, KEY key)
{
EVENT 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);
}
void customize_controls(bool on)
{
#if XVTWS == WMWS
if (on)
{
// set_value(NULL_WIN,ATTR_CH_SHADOW,XVT_CH_SHADOW_WINDOW|XVT_CH_SHADOW_DIALOG);
set_value(NULL_WIN, ATTR_CH_TOGGLE_COMBO, (long)K_F9);
}
#endif
#if XVT_OS == XVT_OS_WIN
if (on)
{
const long style = WSF_ICONIZABLE | WSF_SIZE | WSF_CLOSE | WSF_MAXIMIZED;
set_value(NULL_WIN,ATTR_WIN_PM_TWIN_STARTUP_STYLE, style);
set_value(NULL_WIN,ATTR_WIN_PM_DRAWABLE_TWIN, TRUE);
set_value(NULL_WIN,ATTR_EVENT_HOOK, (long)event_hook);
}
else
{
DeleteObject(NormalFont);
DeleteObject(MaskBrush);
DeleteObject(NormalBrush);
DeleteObject(FocusBrush);
free_controls_bmp();
}
#endif
if (on) set_value(NULL_WIN,ATTR_FATAL_ERR_HANDLER, (long)fatal_hook);
}
void xvt_set_font(WINDOW win, int family, int style, int dim)
{
CHECK(win > 0, "Can't set the font in a NULL window");
#if XVT_OS == XVT_OS_WIN
if (dim < 1)
{
NormalLogFont.lfHeight = (style & FS_BOLD) ? CHARY-1 : CHARY-3;
NormalLogFont.lfWidth = (style & FS_BOLD) ? CHARX-1 : CHARX;
NormalLogFont.lfWeight = (style & FS_BOLD) ? 600 : 300;
NormalLogFont.lfItalic = (style & FS_ITALIC) ? TRUE : FALSE;
set_value(NULL_WIN, ATTR_WIN_PM_LOGFONT, long(&NormalLogFont));
set_value(NULL_WIN, ATTR_WIN_PM_USERFONT, TRUE);
win_set_font(win, NULL, FALSE);
set_value(NULL_WIN, ATTR_WIN_PM_USERFONT, FALSE);
return;
}
#endif
FONT font;
select_font(family, style, dim < 1 ? CHARY : dim, &font);
win_set_font(win, &font, FALSE);
}
WINDOW xvt_create_window(WIN_TYPE wt,
short x, short y, short dx, short dy,
const char* caption, WINDOW parent,
long flags, EVENT_HANDLER eh, long app_data
)
{
RCT& rect = resize_rect(x, y, dx, dy, wt, parent);
if (wt == WD_MODAL) wt = W_DOC;
WINDOW win = create_window(wt,
&rect,
(char*)caption,
0, parent,
flags,
EM_ALL, eh,
app_data);
CHECKD(win, "Can't create a window: XVT error ", get_xvterrno());
#if XVT_OS == XVT_OS_WIN
static bool set = TRUE;
if (set)
{
HWND hwnd = (HWND)get_value(win, ATTR_NATIVE_WINDOW);
word style = GetClassWord(hwnd, GCW_STYLE);
style |= CS_BYTEALIGNCLIENT | CS_SAVEBITS;
SetClassWord(hwnd, GCW_STYLE, style);
set = FALSE;
}
#endif
return win;
}
WINDOW xvt_create_control(WIN_TYPE wt,
short x, short y, short dx, short dy,
const char* caption,
WINDOW parent,
long flags,
long app_data,
int id)
{
RCT r = resize_rect(x, y, dx, dy, wt, parent);
WINDOW win = NULL_WIN;
#if XVT_OS == XVT_OS_WIN
if (wt == WC_CHECKBOX)
win = xvt_create_checkbox(r.left, r.top, r.right, r.bottom,
caption, parent, flags, app_data, id);
if (wt == WC_RADIOBUTTON)
win = xvt_create_radiobutton(r.left, r.top, r.right, r.bottom,
caption, parent, flags, app_data, id);
if (wt == WC_PUSHBUTTON)
win = xvt_create_pushbutton(r.left, r.top, r.right, r.bottom,
caption, parent, flags, app_data, id);
if (wt == WC_GROUPBOX)
{
win = xvt_create_groupbox(r.left, r.top, r.right, r.bottom,
caption, parent, flags, app_data, id);
}
if (wt == WC_TEXT)
{
win = xvt_create_text(r.left, r.top, r.right, r.bottom,
caption, parent, flags, app_data, id);
}
#endif
if (win == NULL_WIN)
{
if (wt == WC_PUSHBUTTON)
{
if (dy == 2) r.bottom -= ROWY;
if (id == DLG_F9)
{ wt = WC_TEXT; r.right = r.left+CHARX; caption = "*"; }
else if (*caption == '#') caption = "";
}
while (*caption == '@') caption += 2;
win = create_control(wt, &r, (char*)caption, parent,
flags, app_data, id);
}
#ifdef DBG
if (win == NULL_WIN)
fatal_box("Can't create control %d: XVT error %d", id, get_xvterrno());
#endif
#if XVT_OS == XVT_OS_WIN
if (wt == WC_EDIT || wt == WC_LISTBUTTON)
{
HWND hwnd = (HWND)get_value(win, ATTR_NATIVE_WINDOW);
SendMessage(hwnd, WM_SETFONT, NormalFont, TRUE);
}
#endif
return win;
}
const char* xvt_get_title(WINDOW win)
{
#if XVTWS == WINWS
TControl* c = TControl::WINDOW2TControl(win);
return c->caption();
#else
static char title[81];
get_title(win, title, 80);
return title;
#endif
}
void xvt_set_front_control(WINDOW win)
{
#if XVTWS == WINWS
TControl* c = TControl::WINDOW2TControl(win);
c->focus(TRUE);
#endif
set_front_window(win);
}
void xvt_enable_control(WINDOW win, bool on)
{
#if XVTWS == WINWS
TControl* c = TControl::WINDOW2TControl(win);
c->enable(on);
#else
enable_window(win, on);
#endif
}
void xvt_check_box(WINDOW win, bool on)
{
#if XVTWS == WMWS
win_check_box(win, on);
#else
TControl* c = (TControl*)TControl::WINDOW2TControl(win);
c->check(on);
#endif
}
bool xvt_get_checked_state(WINDOW win)
{
#if XVTWS == WMWS
return get_checked_state(win);
#else
TControl* c = TControl::WINDOW2TControl(win);
return c->checked();
#endif
}
void xvt_check_radio_button(WINDOW win, const WINDOW* ctls, int count)
{
#if XVTWS == WMWS
win_check_radio_button(win, (WINDOW*)ctls, count);
#else
for (int i = 0; i < count; i++)
xvt_check_box(ctls[i], ctls[i] == win);
#endif
}
int xvt_get_checked_radio(const WINDOW* ctls, int count)
{
for (int i = 0; i < count; i++)
if (xvt_get_checked_state(ctls[i])) return i;
#ifdef DBG
error_box("Accendi la tua radio per favore!");
#endif
return 0;
}
///////////////////////////////////////////////////////////
// Gestione Status bar
///////////////////////////////////////////////////////////
HIDDEN WINDOW statbar = NULL_WIN;
HIDDEN TString80 stattext;
WINDOW xvt_create_statbar()
{
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] =
{
"",
"HEIGHT=23",
"TASK_WIN=TRUE",
"FIELD_OFFSET=24",
NULL
};
statbar = statbar_create(-1, 0, 0, 1, 1, prop_count, prop_list,
TASK_WIN, 0, 0, NULL);
xvt_set_font(statbar, FF_FIXED, 0);
DRAW_CTOOLS ct;
win_get_draw_ctools(statbar, &ct);
#ifndef XVT_R3_API
statbar_set_font(statbar, &ct.font);
#endif
#endif
return statbar;
}
void xvt_statbar_set(const char* text)
{
#if XVT_OS == XVT_OS_WIN
if (text != NULL)
{
stattext.strncpy(text, 56);
const TDate oggi(TODAY);
stattext << '\t' << oggi.string() << " - " << MainApp()->title();
}
statbar_set_title(statbar, (char*)(const char*)stattext);
#endif
}
void xvt_statbar_refresh()
{
#if XVT_OS == XVT_OS_WIN
statbar_set_title(statbar, (char*)(const char*)stattext);
#endif
}
///////////////////////////////////////////////////////////
// Test menu
///////////////////////////////////////////////////////////
HIDDEN bool test_menu_tag(MENU_ITEM* mi, MENU_TAG tag)
{
CHECK(mi, "Can't test NULL MENU_ITEM");
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;
}
bool xvt_test_menu_tag(MENU_TAG tag)
{
MENU_ITEM *mi = win_menu_fetch(TASK_WIN);
const bool ok = test_menu_tag(mi, tag);
menu_free(mi);
return ok;
}
// translation of graphics attributes from codes chars
// used by print functions
COLOR trans_color(char c)
{
switch (c)
{
case 'n': return COLOR_BLACK; break;
case 'r': return COLOR_RED; break;
case 'g': return COLOR_GREEN; break;
case 'b': return COLOR_BLUE; break;
case 'c': return COLOR_CYAN; break;
case 'y': return COLOR_YELLOW; break;
case 'v': return COLOR_MAGENTA; break;
case 'w': return COLOR_WHITE; break;
case 'm': return MASK_BACK_COLOR; break;
case 'd': return COLOR_DKGRAY; break;
case 'l': return COLOR_LTGRAY; break;
case 'k': return COLOR_GRAY; break;
default: CHECK(0,"trans_color: Undefined color"); break;
}
return -1;
}
PAT_STYLE trans_brush(char p)
{
switch (p)
{
case 'n' : return PAT_NONE; break;
case 'h' : return PAT_HOLLOW; break;
case 's' : return PAT_SOLID; break;
case '-' : return PAT_HORZ; break;
case '|' : return PAT_VERT; break;
case '/' : return PAT_FDIAG; break;
case '\\': return PAT_BDIAG; break;
case 'X' : return PAT_DIAGCROSS; break;
case '+' : return PAT_CROSS; break;
default : CHECK(0,"trans_brush: Undefined pattern"); break;
}
return PAT_NONE;
}
PEN_STYLE trans_pen(char p)
{
switch (p)
{
case 'n' : return P_SOLID; break;
case '.' : return P_DOT; break;
case '-' : return P_DASH; break;
default: CHECK(0,"trans_pen: Undefined pattern"); break;
}
return P_SOLID;
}