有好几种方法可以使Ctrl+Break功能失效,这里只讨论两种最常用的方法。
第一种方法是用DOS来解除Ctrl+Break功能。
你可能用DOS中断21H的33H函数来得到或设置Ctrl+Break检查标志,该标志告诉DOS是否在Ctrl+Break按下时对其进行处理。下面的例子说明了这种方法:
# include <stdio.h>
# include <dos.h>
void main(int argc,char **argv)
{
union REGS regs;
int ctrlBreakFlag ;
/* find out the curre.nt state of the flag */
regs. x. ax= 0x3300 ; /* subfunction 0 gets flag state */
int86 (0x21, ®s, ®s) ;
ctrlBreakFlag == rags. h. dl ; /* save flag value from DL */
/* set the state of the flag to disable Ctrl+Break */
regs. x. ax=0x3301;
regs. h. dl = 0 ; /* disable checking */
int86(0x21,®s, ®s) ; /* subfunction 1 sets flag state */
}
上例首先调用DOS来查询Ctrl+Break检查标志的当前状态,并将其存入ctrlBreakFlag中。DOS调用的返回值存在DL中,如果解除了Ctrl+Break检查,则该值为O;如果允许Ctrl+Break检查,则该值为1。接着,上例清除DL并调用DOS的设置Ctrl+Break标志函数来解除Ctrl+Break检查。在调用上述函数重新设置Ctrl+Break标志之前,此次所设置的状态将一直保留。上例没有用到子函数02(AX一0x3302),该函数能同时得到并设置Ctrl+Break标志的状态,为了完成这项任务,你应该把0x3302放到AX中,把要求的Ctrl+Break标志状态放到DL中,然后进行中断,并把原来的状态从DL中存入ctrlBreakFlag中。
第二种方法是使用信号(signal)。
信号是从过去的UNIX时代继承下来的。信号函数的作用是在某些事件发生时通知程序员,这些事件之一就是用户中断——在DOS下就是Ctrl+Break事件。下面的例子说明了如何用Microsoft的signal()函数来捕获Ctrl+Break事件并作出反应(假设允许Ctrl+Break检查):
# include <stdio.h>
# include <signal.h>
int exitHandler (void) ;
int main (int argc,char ** argv)
{
int quitFlag = 0 ;
/* Trap all Ctrl+Breaks */
signal (SIGINT, (void (__cdecl * ) (int))exitHandler);
/* Sit in infinite loop until user presses Ctrl+Break */
while (quitFlag = = 0)
printf (" % s\", (argv > 1 ) ? argv [ 1 ] : "Waiting for Ctrl + Break" );
}
/* Ctrl+Break event handler function */
int exitHandler ()
{
char ch ;
/* Disable Ctrl+Break handling while inside the handler */
signal (SIGINT, SIG_ IGN ) ;
/* Since it was an "interrupt",clear keyboard input buffer */
fflush(stdin) ;
/* Ask if user really wants to quit program */
printf("\nCtrl+Break occurred. Do you wish to exit this program? →(Y or N)");
/* Flush output buffer as well */
fflush (stdout) ;
/* Get input from user, print character and newline */
ch =getche ( ) ;
printf("\n" ) ;
/* If user said yes, leave program */
if(toupper (eh) = 'Y' )
exit (0) ;
/* Reenable Ctrl+Break handling */
signal (SIGINT, (void (__cdecl * ) (int))exitHandler) ;
return(0) ;
}
上例的好处在于每当按下Ctrl+Break时都会调用一个函数,也就是说,你可以选择将要作出的反应一一你可以忽略这个事件,相当于解除Ctrl+Break功能;你也可以作出所需的其它任何反应;上例的另一个好处是当程序退出时,Ctrl+Break的正常操作就会恢复,不需要人为的干预。