extern "C" { #include #include #include } #if XVT_OS != XVT_OS_WIN #error "This file should be compiled for Windows only" #endif #include #include #include #include #include #include /////////////////////////////////////////////////////////// // TPicture_array /////////////////////////////////////////////////////////// class TPicture_array { enum { MAXPIC = 128 }; PICTURE _picture[MAXPIC]; public: PICTURE getbmp(short id, bool convert = FALSE); PICTURE operator[](short id) { return _picture[id-BMP_OK]; } void reset(); TPicture_array(); ~TPicture_array() { reset(); } }; HIDDEN byte COLOR2PIC(COLOR c) { static unsigned long color[16][2] = { 0x000000, 0x00, // BLACK 0x0000FF, 0x04, // BLUE 0x000080, 0x0C, // LTBLUE 0x008000, 0x02, // DKGREEN 0x008080, 0x06, // DKCYAN 0x00FF00, 0xFA, // GREEN 0x00FFFF, 0xFE, // CYAN 0x800000, 0x01, // DKRED 0x800080, 0xFD, // DKMAGENTA 0x808000, 0x03, // DKYELLOW 0x808080, 0xF8, // GRAY 0xC0C0C0, 0x07, // LTGRAY 0xFF0000, 0xF9, // RED 0xFF00FF, 0x05, // MAGENTA 0xFFFF00, 0xFB, // YELLOW 0xFFFFFF, 0xFF, // WHITE }; int idx, f = 0, l = 15; c &= 0x00FFFFFF; while (TRUE) { idx = (f+l)>>1; if (c == color[idx][0]) break; if (c > color[idx][0]) f = idx+1; else l = idx-1; if (f > l) { break; } } const byte b = (byte)color[idx][1]; return b; } PICTURE xvt_picture_load(short id, bool convert) { static bool _can_convert = 2; if (_can_convert == 2) { HWND hwnd = (HWND)get_value(TASK_WIN, ATTR_NATIVE_WINDOW); HDC hdc = GetDC(hwnd); const int bits = GetDeviceCaps(hdc, BITSPIXEL); _can_convert = bits == 8; ReleaseDC(hwnd, hdc); } PICTURE cpb = cpb_picture_load(id); CHECKD(cpb, "Can't load picture ", id); if (convert && _can_convert && MASK_BACK_COLOR != COLOR_DKCYAN) { long size; char huge * buf = picture_lock(cpb, &size); if (buf != NULL) { RCT r; cpb_get_picture_size(cpb, &r); const byte newba = COLOR2PIC(MASK_BACK_COLOR); const byte newlt = COLOR2PIC(MASK_LIGHT_COLOR); const byte newdk = COLOR2PIC(MASK_DARK_COLOR); const long first = 14; const long last = first + (long)r.right*r.bottom; for (long i = first; i < last; i++) switch((byte)buf[i]) { case 0x06: buf[i] = newba; break; case 0xF8: buf[i] = newdk; break; case 0xFE: buf[i] = newlt; break; default: break; } const PICTURE old = cpb; cpb = picture_make(buf, size, &r); picture_unlock(old); picture_free(old); } } return cpb; } PICTURE TPicture_array::getbmp(short id, bool convert) { const int i = id-BMP_OK; CHECKD(i >= 0 && i < MAXPIC, "Control ID out of range", id); if (_picture[i] != NULL) { if (i < 100) return _picture[i]; picture_free(_picture[i]); } _picture[i] = xvt_picture_load(id, convert); if (_picture[i] == NULL) error_box("Can't load picture %d", id); return _picture[i]; } TPicture_array::TPicture_array() { memset(_picture, 0, sizeof(_picture)); } void TPicture_array::reset() { for (int i = 0; i < MAXPIC; i++) if (_picture[i] != NULL) { picture_free(_picture[i]); _picture[i] = NULL; } } /////////////////////////////////////////////////////////// // Static data and functions /////////////////////////////////////////////////////////// HIDDEN TControl* creating = NULL; HIDDEN long ctl_flags; HIDDEN WINDOW _hdc; HIDDEN RCT _client; HIDDEN TPicture_array cpb; HIDDEN void get_geometry(WINDOW win) { get_client_rect(win, &_client); _client.right--; _client.bottom--; _hdc = win; } HIDDEN void set_creation_args(WIN_CREATION_ARGS *a) { long& flags = a->win_flags; if (ctl_flags & CTL_FLAG_DISABLED) flags |= WSF_DISABLED; if (ctl_flags & CTL_FLAG_INVISIBLE) flags |= WSF_INVISIBLE; switch(creating->id()) { case -2: flags |= WSF_DISABLED; break; default:break; } } 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;) { win_set_cpen(win, &pen); PNT p; // Current vertex of the rectangle bool drawed = FALSE; if (lt != COLOR_LTGRAY) { p.h = r.left; p.v = r.bottom; win_move_to(win, p); p.v = r.top; win_draw_line(win, p); p.h = r.right; win_draw_line(win, p); drawed = TRUE; } if (rb != COLOR_LTGRAY) { if (pen.color != rb) { pen.color = rb; win_set_cpen(win, &pen); } if (!drawed) { p.h = r.right; p.v = r.top; win_move_to(win, p); } p.v = r.bottom; win_draw_line(win, p); p.h = r.left; win_draw_line(win, p); } if (++d < depth) { r.left++; r.top++; r.right--; r.bottom--; } } } void TControl::create( short left, short top, short right, short bottom, const char* title, WINDOW parent, long flags, long app_data, short id) { bool bold = *title == '@'; if (bold) title += 2; const int prop_count = 1; const char* prop_list[prop_count+1] = { title, NULL }; _id = id; _caption = title; _caption.strip("~"); _disabled = (flags & CTL_FLAG_DISABLED) != 0; _checked = (flags & CTL_FLAG_CHECKED) != 0; _multiple = (flags & CTL_FLAG_MULTIPLE) != 0; _focused = FALSE; creating = this; ctl_flags = flags; _win = xvtcm_create(id, left, top, right, bottom, prop_count, (char**)prop_list, parent, 0, 0, NULL, handler, set_creation_args); CHECKD(_win, "Can't create control ", id); creating = NULL; set_app_data(_win, app_data); xvt_set_font(_win, FF_FIXED, bold ? FS_BOLD : 0); } // Virtual destructor needed to make derived descrutors live! TControl::~TControl() {} long TControl::handler(WINDOW win, EVENT* ep) { static bool tracking = FALSE; static bool pressed = FALSE; if (ep->type == E_CREATE) xvtcm_eh_start(win, ep); TControl** model = (TControl**)xvtcm_get_model(win, sizeof(TControl*)); CHECK(model, "Can't get the model"); TControl*& cc = *model; if (ep->type == E_CREATE) { CHECK(creating, "Can't create a NULL control"); cc = creating; } CHECK(cc, "Can't handle a NULL control"); if (creating == NULL) switch(ep->type) { case E_FOCUS: cc->focus((bool)ep->v.active); case E_UPDATE: cc->update(); break; case E_MOUSE_DOWN: trap_mouse(win); tracking = pressed = TRUE; cc->mouse_down(ep->v.mouse.where); break; case E_CHAR: { const KEY key = e_char_to_key(ep); switch(key) { case K_SPACE: cc->mouse_up(); break; default: dispatch_e_char(get_parent(win), key); break; } } break; case E_MOUSE_MOVE: if (tracking) { RCT r; get_client_rect(win, &r); if (pt_in_rect(&r, ep->v.mouse.where)) { if (!pressed) { cc->mouse_down(ep->v.mouse.where); pressed = TRUE; } } else { if (pressed) { cc->update(); pressed = FALSE; } } } break; case E_MOUSE_UP: if (tracking) { release_mouse(); tracking = FALSE; if (pressed) { cc->mouse_up(); pressed = FALSE; } } break; case E_DESTROY: delete *model; *model = NULL; xvtcm_eh_end(win, ep); break; default: break; } return 0L; } void TControl::enable(bool on) { if (on == disabled()) { _disabled = !on; update(); enable_window(win(), on); } } void TControl::check(bool on) { _checked = on; } void TControl::update() const { if (_win != _hdc) get_geometry(_win); clear_window(_hdc, MASK_BACK_COLOR); win_set_fore_color(_hdc, disabled() ? DISABLED_COLOR : NORMAL_COLOR); } void TControl::set_caption(const char* t) { _caption = t; update(); } /////////////////////////////////////////////////////////// // TText /////////////////////////////////////////////////////////// class TText : public TControl { protected: virtual WIN_TYPE type() const { return WC_TEXT; } virtual void update() const; public: TText(short left, short top, short right, short bottom, const char* caption, WINDOW parent, long flags, long app_data, short id); }; TText::TText(short left, short top, short right, short bottom, const char* caption, WINDOW parent, long flags, long app_data, short id) { create(left, top+1, right, bottom-1, caption, parent, flags, app_data, id); } void TText::update() const { TControl::update(); win_set_fore_color(_hdc, NORMAL_COLOR); win_draw_text(_hdc, _client.left, _client.top+BASEY, (char*)caption(), -1); } /////////////////////////////////////////////////////////// // TGroup /////////////////////////////////////////////////////////// class TGroup : public TText { protected: virtual WIN_TYPE type() const { return WC_GROUPBOX; } virtual void update() const; void draw_round_rect(const RCT& r, COLOR c) const; public: TGroup(short left, short top, short right, short bottom, const char* caption, WINDOW parent, long flags, long app_data, short id); }; TGroup::TGroup(short left, short top, short right, short bottom, const char* caption, WINDOW parent, long flags, long app_data, short id) : TText(left, top, right, bottom, caption, parent, flags | CTL_FLAG_DISABLED, app_data, (id < 0) ? -2 : id) {} void TGroup::draw_round_rect(const RCT& r, COLOR c) const { CPEN pen; pen.width = 2; pen.pat = PAT_SOLID; pen.style = P_SOLID; pen.color = c; win_set_cpen(_hdc, &pen); CBRUSH brush = { PAT_HOLLOW, MASK_BACK_COLOR }; win_set_cbrush(_hdc, &brush); win_draw_roundrect(_hdc, (RCT*)&r, ROWY, ROWY); } void TGroup::update() const { TText::update(); RCT r = _client; r.top += CHARY; r.right-=4; r.bottom-=ROWY/2; if (multiple()) { r.left++; r.top++; r.right--; r.bottom--; draw_round_rect(r, MASK_LIGHT_COLOR); } else { xvt_draw_rect(_hdc, r, MASK_DARK_COLOR, MASK_LIGHT_COLOR); } } /////////////////////////////////////////////////////////// // Button /////////////////////////////////////////////////////////// class TButton : public TControl { protected: enum { DEPTH = 2 }; virtual WIN_TYPE type() const { return WC_PUSHBUTTON; } virtual void update() const; virtual void mouse_down(PNT where); virtual void mouse_up(); virtual void check(bool on); virtual void draw_pressed(bool pressed) const; public: TButton(short left, short top, short right, short bottom, const char* caption,WINDOW parent, long flags, long app_data, short id); }; TButton::TButton(short left, short top, short right, short bottom, const char* caption, WINDOW parent, long flags, long app_data, short id) { create(left, top, right, bottom, caption, parent, flags, app_data, id); } void TButton::draw_pressed(bool pressed) const { get_geometry(win()); clear_window(_hdc, COLOR_LTGRAY); RCT r = _client; xvt_draw_rect(_hdc, r, COLOR_BLACK, COLOR_BLACK); COLOR lt = pressed ? COLOR_GRAY : COLOR_WHITE; COLOR rb = pressed ? COLOR_LTGRAY : COLOR_GRAY; for (int i = DEPTH; i--;) { r.left++; r.top++; r.right--; r.bottom--; xvt_draw_rect(_hdc, r, lt, rb); if (i == 1) lt = COLOR_LTGRAY; } } void TButton::update() const { TControl::update(); draw_pressed(checked()); } void TButton::mouse_down(PNT) { draw_pressed(!checked()); } void TButton::mouse_up() { draw_pressed(checked()); EVENT e; // Notification message e.type = E_CONTROL; e.v.ctl.id = id(); e.v.ctl.ci.type = type(); e.v.ctl.ci.win = win(); dispatch_event(get_parent(win()), &e); } void TButton::check(bool on) { TControl::check(on); draw_pressed(on); } /////////////////////////////////////////////////////////// // TPush button /////////////////////////////////////////////////////////// class TPush_button : public TButton { PICTURE _picup, _picdn; byte _dx, _dy; int _accel; protected: void draw_pressed(bool pressed) const; void update() const; public: TPush_button(short left, short top, short right, short bottom, const char* caption, WINDOW parent, long flags, long app_data, short id); virtual ~TPush_button(); }; TPush_button::TPush_button(short left, short top, short right, short bottom, const char* capt, WINDOW parent, long flags, long app_data, short id) : TButton(left-(id == DLG_F9), top, right, bottom, capt, parent, flags, app_data, id), _picup(0L), _picdn(0L) { switch(id) { case DLG_OK: if (strcmp("Conferma", caption()) == 0) capt = format("#%d", BMP_OK); break; case DLG_CANCEL: if (strcmp("Annulla", caption()) == 0) capt = format("#%d", BMP_CANCEL); break; case DLG_QUIT: capt = format("#%d#%d", BMP_QUIT, BMP_QUITDN); break; case DLG_SELECT: capt = format("#%d", BMP_SELECT); break; case DLG_DELREC: capt = format("#%d#%d", BMP_DELREC, BMP_DELRECDN); break; case DLG_NEWREC: if (strcmp("Nuovo", caption()) == 0) // Puo' essere Gestione capt = format("#%d#%d", BMP_NEWREC, BMP_NEWRECDN); break; case DLG_STOPREC: capt = format("#%d", BMP_STOPREC); break; /* case DLG_FIRSTREC: capt = format("#%d", BMP_FIRSTREC); break; case DLG_PREVREC: capt = format("#%d", BMP_PREVREC); break; case DLG_NEXTREC: capt = format("#%d", BMP_NEXTREC); break; case DLG_LASTREC: capt = format("#%d", BMP_LASTREC); break; */ case DLG_SAVEREC: capt = format("#%d#%d", BMP_SAVEREC, BMP_SAVERECDN); break; case DLG_FINDREC: capt = format("#%d", BMP_FINDREC); break; case DLG_F9: capt = format("#%d", BMP_SEARCH); break; case DLG_LINK: capt = format("#%d", BMP_LINK); break; case DLG_EDIT: capt = format("#%d", BMP_EDIT); break; case DLG_PRINT: capt = format("#%d", BMP_PRINT); break; case DLG_SETPRINT: capt = format("#%d", BMP_SETPRINT); break; case DLG_RECALC: capt = format("#%d", BMP_RECALC); break; default: break; } const int height = bottom-top; const int width = right-left; const char* diesis = strchr(capt, '#'); if (diesis != NULL) { int pid = atoi(++diesis); _picup = cpb.getbmp(pid); diesis = strchr(diesis, '#'); if (diesis != NULL) { pid = atoi(++diesis); _picdn = cpb.getbmp(pid); } RCT r; cpb_get_picture_size(_picup, &r); _dx = byte((width-r.right+1) >> 1); _dy = byte((height-r.bottom) >> 1); _accel = -1; } else { TFixed_string c(capt); _accel = c.find('~'); if (_accel > 0) _accel *= CHARX; _dx = (width - win_get_text_width(win(), (char*)caption(), -1)) >> 1; _dy = byte((height-CHARY)/2 + BASEY - DEPTH); } } TPush_button::~TPush_button() { } void TPush_button::draw_pressed(bool pressed) const { TButton::draw_pressed(pressed); const int p = pressed ? DEPTH : 0; if (_picup) { const PICTURE pic = (pressed && _picdn) ? _picdn : _picup; cpb_win_picture_draw_at(_hdc, pic, _dx+p, _dy+p); } else { const char* t = caption(); win_set_fore_color(_hdc, COLOR_WHITE); win_draw_text(_hdc, _dx+p+1, _dy+p+1, (char*)t, -1); if (_accel >= 0) win_draw_text(_hdc, _dx+_accel+p+1, _dy+p+3, "_", 1); const COLOR c = disabled() ? DISABLED_COLOR : NORMAL_COLOR; win_set_fore_color(_hdc, c); win_draw_text(_hdc, _dx+p, _dy+p, (char*)t, -1); if (_accel >= 0) win_draw_text(_hdc, _dx+_accel+p, _dy+p+2, "_", 1); } } void TPush_button::update() const { draw_pressed(FALSE); if (focused() && id() != DLG_F9) { CPEN pen; pen.width = 1; pen.pat = PAT_SOLID; pen.style = P_SOLID; pen.color = COLOR_RED; win_set_cpen(_hdc, &pen); CBRUSH brush = { PAT_HOLLOW, COLOR_WHITE }; win_set_cbrush(_hdc, &brush); win_draw_rect(_hdc, &_client); } else if (disabled() && _picup) { CPEN pen; pen.width = 1; pen.pat = PAT_SOLID; pen.style = P_SOLID; pen.color = COLOR_LTGRAY; win_set_cpen(_hdc, &pen); const int sx = _client.left+DEPTH+1; const int sy = _client.top+DEPTH+1; const int ex = _client.right-DEPTH-1; const int ey = _client.bottom-DEPTH-1; for (int i = sx; i < ex; i += 2) { PNT p = { sy, i }; win_move_to(_hdc, p); p.v = ey; win_draw_line(_hdc, p); } for (i = sy; i < ey; i += 2) { PNT p = { i, sx }; win_move_to(_hdc, p); p.h = ex; win_draw_line(_hdc, p); } } } /////////////////////////////////////////////////////////// // TPage_button /////////////////////////////////////////////////////////// class TPage_button : public TControl { enum { height = 19, width2 = 16, width = 32 }; byte _flag; protected: virtual void update() const; virtual void mouse_down(PNT where); virtual void mouse_up(); public: TPage_button(WINDOW parent, byte flag); byte get_flag() const { return _flag; } void set_flag(byte f); }; TPage_button::TPage_button(WINDOW parent, byte flag) : _flag(flag) { RCT r; get_client_rect(parent, &r); const int w = (flag == 3) ? width : width2; if (flag == 2) r.right -= w; create(r.right-w, r.bottom-height, r.right, r.bottom, "", parent, 0L, 0L, DLG_PAGE); cpb.getbmp(BMP_BOOK1 + flag -1, flag == 3); } void TPage_button::mouse_down(PNT where) { bool p; switch (_flag) { case 1: p = FALSE; break; case 2: p = TRUE; default: p = where.h < (width2); break; } check(p); } void TPage_button::mouse_up() { dispatch_e_char(get_parent(win()), checked() ? K_PREV : K_NEXT); } void TPage_button::update() const { TControl::update(); if (_flag) cpb_win_picture_draw_at(_hdc, cpb[BMP_BOOK1 + _flag -1], 0, 0); } void TPage_button::set_flag(byte f) { _flag = f; update(); } /////////////////////////////////////////////////////////// // TTag_button /////////////////////////////////////////////////////////// class TTag_button : public TControl { enum { height = 12, width = 32 }; byte _curr; byte _page; byte _pages; WINDOW _parent; protected: virtual void update() const; virtual void mouse_down(PNT where); virtual void mouse_up(); public: TTag_button(WINDOW parent, byte p, byte tot); byte get_pages() const { return _pages; } void set_pages(byte p); }; TTag_button::TTag_button(WINDOW parent, byte p, byte tot) : _parent(parent), _page(p), _pages(tot), _curr(p) { RCT r; get_client_rect(parent, &r); create(0, 0, r.right, CHARY, "", parent,0L,0L, DLG_PAGETAGS); } void TTag_button::update() const { get_geometry(win()); clear_window(_hdc, MASK_DARK_COLOR); for (int i = 0; i < _pages; i++) { RCT r; set_rect(&r, width*i, 0, width*(i+1), _client.bottom+4); CBRUSH b = { PAT_SOLID, (i == _page) ? MASK_BACK_COLOR : MASK_DARK_COLOR}; win_set_cbrush(_hdc, &b); win_set_std_cpen(_hdc, TL_PEN_BLACK); win_draw_rect(_hdc, &r); if (i == _page) xvt_draw_rect(_hdc, r, MASK_LIGHT_COLOR, MASK_BACK_COLOR); char n[4]; sprintf(n, "%d", i+1); win_set_fore_color(_hdc, NORMAL_COLOR); win_draw_text(_hdc, (width-CHARX)/2 + i*width, BASEY, n, -1); } CPEN pen; pen.width = 1; pen.pat = PAT_SOLID; pen.style = P_SOLID; pen.color = MASK_LIGHT_COLOR; win_set_cpen(_hdc, &pen); PNT p = { _client.bottom, 0 }; win_move_to(_hdc, p); p.h = width*_page; win_draw_line(_hdc, p); p.h += width+1; win_move_to(_hdc, p); p.h = _client.right; win_draw_line(_hdc, p); } void TTag_button::mouse_down(PNT where) { _curr = where.h / width; if (_curr >= _pages) _curr = _pages-1; else if (_curr < 0) _curr = 0; } void TTag_button::mouse_up() { if (_curr != _page) dispatch_e_char(_parent, K_CTRL + K_F1 + _curr); } void TTag_button::set_pages(byte p) { _pages = p; update(); } /////////////////////////////////////////////////////////// // Checkbox /////////////////////////////////////////////////////////// class TCheckbox : public TButton { static int _dy; protected: virtual WIN_TYPE type() const; virtual void draw_pressed(bool pressed) const; virtual void update() const; int radio() const { return multiple() ? 1 : 0; } public: TCheckbox(short left, short top, short right, short bottom, const char* caption, WINDOW parent, long flags, long app_data, short id); virtual ~TCheckbox(); }; int TCheckbox::_dy = -1; TCheckbox::TCheckbox( short left, short top, short right, short bottom, const char* caption, WINDOW parent, long flags, long app_data, short id) : TButton(left, top, right, bottom, caption, parent, flags, app_data, id) { if (_dy < 0) { cpb.getbmp(BMP_CHECK_ON, TRUE); cpb.getbmp(BMP_CHECK_OFF, TRUE); cpb.getbmp(BMP_RADIO_ON, TRUE); PICTURE p = cpb.getbmp(BMP_RADIO_OFF, TRUE); RCT r; cpb_get_picture_size(p, &r); _dy = BASEY - r.bottom + 2; } } TCheckbox::~TCheckbox() { } WIN_TYPE TCheckbox::type() const { return multiple() ? WC_RADIOBUTTON : WC_CHECKBOX; } void TCheckbox::draw_pressed(bool pressed) const { get_geometry(win()); PICTURE pic; if (radio()) pic = pressed ? cpb[BMP_RADIO_ON] : cpb[BMP_RADIO_OFF]; else pic = pressed ? cpb[BMP_CHECK_ON] : cpb[BMP_CHECK_OFF]; cpb_win_picture_draw_at(_hdc, pic, _client.left, _client.top+_dy); } void TCheckbox::update() const { TButton::update(); const int x = _client.left+20; const int y = _client.top + BASEY; if (focused()) { #if XVT_OS == XVT_OS_WIN RECT r; r.left = x-2; r.top = _client.top; r.right = _client.right-CHARX; r.bottom = y+3; HWND hwnd = (HWND)get_value(_hdc, ATTR_NATIVE_WINDOW); HDC hdc = GetDC(hwnd); DrawFocusRect(hdc, &r); ReleaseDC(hwnd, hdc); #endif } win_draw_text(_hdc, x, y, (char*)caption(), -1); } /////////////////////////////////////////////////////////// // User functions /////////////////////////////////////////////////////////// WINDOW xvt_create_checkbox( short left, short top, short right, short bottom, const char* caption, WINDOW parent, long flags, long app_data, int id) { TCheckbox* cb = new TCheckbox(left, top, right, bottom, caption, parent, flags, app_data, id); // It'll destroy itself automagically :-) return cb->win(); } WINDOW xvt_create_radiobutton( short left, short top, short right, short bottom, const char* caption, WINDOW parent, long flags, long app_data, int id) { flags |= CTL_FLAG_MULTIPLE; TCheckbox* cb = new TCheckbox(left, top, right, bottom, caption, parent, flags, app_data, id); // It'll destroy itself automagically :-) return cb->win(); } WINDOW xvt_create_pushbutton( short left, short top, short right, short bottom, const char* caption, WINDOW parent, long flags, long app_data, int id) { TControl* pb; switch (id) { case DLG_PAGE: pb = new TPage_button(parent, (byte)flags); break; case DLG_PAGETAGS: pb = new TTag_button(parent, (byte)flags, (byte)app_data); break; default: if (bottom-top > (CHARY<<1)) { top += BASEY>>1; bottom -= BASEY>>1; } pb = new TPush_button(left, top, right, bottom, caption, parent, flags, app_data, id); } // It'll destroy itself automagically :-) return pb->win(); } WINDOW xvt_create_text( short left, short top, short right, short bottom, const char* caption, WINDOW parent, long flags, long app_data, int id) { TText* cb = new TText(left, top, right, bottom, caption, parent, flags, app_data, id); // It'll destroy itself automagically :-) return cb->win(); } WINDOW xvt_create_groupbox( short left, short top, short right, short bottom, const char* caption, WINDOW parent, long flags, long app_data, int id) { TGroup* cb = new TGroup(left, top, right, bottom, caption, parent, flags, app_data, id); // It'll destroy itself automagically :-) return cb->win(); } void free_controls_bmp() { cpb.reset(); } TControl* TControl::WINDOW2TControl(WINDOW win) { TControl** model = (TControl**)xvtcm_get_model(win, 0); CHECK(model && *model, "Can't get the model from a window"); return *model; } void xvt_change_page_tags(WINDOW pag, bool on, WINDOW tag, byte p) { if (pag != NULL_WIN) { TPage_button* pb = (TPage_button*)TControl::WINDOW2TControl(pag); byte f = pb->get_flag(); if (on) f |= 0x1; else f &= 0x2; pb->set_flag(f); } if (tag != NULL_WIN) { TTag_button* pt = (TTag_button*)TControl::WINDOW2TControl(tag); pt->set_pages(p); } }