全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2875
推到 Plurk!
推到 Facebook!

利用鍵盤鉤子實現對Ctrl+C等組合鍵的遮罩

 
conundrum
尊榮會員


發表:893
回覆:1272
積分:643
註冊:2004-01-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-03-27 02:49:33 IP:61.64.xxx.xxx 未訂閱
http://www.ahcit.com/200306  
 
利用鍵盤鉤子實現對Ctrl C等組合鍵的遮罩
                      劉華志1,朱愛紅2  徐梅
(1.海軍航空工程學院學員旅;2.海軍航空工程學院;3.同濟大學)
摘要:介紹了鉤子的概念和運行機制,給出了如何利用鍵盤鉤子實現對Ctrl C、Ctrl X和Ctrl V的攔截和遮罩。
關鍵字:鉤子,攔截,Delphi    1.引言
   有些軟體或網站為了不讓別人拷貝資訊,都做了處理,譬如:遮罩了Ctrl C和滑鼠右鍵複製功能。其實使用鍵盤鉤子
和滑鼠鉤子就可以實現對Ctrl C和滑鼠右鍵等的遮罩。本文簡單介紹了鉤子的概念和運行機制,並詳細說明了編程實現方
法。
2.Win32鉤子及其運行機制
Win32鉤子實際上是一個處理特定消息的程式段,它可以監視系統或進程中的各種事件消息,截獲發往目標視窗的消息並進
行處理。當觸發某個特定的消息時,該消息到達目的應用程式之前,鉤副程式就先得到該消息的控制權並捕獲該消息。這時
鉤副程式可以按特定的要求加工處理(改變)該消息,也可以不作任何處理而繼續傳遞該消息,還可以強制結束消息的傳遞。
對每種類型的鉤子由系統來維護一個鉤子鏈,最近安裝的鉤子放在鏈的開始,而最先安裝的鉤子放在最後,也就是後加入的
鉤子先獲得控制權。其中,全局鉤子函數必須含在DLL中,而線程專用鉤子還可以包含在執行檔中。[1]
這樣,我們就可以在系統中安裝自定義的鉤子,監視系統中特定事件的發生,完成特定的功能,比如截獲鍵盤、滑鼠的輸入、
螢幕取詞和日誌監視等等。Win32中鉤子類型很多,按事件分主要有鍵盤鉤子、滑鼠鉤子和日誌鉤子等,按使用範圍有系統
鉤子和線程鉤子。[2]
3.實現方法
(1)安裝鉤子函數
HHOOK SetWindowsHookEx(
int idHook,                  //鉤子的類型
HOOKPROC lpfn,          //安裝的鉤子函數的位址
HINSTANCE hMod,          //此函數所在模組的控制碼
DWORD dwThreadId  //所監控線程的ID
);
idHook的取值決定Hook要截獲消息的類型(如系統消息、鍵盤消息、滑鼠消息或所有消息)和截獲方式(如到達目的程
式之前還是目的程式處理之後),主要有 :WH_CALLWNDPROC、WH_CALLWNDPROCRET、WH_GETMESSAGE、           
WH_JOURNALRECORD、WH_KEYBOARD、WH_MOUSE、WH_SHELL。        
idHook的詳細使用說明請查看聯機幫助。由於本程式要實現鍵盤鉤子功能,所以選用WH_KEYBOARD。
Windows發出的消息如符合鉤子函數的條件就調用設置的鉤子函數(位址為lpfn),鉤子函數由用戶定義 ,其介面格式必
須為 :
LRESULT KeyboardHookHandler(iCode: Integer;wParam: WPARAM;lParam: LPARAM);
其中參數wParam,lParam因鉤子的類型不同有不同含義。參數iCode<0必須設置返回值Result:=CallNextHookEx
();
SetWindowsHookEx函數多數情況下在DLL中,所以hMod通常為GetModuleHandle(DllfileName:LPCTSTR);
dwThreadId如為0,表示監視所有線程。
(2)卸載鉤子函數
安裝上鉤子函數會降低系統性能,用完後應調用卸載鉤子函數UnHookWindowsHookProc以釋放系統資源。
(3)以下程式在Delphi 6.0中編譯通過。步驟如下:
①如果Hook在應用程式中實現,若應用程式不是當前視窗時,該Hook就不起作用;如果Hook在DLL中實現,程式在運
行中動態調用它,它能即時對系統進行監控。所以採用在DLL中實現Hook。新建一個導出兩個函數的DLL檔,在
HookUnit.pas中定義了鉤子具體實現過程。代碼如下:
library Hook;
uses
  HookUnit in 'HookUnit.pas';
exports
  EnableHotKeyHook,
  DisableHotKeyHook;
begin
 hNextHookProc := 0; 
 procSaveExit := ExitProc;
 ExitProc := @HotKeyHookExit;
end.
②鍵盤鉤子編程實現過程如下:
unit HookUnit;
interface
uses
  Windows, Messages;
var
  hNextHookProc: HHook;//保存SetWindowsHookEx的返回值
  procSaveExit: Pointer;
  function KeyboardHookHandler(iCode: Integer;wParam: WPARAM;lParam: LPARAM): LRESULT; stdcall; export;
  function EnableHotKeyHook: BOOL; export;//安裝鉤子
  function DisableHotKeyHook: BOOL; export;//卸載鉤子
  procedure HotKeyHookExit; far;
implementation
function KeyboardHookHandler(iCode: Integer;wParam: WPARAM;lParam: LPARAM): LRESULT; stdcall; export;
const
 _KeyPressMask=$80000000;//鍵盤遮罩常量
begin
 Result:=0;
 If iCode < 0 Then //根據SDK說明,若iCode小於0,調用CallNextHookEx並返回
  begin
   Result:=CallNextHookEx(hNextHookProc, iCode, wParam, lParam);
   Exit;
  end;
 // 監測是否按下了Ctrl X、Ctrl V、Ctrl C這三個組合鍵,若按下則退出,不響應事件
 if ((lParam and _KeyPressMask) = 0) and(GetKeyState(vk_control) <0)
    and ((wParam = Ord('X'))or(wParam = Ord('V'))or(wParam = Ord('C')))then
  begin
   Result:=1;
   Exit;
  end;
end;
function EnableHotKeyHook: BOOL; export;
begin
 Result := False;//初始化返回值
 if hNextHookProc<>0 then//如果已經註冊,直接退出
   Exit; 
//掛上鍵盤鉤子,同時傳回值必須保留下來,免得Hook呼叫鏈結斷掉
 hNextHookProc:=SetWindowsHookEx(WH_KEYBOARD,KeyboardHookHandler,HInstance,0);
//註冊hook
 Result:=hNextHookProc <> 0;//通過返回值確定是否註冊成功
end;
function DisableHotKeyHook: BOOL; export;
begin
 if hNextHookProc<>0 then
  begin
   UnhookWindowshookEx(hNextHookProc);//解除Keyboard Hook
   hNextHookProc:=0;//恢復標誌
  end;
 Result:=hNextHookProc=0;//返回是否註銷成功 
end;
procedure HotKeyHookExit;
begin
 if hNextHookProc<>0 then DisableHotKeyHook;//如果忘了解除HOOK,自動代理解除動作
 ExitProc:=procSaveExit;
end;
end.
③主程序
unit HkUnit;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;
type
  TForm1 = class(TForm)
Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;    var
  Form1: TForm1;
implementation
{$R *.DFM}
function EnableHotKeyHook: BOOL; external 'HookDll.DLL';//dll中註冊hook的函數,傳遞參數為回調
函數的指標
function DisableHotKeyHook: BOOL; external 'HookDll.DLL';//dll中登出hook的函數
procedure TForm1.Memo1ContextPopup(Sender: TObject; MousePos: TPoint;
  var Handled: Boolean);//遮罩Memo1滑鼠右鍵彈出的系統功能表
begin
 Handled:=true;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
 EnableHotKeyHook;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 DisableHotKeyHook;
end;
end.
4.總結
本文介紹了如何攔截Memo的複製、剪切和粘貼功能。調用Memo事件OnContextPopup(或新建空的PopupMenu,然後
指向Memo的PopupMenu)可以遮罩滑鼠右鍵;使用鍵盤鉤子則可以攔截Ctrl C、Ctrl X和Ctrl V,讓鍵盤失效。最
大的缺點是:運行該程式後,將無法再使用這三個組合鍵,如:Word、記事本等都無使用這三個組合鍵來進行複製、剪切
和粘貼功能,也不能用這三個組合鍵對檔或檔夾進行操作。
參考文獻:
[1].甫爾哈提•阿布都熱依木,亞森江•木沙,古麗米拉•克孜別克.關於鍵盤輸入與Win32鉤子的探討.新疆大學學報
(自然科學版)[J].2002,19(4).
[2].戴春達,符紅光.Win32中鉤子的實現技術及其應用.電腦應用[J].2002,22(8).    
發表人 - conundrum 於 2004/03/27 02:54:56
系統時間:2024-05-14 10:47:31
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!