⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mouse.cpp

📁 这是一个C++编程文档
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    hotx   = cgc->hotx;
    hoty   = cgc->hoty;
    height = cgc->cHeight - 1;
    width  = cgc->cWidth  - 1;
  }
  else
  {
    hotx   = gc->hotx;
    hoty   = gc->hoty;
    height = gc->cHeight - 1;
    width  = gc->cWidth  - 1;
  }

  if((current.x >= (left-width+hotx)) && (current.y >= (top-height+hoty)) &&
     (current.x <= (right+hotx)) && (current.y <= (bottom+hoty)))
    Hide();
  else
    Show();
}

void Mouse::SetClickThreshold(unsigned time)
{
  clickThreshold = time;		// time is in milliseconds
}

int Mouse::MultiClick(int button)	// check for multiple clicks
{
  if(!exists || !enabled) return(0);

  return Click[button >> 1].count;
}

int Mouse::DoubleClick(int button)     // check for double clicks
{
  if(!exists || !enabled) return(0);

  return (Click[button >> 1].count == 2);
}

void Mouse::ClearClick(int button)	// clear the MultiClick buffer
{					//   button = 7 is the default
  if(!exists || !enabled) return;	//   which clears all the buttons

  if(button & LEFTBUTTON)
    Click[0].count = 0;
  if(button & RIGHTBUTTON)
    Click[1].count = 0;
  if(button & CENTERBUTTON)
    Click[2].count = 0;
}

/* ----- Event Handler routines --------------------------------------- */

void interrupt MouseHandler(void)	// default event handler
{
  mouse.Save(_AX,_BX,_CX,_DX,_DI,_SI);  // save the normal stuff
  EventExit();				// required for interrupt function
}

void Mouse::InstallHandler(void)
{
  unsigned seg, off;

  if(!exists) return;

  unsigned char mask = currentHandler.mask;
  if(cgcActive)
    mask |= MOUSE_MOVED;		// ColorGraphicsCursors require this

  seg = currentHandler.segment;
  off = currentHandler.offset;
  _ES = seg;
  _DX = off;
  _CX = mask;
  _AX = 0x14;
  geninterrupt(0x33);

  handlerInstalled = 1;
  buffer.Clear();
}

void Mouse::InstallHandler(unsigned char mask,
                           void interrupt (*handler)(void))
{
  if(!exists) return;

  currentHandler.mask    = mask;
  currentHandler.segment = FP_SEG(handler);
  currentHandler.offset  = FP_OFF(handler);

  InstallHandler();
}

void Mouse::InstallHandler(MouseEventHandler& handler)
{					// install an event handler
  currentHandler = handler;
  InstallHandler();
}

void Mouse::ClearHandler(void)		// clear the event handler
{
  if(!exists) return;

  _ES = 0;
  _DX = 0;
  _CX = 0;
  _AX = 0x14;
  geninterrupt(0x33);

  handlerInstalled = 0;
  buffer.Clear();
}
					// save an event to the buffer
void Mouse::Save(int event, int button,
                 int x, int y, int xcount, int ycount)
{
  static unsigned char keymask;
  static unsigned long time;

  if(cgcActive && (event & MOUSE_MOVED))
  {
    cgc->x = x;
    cgc->y = y;

    if(visible)
      cgc->Move();

    if(!(currentHandler.mask & MOUSE_MOVED))
      return;
  }

  if(buffer.IsFull())
    return;

  if(event & MB_PRESSED)
  {
    time = *(unsigned long far *)MK_FP(0x0040, 0x006C)*55;
    keymask = *(char far *)MK_FP(0x0040, 0x0017);

    button += (keymask << 4);
    if(keymask & 0x03)
      button += 0x08;

    if(event & LB_PRESSED)
    {
      Repeat[0].count = 0;
      Repeat[0].time  = time;
    }
    if(event & RB_PRESSED)
    {
      Repeat[1].count = 0;
      Repeat[1].time  = time;
    }
    if(event & CB_PRESSED)
    {
      Repeat[2].count = 0;
      Repeat[2].time  = time;
    }
  }
  else
    time = 0;				// no button press so time not needed

  buffer.PutEvent(event, button, x, y, xcount, ycount, time);
}

void Mouse::GetEvent(void)		// get an event from the buffer
{
  if(!exists || !enabled) return;

  if(buffer.HasEvent())			// if an event is available...
  {
    current = buffer.GetEvent();

    if(current.time)			// store info for MultiClick()
    {
      if(current.event & LB_PRESSED)
      {
        if((current.time - Click[0].time) < clickThreshold)
          Click[0].count++;
        else
          Click[0].count = 1;

        Click[0].time = current.time;
      }
      if(current.event & RB_PRESSED)
      {
        if((current.time - Click[1].time) < clickThreshold)
          Click[1].count++;
        else
          Click[1].count = 1;

        Click[1].time = current.time;
      }
      if(current.event & CB_PRESSED)
      {
        if((current.time - Click[2].time) < clickThreshold)
          Click[2].count++;
        else
          Click[2].count = 1;

        Click[2].time = current.time;
      }
    }
  }
  else
  {
    current.event  = 0;
    current.xcount = 0;
    current.ycount = 0;
  }
}

void Mouse::ClearEvent(void)		// clear the current event
{
  current.event  = 0;
  current.button = 0;
  current.x      = 0;
  current.y      = 0;
  current.xcount = 0;
  current.ycount = 0;
}

void Mouse::ClearBuffer(void)		// clear the event buffer
{
  buffer.Clear();
}

/* ----- Repeater routines -------------------------------------------- */

void interrupt RepeatHandler(...)
{
  (*oldInterrupt_1C)();
  mouse.Repeater();
}

void Mouse::Repeater(void)
{
  static int x, y;
  static unsigned char event, button, mbutton, keymask;
  static long time, dtime;

  if(repeatRate == 0)			// repeat feature is off
    return;
  if(buffer.IsFull())
    return;

  time = *(long far *)MK_FP(0x0040, 0x006C)*55;

  _AX = 0x03;				// get the current mouse position
  geninterrupt(0x33);			//  & button status
  button = _BL;
  x = _CX;
  y = _DX;

  if(button & LEFTBUTTON & repeatMask)
  {
    mbutton = 0;
    event = LB_PRESSED;
  }
  else if(button & RIGHTBUTTON & repeatMask)
  {
    mbutton = 1;
    event = RB_PRESSED;
  }
  else if(button & CENTERBUTTON & repeatMask)
  {
    mbutton = 2;
    event = CB_PRESSED;
  }
  else
    return;

  dtime = time - Repeat[mbutton].time;	// time since the last repeat

  if((!Repeat[mbutton].count && (dtime >= repeatDelay)) ||
      (Repeat[mbutton].count && (dtime >= repeatRate)))
  {
    keymask = *(char far *)MK_FP(0x0040, 0x0017);

    button += (keymask << 4);		// add it to the button mask
    if(keymask & 0x03)
      button += 0x08;

    buffer.PutEvent(event, button, x, y, 0, 0, time);

    Repeat[mbutton].count++;		// increment the click count
    Repeat[mbutton].time = time;
  }
}

void Mouse::SetRepeatRate(unsigned char button,
                          unsigned delay, unsigned rate)
{
  repeatMask  = button;
  repeatDelay = delay;
  repeatRate  = rate;
}

/* ----- EventBuffer methods ------------------------------------------ */

int EventBuffer::IsFull(void)
{
  if(headPtr == tailPtr-1)
    return 1;
  if(headPtr == MOUSE_BUFFER_SIZE-1 && tailPtr == 0)
    return 1;
  return 0;
}

int EventBuffer::HasEvent(void)
{
  return (headPtr != tailPtr);
}

void EventBuffer::PutEvent(unsigned char event, unsigned char button,
                           unsigned x, unsigned y,
	                   unsigned xcount, unsigned ycount,
		           unsigned long time)
{
  buffer[headPtr].event  = event;	// store the info in the event buffer
  buffer[headPtr].button = button;
  buffer[headPtr].x      = x;
  buffer[headPtr].y      = y;
  buffer[headPtr].xcount = xcount;
  buffer[headPtr].ycount = ycount;
  buffer[headPtr].time   = time;

  if(++headPtr >= MOUSE_BUFFER_SIZE)	// increment the head ptr
    headPtr = 0;
}

MouseEvent EventBuffer::GetEvent(void)
{
  MouseEvent event = buffer[tailPtr];

  if(++tailPtr >= MOUSE_BUFFER_SIZE)
    tailPtr = 0;

  return event;
}

void EventBuffer::Clear(void)
{
  headPtr = 0;
  tailPtr = 0;
}

/* ----- MouseEventHandler methods ------------------------------------ */

MouseEventHandler::MouseEventHandler(void)
{
  mask = 0;
  segment = 0;
  offset  = 0;
}

MouseEventHandler::MouseEventHandler(unsigned char mask,
                                     void interrupt (*handler)(void))
{
  this->mask = mask;
  segment = FP_SEG(handler);
  offset  = FP_OFF(handler);
}

void MouseEventHandler::Install(void)
{
  mouse.InstallHandler(*this);
}

/* ----- Cursor constructors ------------------------------------------ */

TextCursor::TextCursor(unsigned sMask, unsigned cMask, int type)
{
  this->sMask = sMask;
  this->cMask = cMask;
  this->type  = type;
}

GraphicsCursor::GraphicsCursor(unsigned char hotx, unsigned char hoty,
                               unsigned image[],
                               unsigned char width, unsigned char height,
                               unsigned char type)
{
  cImage     = image;
  this->hotx = hotx;
  this->hoty = hoty;
  cWidth     = width;
  cHeight    = height;
  cWords     = width/16 + (width%16 ? 1 : 0);
  this->type = type;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -