📄 getxch.c
字号:
/* CXL - Copyright (c) 1987-1990 by Mike Smedley - All Rights Reserved */
/* GETXCH.C - gets a key (ASCII code/extended ASCII code) from keyboard */
#include <conio.h>
#include <dos.h>
#include <stdlib.h>
#include "cxldef.h"
#include "cxlkey.h"
#include "cxlmou.h"
#include "cxlvid.h"
#include "cxlwin.h"
#if defined(_M_IX86)
#define bioskey(a) _bios_keybrd(a)
#endif
static void call_func(void (*func)(void));
static struct _item_t *find_hotkey(struct _menu_t *wmenu,unsigned xch);
unsigned getxch(void)
{
register unsigned int xch;
int bstat,mrow,mcol,bcount;
struct _onkey_t *onkey;
struct _kbuf_t *kbuf;
struct _item_t *item;
/* check for any keys in the CXL keyboard "buffer" */
if(_kbinfo.kbuf==NULL) {
/* reset mouse position, left button, and right button */
if((_mouse&MS_KEYS)&&!kbhit()) {
msgotoxy(12,40);
msbclear();
}
/* loop until a key has no match in the defined onkey linked list */
for(;;) {
Continue:
/* if mouse installed, translate movements/button presses */
if((_mouse&MS_KEYS)&&!kbhit()) {
/* set keypress source to default to mouse. if a key */
/* is actually pressed, then it will be changed. */
_kbinfo.source=2;
for(;;) {
/* check CXL's keyboard buffer for keystrokes */
if(_kbinfo.kbuf!=NULL) goto keybuf;
/* process keyboard loop handler */
if(_kbinfo.kbloop!=NULL) (*_kbinfo.kbloop) ();
/* check keyboard for activity. if a key has */
/* been pressed, leave keyboard/mouse wait loop */
if(kbhit()) {
xch=bioskey(0);
_kbinfo.source=0;
break;
}
/* check left button for activity. if it has */
/* been pressed, translate it to the Enter key, */
/* and leave keyboard/mouse wait loop */
msbreles(0,&bstat,&bcount,&mrow,&mcol);
if(bcount) {
xch=0x1c0d; /* Enter */
break;
}
/* check right button for activity. if it has */
/* been pressed, translate it to the Esc key, */
/* and leave keyboard/mouse wait loop. */
msbreles(1,&bstat,&bcount,&mrow,&mcol);
if(bcount) {
xch=0x011b; /* Esc */
break;
}
/* read mouse status. check direction */
/* of mouse movement and translate it */
/* into one of the arrow keys. */
msstatus(&bstat,&mrow,&mcol);
xch=0;
if(mrow<11) xch=0x4800; /* Up */
else if(mrow>13) xch=0x5000; /* Down */
else if(mcol<37) xch=0x4b00; /* Left */
else if(mcol>43) xch=0x4d00; /* Right */
if(xch) break;
}
}
else {
/* check CXL's keyboard buffer for keystrokes */
if(_kbinfo.kbuf!=NULL) goto keybuf;
/* process keyboard loop handler */
if(_kbinfo.kbloop!=NULL) while(!kbhit()) (*_kbinfo.kbloop) ();
/* get key from keyboard */
xch=bioskey(0);
_kbinfo.source=0;
}
/* search through onkey linked list for a */
/* matching defined onkey. if one is found, */
/* then save the current environment, call the */
/* onkey's function, and restore the environment. */
onkey=_kbinfo.onkey;
while(onkey!=NULL) {
if( onkey->keycode == xch ) {
call_func(onkey->func);
if(_kbinfo.inmenu&&(_mouse&MS_CURS)) return(0);
break;
}
onkey=onkey->prev;
}
if(onkey!=NULL) {
if(!onkey->pass) continue;
xch=onkey->pass;
break;
}
/* search for a menu hot key. if one is found, */
/* then save the current environment, call the */
/* hotkey's function, and restore the environment. */
if(_winfo.menu!=NULL&&xch) {
item=find_hotkey(_winfo.menu,xch);
if(item!=NULL) {
call_func(item->select);
if(_kbinfo.inmenu&&(_mouse&MS_CURS)) return(0);
goto Continue;
}
}
break;
}
}
else {
keybuf:
/* return key from top of buffer */
xch=_kbinfo.kbuf->xch;
/* set variable to indicate that key came from buffer */
_kbinfo.source=1;
/* free keypress record and update linked list */
kbuf=_kbinfo.kbuf->next;
free(_kbinfo.kbuf);
_kbinfo.kbuf=kbuf;
if(_kbinfo.kbuf!=NULL) _kbinfo.kbuf->prev=NULL;
}
/* return keypress */
return(xch);
}
/*---------------------------------------------------------------------------*/
static void call_func(void (*func)(void))
{
struct _menu_t *menu;
int sline,eline,row,col;
getcursz(&sline,&eline);
readcur(&row,&col);
menu=_winfo.cmenu;
(*func)();
_winfo.cmenu=menu;
gotoxy_(row,col);
setcursz(sline,eline);
}
/*---------------------------------------------------------------------------*/
static struct _item_t *find_hotkey(struct _menu_t *wmenu,unsigned xch)
{
struct _item_t *witem,*item;
/* do while more items in this menu */
for(witem=wmenu->item;witem!=NULL;witem=witem->prev) {
/* if hot key matches keypress, return its item address */
if(witem->hotkey==xch&&(!(witem->fmask&M_NOSEL))&&witem->select!=NULL)
return(witem);
/* if current item has a child menu, process it */
if(witem->child!=NULL) {
item=find_hotkey(witem->child,xch);
if(item!=NULL) return(item);
}
}
/* return address of item found */
return(witem);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -