1158 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1158 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
extern "C"
 | 
						|
{
 | 
						|
#include <xvt.h>
 | 
						|
#include <xvtcm.h>
 | 
						|
#include <cpb.h>
 | 
						|
}
 | 
						|
 | 
						|
#if XVT_OS != XVT_OS_WIN
 | 
						|
#error "This file should be compiled for Windows only"
 | 
						|
#endif
 | 
						|
 | 
						|
#include <colors.h>
 | 
						|
#include <controls.h>
 | 
						|
#include <urldefid.h>
 | 
						|
#include <utility.h>
 | 
						|
#include <xvtility.h>
 | 
						|
 | 
						|
#include <windows.h>
 | 
						|
 | 
						|
/////////////////////////////////////////////////////////// 
 | 
						|
// 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);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// 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);
 | 
						|
  }  
 | 
						|
}
 | 
						|
 | 
						|
 |