📄 mouse.cpp
字号:
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 + -