extern "C" { #include #include } #if XVT_OS != XVT_OS_WIN #error "This file should be compiled for Windows only" #endif #include #include #include #include #include #define STRICT #include /////////////////////////////////////////////////////////// // TPicture_array /////////////////////////////////////////////////////////// class TPicture_array : public TArray { public: TImage& add(short id, bool convert = FALSE); //TImage& image(short id) { return (TImage&)operator[](id); } const TImage& image(short id) const { return (const TImage&)operator[](id); } bool exist(short id) const { return objptr(id) != NULL; } TPicture_array() : TArray(128) {} ~TPicture_array() {} }; TImage& TPicture_array::add(short id, bool convert) { TImage* i = (TImage*)objptr(id); if (i == NULL) { i = new TImage(id); TArray::add(i, id); if (convert) i->convert_to_default_colors(); } return *i; } /////////////////////////////////////////////////////////// // 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) { xvt_vobj_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;) { xvt_dwin_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; 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); drawed = TRUE; } if (rb != COLOR_LTGRAY) { if (pen.color != rb) { pen.color = rb; xvt_dwin_set_cpen(win, &pen); } if (!drawed) { 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--; } } } 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 = FALSE; _color = NORMAL_COLOR; while (*title == '@' || *title == '$') { switch (*title++) { case '@': if (toupper(*title) == 'B') bold = TRUE; break; case '$': title++; // Skip [ if (isalpha(*title)) _color = trans_color(*title); else { int r = 0, g = 0, b = 0; sscanf(title, "%d,%d,%d", &r, &g, &b); _color = MAKE_COLOR(r, g, b); } while (*title != ']') // Find ] { CHECK(*title, "Bad prompt format"); title++; } break; default: break; } title++; } const int prop_count = 1; const char* prop_list[prop_count+1] = { title, NULL }; _id = id; _disabled = (flags & CTL_FLAG_DISABLED) != 0; _checked = (flags & CTL_FLAG_CHECKED) != 0; _multiple = (flags & CTL_FLAG_MULTIPLE) != 0; _focused = FALSE; _caption = title; _caption.strip("~"); 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; xvt_vobj_set_data(_win, app_data); xvt_set_font(_win, "", int(bold ? XVT_FS_BOLD : XVT_FS_NONE)); } // Virtual destructor needed to make derived descrutors live! TControl::~TControl() {} long XVT_CALLCONV1 TControl::handler(WINDOW win, EVENT* ep) { HIDDEN bool tracking = FALSE; HIDDEN 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: xvt_win_trap_pointer(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(xvt_vobj_get_parent(win), key); break; } } break; case E_MOUSE_MOVE: if (tracking) { RCT r; xvt_vobj_get_client_rect(win, &r); if (xvt_rect_has_point(&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) { xvt_win_release_pointer(); 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(); xvt_vobj_set_enabled(win(), on); } } void TControl::check(bool on) { _checked = on; } void TControl::update() const { if (_win != _hdc) get_geometry(_win); xvt_dwin_clear(_hdc, MASK_BACK_COLOR); xvt_dwin_set_fore_color(_hdc, disabled() ? DISABLED_COLOR : 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(); xvt_dwin_set_fore_color(_hdc, color()); xvt_dwin_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; xvt_dwin_set_cpen(_hdc, &pen); CBRUSH brush = { PAT_HOLLOW, MASK_BACK_COLOR }; xvt_dwin_set_cbrush(_hdc, &brush); xvt_dwin_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()); xvt_dwin_clear(_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(); xvt_win_dispatch_event(xvt_vobj_get_parent(win()), &e); } void TButton::check(bool on) { TControl::check(on); draw_pressed(on); } /////////////////////////////////////////////////////////// // TPush button /////////////////////////////////////////////////////////// class TPush_button : public TButton { short _picup, _picdn; short _accel, _dx, _dy; 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(0), _picdn(0) { 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: if (*capt != '#') capt = format("#%d", BMP_SEARCH); break; case DLG_LINK: if (strcmp("~Collega", caption()) == 0) 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) { _picup = atoi(++diesis); const TImage& pic = cpb.add(_picup); diesis = strchr(diesis, '#'); if (diesis != NULL) { _picdn = atoi(++diesis); cpb.add(_picdn); } _dx = (width - pic.width()) >> 1; _dy = (height - pic.height()) >> 1; _accel = -1; } else { TFixed_string c(capt); _accel = c.find('~'); if (_accel > 0) _accel = xvt_dwin_get_text_width(win(), (char*)capt, _accel); _dx = (width - xvt_dwin_get_text_width(win(), (char*)caption(), -1)) >> 1; _dy = (height- CHARY)/2 + BASEY - DEPTH; } } TPush_button::~TPush_button() { } void TPush_button::draw_pressed(bool pressed) const { TButton::draw_pressed(pressed); if (_picup) { const short pic = (pressed && _picdn) ? _picdn : _picup; if (cpb.exist(pic)) { const TImage& i = cpb.image(pic); RCT dst = i.rect(); if (pressed) xvt_rect_offset(&dst, _dx+DEPTH, _dy+DEPTH); else xvt_rect_offset(&dst, _dx, _dy); i.draw(_hdc, dst); } } else { const char* t = caption(); const short x = _dx + DEPTH*pressed; const short y = _dy + DEPTH*pressed; xvt_dwin_set_fore_color(_hdc, COLOR_WHITE); xvt_dwin_draw_text(_hdc, x+1, y+1, (char*)t, -1); if (_accel >= 0) xvt_dwin_draw_text(_hdc, x+_accel+1, y+1, "_", 1); const COLOR c = disabled() ? DISABLED_COLOR : color(); xvt_dwin_set_fore_color(_hdc, c); xvt_dwin_draw_text(_hdc, x, y, (char*)t, -1); if (_accel >= 0) xvt_dwin_draw_text(_hdc, x+_accel, y+0, "_", 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; xvt_dwin_set_cpen(_hdc, &pen); CBRUSH brush = { PAT_HOLLOW, COLOR_WHITE }; xvt_dwin_set_cbrush(_hdc, &brush); xvt_dwin_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; xvt_dwin_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 }; xvt_dwin_draw_set_pos(_hdc, p); p.v = ey; xvt_dwin_draw_line(_hdc, p); } for (i = sy; i < ey; i += 2) { PNT p = { i, sx }; xvt_dwin_draw_set_pos(_hdc, p); p.h = ex; xvt_dwin_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; xvt_vobj_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.add(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(xvt_vobj_get_parent(win()), checked() ? K_PREV : K_NEXT); } void TPage_button::update() const { TControl::update(); if (_flag) cpb.image(BMP_BOOK1 + _flag -1).draw(_hdc); } 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; xvt_vobj_get_client_rect(parent, &r); create(0, 0, r.right, CHARY, "", parent,0L,0L, DLG_PAGETAGS); } void TTag_button::update() const { get_geometry(win()); xvt_dwin_clear(_hdc, MASK_DARK_COLOR); for (int i = 0; i < _pages; i++) { RCT r; xvt_rect_set(&r, width*i, 0, width*(i+1), _client.bottom+4); CBRUSH b = { PAT_SOLID, (i == _page) ? MASK_BACK_COLOR : MASK_DARK_COLOR}; xvt_dwin_set_cbrush(_hdc, &b); xvt_dwin_set_std_cpen(_hdc, TL_PEN_BLACK); xvt_dwin_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); xvt_dwin_set_fore_color(_hdc, color()); xvt_dwin_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; xvt_dwin_set_cpen(_hdc, &pen); PNT p = { _client.bottom, 0 }; xvt_dwin_draw_set_pos(_hdc, p); p.h = width*_page; xvt_dwin_draw_line(_hdc, p); p.h += width+1; xvt_dwin_draw_set_pos(_hdc, p); p.h = _client.right; xvt_dwin_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 { 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(); }; 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 (!cpb.exist(BMP_CHECK_ON)) { TImage& i = cpb.add(BMP_CHECK_ON, TRUE); const short dx = 0; const short dy = BASEY - i.height() + 2; i.set_pos(dx, dy); cpb.add(BMP_CHECK_OFF, TRUE).set_pos(dx, dy); cpb.add(BMP_RADIO_ON, TRUE).set_pos(dx, dy); cpb.add(BMP_RADIO_OFF, TRUE).set_pos(dx, dy); } } TCheckbox::~TCheckbox() { } WIN_TYPE TCheckbox::type() const { return multiple() ? WC_RADIOBUTTON : WC_CHECKBOX; } void TCheckbox::draw_pressed(bool pressed) const { get_geometry(win()); short pic; if (radio()) pic = pressed ? BMP_RADIO_ON : BMP_RADIO_OFF; else pic = pressed ? BMP_CHECK_ON : BMP_CHECK_OFF; if (cpb.exist(pic)) cpb.image(pic).draw(_hdc); } 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)xvt_vobj_get_attr(_hdc, ATTR_NATIVE_WINDOW); HDC hdc = GetDC(hwnd); DrawFocusRect(hdc, &r); ReleaseDC(hwnd, hdc); #endif } xvt_dwin_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.destroy(); } TControl* TControl::WINDOW2TControl(WINDOW win) { CHECK(win, "Can't get the control model from a NULL window"); TControl** model = (TControl**)xvtcm_get_model(win, 0); CHECK(model && *model, "Can't get the control 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); } }