這篇文章讨論如何處理所有的控制台消息。
第一步,首先要安裝一個事件鈎子,也就是說要建立一個回調函數。調用win32 api,原型如下:
bool setconsolectrlhandler(
phandler_routine handlerroutine, //
回調函數
bool add // 表示添加還是删除
);
參數handlerroutine是一個指向函數的指針,原型如下:
bool winapi handlerroutine(
dword dwctrltype //
控制事件類型
所有的handlerroutine函數隻有一個參數dwctrltype,他表示控制台發出了什麼消息。參數有下列值:
ctrl_c_event - 當使用者按下了ctrl+c,或者由generateconsolectrlevent
api發出.
ctrl_break_event - 使用者按下ctrl+break,
或者由generateconsolectrlevent api發出.
ctrl_close_event -
當試圖關閉控制台程式,系統發送關閉消息。
ctrl_logoff_event -
使用者退出時,但是不能決定是哪個使用者.
ctrl_shutdown_event -
當系統被關閉時.
當收到事件的時候,handlerroutine可以選擇處理,或者簡單的忽略。如果回調函數選擇忽略,函數傳回false,系統将處理下一個鈎子程式。如果處理消息,程式在處理完消息後應該傳回true。
ctrl_close_event,
ctrl_logoff_event和ctrl_shutdown_event通常被用來處理一些程式的清理工作,然後調用exitprocess
api。另外,這三個事件有逾時機制,ctrl_close_event是5秒,另外兩個是20秒。如果程式逾時候,系統将會彈出結束程序的對話框。如果使用者選擇了結束程序,任何清理工作都不會做,是以應該在逾時時間内完成工作。下面是一個回調函數的例子:
bool winapi consolehandler(dword cevent)
{
char mesg[128];
switch(cevent)
case
ctrl_c_event:
messagebox(null,
"ctrl+c
received!","cevent",mb_ok);
break;
ctrl_break_event:
"ctrl+break
ctrl_close_event:
"program being
closed!","cevent",mb_ok);
ctrl_logoff_event:
"user is logging
off!","cevent",mb_ok);
ctrl_shutdown_event:
}
return true;
好,現在已經有了回調函數,再來看看怎麼安裝鈎子:
if
(setconsolectrlhandler(
(phandler_routine)consolehandler,true)==false)
//
unable to install handler...
// display message to the
user
printf("unable to install handler!\n");
return
-1;
第一個參數是函數指針,就是上面的那個函數。第二個參數是标志,如果為true那麼就安裝鈎子,如果為false那麼删除鈎子。
好了,在安裝了鈎子後,我們就能收到控制台消息了,在程式退出前,要删除鈎子。很簡單吧。