📄 eventlow.c
字号:
/* BUG FIX FOR WORKS : don't repeat ENTER or ALT KEYS */
!(kk & KK_MENU) && wParamKey != LOBYTE(VK_RETURN))
{
/* coallese keydown repeat counts */
pmsgLast->lParam++;
return; /* message already posted */
}
kk |= vk;
}
else if (vw != 0)
{
/* key released */
message = WM_KEYUP;
kk |= vk;
}
else
{
/* just change in shift state */
/* wParamKey = kkOld, kk = kkNew */
if (pmsgLastKeyboard->message == WM_KEYSTATE)
{
/* coalesce shift key transitions */
pmsgLastKeyboard->wParam = kk;
SetMessage();
return;
}
message = WM_KEYSTATE;
wParamKey = kk; /* new shift states */
}
#ifdef KANJI
if (!FQueueMsg(&msgqKeyboard, NULL, message, wParamKey,
MAKELONG(MAKEWORD(1 | kj, sc), kk),
#else
if (!FQueueMsg(&msgqKeyboard, NULL, message, wParamKey, MAKELONG(1, kk),
#endif /*KANJI*/
ClockTicks()))
{
/* buffer full !! */
Beep();
}
pmsgLastKeyboard = pmsgLast;
SetMessage(); /* after every key event seen here */
}
VOID FAR PASCAL
MouseMessage(message)
/*
-- post a mouse message
-- This routine is called as part of an interrupt service routine.
It does not ensure that SS == DS, so this routine, and any routine
it calls MUST NOT take the address of stack variables (procedure
parameters and locals).
Message format :
message = WM_...
wParam = MK_ code for keys down
lParam = mouse coordinates
LOBYTE(LOWORD(lParam)) = rx
HIBYTE(LOWORD(lParam)) = ry
LOBYTE(HIWORD(lParam)) = ax
HIBYTE(HIWORD(lParam)) = ay
*/
WORD message;
{
REGISTER WORD wParam = sstMouse;
if (message == WM_MOUSEMOVE)
{
if (mspPrev.s.ay == ayMouse && mspPrev.s.ax == axMouse)
return; /* same place */
mspPrev.s.ax = axMouse;
mspPrev.s.ay = ayMouse;
if (pmsgLast->message == WM_MOUSEMOVE)
{
/* change coordinates of last message */
pmsgLast->lParam = mspPrev.lParam;
return;
}
/* only set Message if the mouse moved with a button down */
if (wParam != 0)
SetMessage();
}
else
{
SetMessage();
}
/* get shift states from keyboard handler */
wParam |= MkGetShiftStates();
FQueueMsg(&msgqMouse, NULL, message, wParam,
mspPrev.lParam, ClockTicks());
}
PRIVATE BOOL
FQueueMsg(pmsgq, pwnd, message, wParam, lParam, time)
/*
-- Queue a message - return TRUE if Queued
-- does not set Message
-- can be called from TSR with SS != DS
*/
MSGQ *pmsgq;
PWND pwnd;
WORD message, wParam;
DWORD lParam;
DWORD time;
{
PMSG pmsg;
if (pmsgq->cmsg == imsgMax)
return(FALSE);
pmsg = pmsgq->pmsgNext;
/* NOTE : we can only change the head if it was pointing at msgNull */
if (pmsgq->cmsg++ == 0)
{
/* count was 0 => we better be pointing to msgNull */
Assert(pmsgq->pmsgHead == &msgNull);
pmsgq->pmsgHead = pmsg; /* set head */
}
else
{
Assert(pmsgq->pmsgHead != &msgNull);
}
if (++(pmsgq->pmsgNext) == &pmsgq->rgmsg[imsgMax])
pmsgq->pmsgNext = &pmsgq->rgmsg[0]; /* wrap around */
pmsgLast = pmsg;
pmsg->pwnd = pwnd;
pmsg->message = message;
pmsg->wParam = wParam;
pmsg->lParam = lParam;
pmsg->time = time;
return(TRUE);
}
STATIC PWND
PwndLocate(pwnd, ax, ay)
REGISTER PWND pwnd;
AX ax;
AY ay;
/*
-- Check if the mouse is pointing within or to a sibbling of the current
window.
-- returns pointer to window in containing mouse or NULL if none
*/
{
AssertSz(pwnd != NULL, "invalid call to PwndLocate");
do
{
if ((ax < pwnd->arcWindow.axRight) &&
(ax >= pwnd->arcWindow.axLeft) &&
(ay < pwnd->arcWindow.ayBottom) &&
(ay >= pwnd->arcWindow.ayTop) &&
pwnd->fEnabled)
return(pwnd);
pwnd = pwnd->pwndSibling;
}
while (pwnd);
return(NULL);
}
PRIVATE VOID
FindMouseWnd(pmsg)
/*
-- convert mouse message to indicate the receiver of the message
-- If WINDOW_OVERLAP is defined we can simply use the Overlap array to
convert the X,Y to a window pointer, else we must search.
*/
REGISTER PMSG pmsg;
{
REGISTER PWND pwnd;
MSP msp;
AX ax;
AY ay;
msp.lParam = pmsg->lParam;
ax = msp.s.ax;
ay = msp.s.ay;
Assert(pmsg->message >= WM_MOUSEFIRST && pmsg->message <= WM_MOUSELAST);
if (pwndRoot == NULL)
{
/* return absolute coordinates only */
pmsg->pwnd = NULL;
pmsg->lParam = msp.lParam;
return;
}
if (pwndCapture != NULL)
{
pwnd = pwndCapture;
}
else
{
#ifdef WINDOW_OVERLAP
if (psOverlap)
{
/* psOverlap is the segment of the array containing
* the overlapping window array. */
pwnd = *((PWND FAR *) MAKELONG(
sizeof(PWND)*(ay * axMac + ax), psOverlap));
}
else
#endif /* WINDOW_OVERLAP */
{
if (pwnd = PwndLocate(pwndRoot, ax, ay))
{
PWND pwndChild;
/* found the root window containing mouse */
/* scan till no more children or mouse is
outside all pwnd's children */
while ((pwndChild = pwnd->pwndChild) != NULL &&
(pwndChild = PwndLocate(pwndChild, ax, ay))
!= NULL)
pwnd = pwndChild;
}
}
}
if (pwnd == NULL)
{
/* no enabled window to receive mouse input */
Assert(pmsg->pwnd == NULL);
return;
}
/* update msg with window specific info */
pmsg->pwnd = pwnd;
msp.s.rx = ax - pwnd->arcClipping.axLeft;
msp.s.ry = ay - pwnd->arcClipping.ayTop;
/* set bits for non-client */
if (ax < pwnd->arcClipping.axLeft ||
ax >= pwnd->arcClipping.axRight)
pmsg->wParam |= MK_NONCLIENT_X;
if (ay < pwnd->arcClipping.ayTop ||
ay >= pwnd->arcClipping.ayBottom)
pmsg->wParam |= MK_NONCLIENT_Y;
pmsg->lParam = msp.lParam;
}
STATIC VOID
CheckDoubleClick(pmsg)
/*
-- test to see if message should be converted to a double click
*/
REGISTER PMSG pmsg;
{
static DWORD timeLeft = 0L;
static DWORD timeRight = 0L;
static DWORD lParamOld;
if (pmsg->lParam != lParamOld) /* mouse has moved */
{
lParamOld = pmsg->lParam;
timeLeft = timeRight = 0L;
}
else if (pmsg->message == WM_LBUTTONDOWN)
{
if (timeLeft && pmsg->time - timeLeft < timeDoubleClick)
{
pmsg->message = WM_LBUTTONDBLCLK;
timeLeft = 0L;
}
else
{
timeLeft = pmsg->time;
}
}
else if (pmsg->message == WM_RBUTTONDOWN)
{
if (timeRight && pmsg->time - timeRight < timeDoubleClick)
{
pmsg->message = WM_RBUTTONDBLCLK;
timeRight = 0L;
}
else
{
timeRight = pmsg->time;
}
}
}
PRIVATE BOOL FARPRIVATE
DummyFilter(pmsg)
PMSG pmsg;
{
Unreferenced(pmsg);
return(FALSE);
}
VOID FAR PASCAL /* called by keyboard driver */
SpecialTsrAbort()
/*
-- special TSR abort occured
-- set the fAbort flag
-- flush the input buffer (should contain at most 1 character)
-- insert 1 ESCAPE message
-- can be called from TSR with SS != DS
*/
{
#ifdef DUAL
if (fProtectMode)
return;
#endif /*DUAL */
#ifndef DOS5
Assert(!fNormalKeyboard); /* only call if TSR driven keyboard */
fAbort = TRUE;
FlushAbort();
FQueueMsg(&msgqKeyboard, NULL, WM_CHAR, LOBYTE(VK_ESCAPE), MAKELONG(1, VK_ESCAPE),
ClockTicks());
#endif /*!DOS5*/
}
BOOL FAR PASCAL /* called by keyboard driver */
FTestKeyboardEmpty()
/*
-- return TRUE if there is enough room to place 1 key event in buffer
-- we need worst case 4 messages for each key
(ALT DOWN, SPACE UP, key, ALT UP).
-- do special work for TSR
*/
{
if (fNormalKeyboard)
return (msgqKeyboard.cmsg < imsgMax - 4);
else
{
/* if TSR (i.e. MSKEY), then only look 1 ahead (for repeat)
but not if previous was an ALT DOWN */
if (msgqKeyboard.cmsg > 1)
return FALSE; /* no chance */
else if (msgqKeyboard.cmsg == 0)
return TRUE; /* we have room */
else
{
/* if last event was MENU (either UP or DOWN)
then don't allow any more */
return (pmsgLastKeyboard->wParam != VK_MENU);
}
}
}
VOID FAR PASCAL
FlushKeyEvents()
/*
-- flush key events from CW queue
-- put them back into keyboard buffer
*/
{
char rgch[imsgMax + 10]; /* max queue size + extra */
char * pch = rgch;
REG MSG * pmsg;
while ((pmsg = msgqKeyboard.pmsgHead) != &msgNull)
{
DequeueTopMsg(&msgqKeyboard);
if (pmsg->message == WM_CHAR && pmsg->wParam < VK_MIN)
{
/* a real character */
*pch++ = (char) pmsg->wParam;
}
}
*pch = '\0'; /* terminate array */
inkj.pfnFlushKeyRgchKbd(rgch);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -