delphi xe2 怎么实现屏蔽ctrl+alt+del组合键,网络上找到一段代码 可是测试了下 不能用 郁闷了。
还请各位大大指教 谢谢
注:delphi版本是xe2的 原来在delphi2007上是有个小控件可以实现 现在xe2这个控件跑不动了 只能想办法diy了。

解决方案 »

  1.   

    代码如下:
    unit unt_HookCtrlAltDelWin;interfaceuses Windows, TLHelp32,SysUtils,Messages;
    type
      {按键消息的结构,Delphi中也没有,自己定义吧。这也就是我为什么说用C写
    这样的程序更好的原因之一。还必须注意的是这个结构在Windows NT 4 sp3以上系统中才能使用}
    tagKBDLLHOOKSTRUCT = packed record
      vkCode: DWORD;//虚拟键值
      scanCode: DWORD;//扫描码值(没有用过,我也不懂^_^)
      {一些扩展标志,这个值比较麻烦,MSDN上说得也不太明白,但是
      根据这个程序,这个标志值的第六位数(二进制)为1时,Alt键按下为0}
      flags: DWORD;
      time: DWORD;//消息时间戳
      dwExtraInfo: DWORD;//和消息相关的扩展信息
    end;
      KBDLLHOOKSTRUCT = tagKBDLLHOOKSTRUCT;
      PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;
    //这个是低级键盘钩子的索引值,Delphi中没有,必须自己定义
    const
     WH_KEYBOARD_LL = 13;
    //定义一个常量好和上面那个结构中的flags比较而得出Alt键是否按下
     LLKHF_ALTDOWN = $20;    //屏蔽热键用www.2cto.com
     MyKernel='SnowmanLockScreenHook.Dll';  //释放完得文件名,可以自己改
     Winlogon='winlogon.exe';
     MyKernelSize=9216;
     MyKernelBuf:Array [0..9215] of Byte =
     (
       。。 );
    procedure RunFuckCAD;
    procedure StopFuckCAD;var
      hhkLowLevelKybd: HHOOK;
    implementation{-------------------------------------------------------------------------------
    功能:低级键盘钩子的回调函数,在里面过滤消息
    作者:刘斌
    参数: nCode   是Hook的标志
         WParam  表示消息的类型
         LParam  是一个指向我们在上面定义的那个结构KBDLLHOOKSTRUCT的指针
    返回值:如果不是0的话,Windows就把这个消息丢掉,程序就不会再收到这个消息了。
    -------------------------------------------------------------------------------}
    function LowLevelKeyboardProc(nCode: Integer;
      WParam: WPARAM;LParam: LPARAM):LRESULT; stdcall;
    var
      fEatKeystroke: BOOL;
      p: PKBDLLHOOKSTRUCT;
    begin
      Result := 0;
      fEatKeystroke := FALSE;
      p := PKBDLLHOOKSTRUCT (lParam);
      //nCode值为HC_ACTION时表示WParam和LParam参数包含了按键消息
      if (nCode = HC_ACTION) then
      begin
      //拦截按键消息并测试是否是Ctrl+Esc、Alt+Tab和Alt+Esc功能键
        case wParam of
          WM_KEYDOWN,
          WM_SYSKEYDOWN,
          WM_KEYUP,
          WM_SYSKEYUP:
               fEatKeystroke :=(P.vkCode = VK_Lwin) or (P.vkCode = VK_Rwin)or (P.vkCode = VK_apps)or
              ((p.vkCode = VK_TAB) and ((p.flags and LLKHF_ALTDOWN) <> 0)) or
              ((p.vkCode = VK_ESCAPE) and ((p.flags and LLKHF_ALTDOWN) <> 0)) or
              ((p.vkCode = VK_CLEAR) and ((p.flags and LLKHF_ALTDOWN) <> 0)) or
              ((p.vkCode = VK_ESCAPE) and ((GetKeyState(VK_CONTROL) and $8000) <> 0));
        end;
      end;
      if fEatKeystroke = True then
        Result := 1;
      if nCode <> 0 then
         Result := CallNextHookEx(0, nCode, wParam, lParam);
    end;
    procedure GetDebugPrivs;  //提升到Debug权限
    var
     hToken: THandle;
     tkp: TTokenPrivileges;
     retval: dword;
    begin
     If (OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)) then
     begin
       LookupPrivilegeValue(nil, 'SeDebugPrivilege'  , tkp.Privileges[0].Luid);
       tkp.PrivilegeCount := 1;
       tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
       AdjustTokenPrivileges(hToken, False, tkp, 0, nil, retval);
     end;
    end;function NameToPID(ExeName:pansichar):longword;
    //通过进程文件名返回一个Pid,如果多个同名进程返回第一个进程的Pid
     var
       hSnap:longword;
       ProcessEntry: TProcessEntry32;
       c:boolean;
     begin
       result:=0;
       hSnap:= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
       ProcessEntry.dwSize:= Sizeof(TProcessEntry32);
       c:= Process32First(hSnap,ProcessEntry);
       While c  do
         begin
           if LstrcmpiA(ExeName,ProcessEntry.szExeFile)= 0 then
              begin
                result:=ProcessEntry.th32ProcessID;
                break;
              end;
           c:=Process32Next(hSnap,ProcessEntry);
         end;
       CloseHandle(hSnap);
     end;function GetSysPath:pchar;  //最后没加'/'
     var
      a:pchar;
     begin
      GetMem(a,255);
      GetSystemDirectory(a,255);
      Result:=a;
     end;
    procedure DelKernel;
     begin
       DeleteFile(pchar(string(GetSysPath)+'\'+string(MyKernel))) ;
     end;function CreateKernelFile(SaveFile:String):Boolean;
     var
       hFile:THandle;
       BytesWrite: dword;
     begin
       Result:=False;
       hFile := CreateFile(Pchar(SaveFile),GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ,nil,CREATE_ALWAYS,0,0);
       if hFile = INVALID_HANDLE_VALUE then Exit;
       if WriteFile(hFile,MyKernelBuf,MyKernelSize, BytesWrite, nil) then Result:=True;
       CloseHandle(hFile);
     end;Function  GetModule(ProcessName,ModuleName:Pansichar):longword;
    //This is a function written by Hke.
    //检查进程是否加载DLL,是返回指针,否返回0
     var
       PID:longword;
       hModuleSnap:longword;
       ModuleEntry: TModuleEntry32;
     begin
       Pid:=NameToPID(ProcessName);
       GetDebugPrivs;
       hModuleSnap:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,Pid);
       ModuleEntry.dwSize:=SizeOf(TModuleEntry32);
       result:=0;
       if Module32First(hModuleSnap,ModuleEntry) then
         if  (LstrcmpiA(ModuleEntry.szModule,ModuleName)=0) then
           Result:=ModuleEntry.hModule
         else
           begin
             while  Module32Next(hModuleSnap,ModuleEntry) do
                begin
                  if LstrcmpiA(ModuleEntry.szModule,ModuleName)=0 then
                    begin
                      Result:=ModuleEntry.hModule;
                      break;
                    end;
                end;
           end;
       CloseHandle(hModuleSnap);
     end;procedure InjectKernelModule(ProcessName ,DllName: Pansichar);
    //This is a function written by Hke.
    //利用远程线程讲把Dll注入进程
     var
       tmp:longword;//这个专门来占格式收集垃圾
       Mysize:longword;//放字符串长度
       Parameter:pointer;//放那个参数的指针(位置在目标进程内)
       hThread:longword;
       MyHandle,PID:longword;
       Tkernel:pansichar;//为了取得指针
     begin
       if GetModule(ProcessName , DllName)=0 then  //如果已经注入就不重复了
         begin
           Tkernel:= DllName;
           Pid:=NameToPID(ProcessName);
           GetDebugPrivs;
           Myhandle:=OpenProcess(PROCESS_ALL_ACCESS, False, Pid);
           Mysize:=strlen(MyKernel)+1;
           Parameter:= VirtualAllocEx(Myhandle, nil, Mysize, MEM_COMMIT, PAGE_READWRITE);
           WriteProcessMemory(Myhandle, Parameter, Pointer(Tkernel), MySize, tmp);
           hThread:= CreateRemoteThread(Myhandle,nil,  0, GetProcAddress(GetModuleHandle('KERNEL32.DLL'), 'LoadLibraryA'), Parameter, 0 , tmp);
           if  hThread <> 0 then
             begin
               WaitForSingleObject(hThread, INFINITE); //等待线程运行完
               CloseHandle(hThread);
             end;
           VirtualFreeEx(MyHandle, Parameter, 0, MEM_RELEASE); //把用完的内存释放掉
           CloseHandle(MyHandle);
         end;
     end;procedure UnInjectKernelModule(ProcessName ,DllName: Pansichar);
    //This is a function written by Hke.
    //从目标进程卸载一个DLL
     var
       tmp:longword;//这个专门来占格式收集垃圾
       hThread:longword;
       MyHandle,PID:longword;
       ModuleEntry:longword;
     begin
      Pid:=NameToPID(ProcessName);
      GetDebugPrivs;
      Myhandle:=OpenProcess(PROCESS_ALL_ACCESS, False, Pid);
      ModuleEntry:=GetModule(ProcessName ,DllName);
      if ModuleEntry<>0 then //没加载就不卸载了
        begin
          hThread:= CreateRemoteThread(Myhandle,nil,  0, GetProcAddress(GetModuleHandle('KERNEL32.DLL'), 'FreeLibrary'), pointer(ModuleEntry), 0 , tmp);
          WaitForSingleObject(hThread, INFINITE);   //等待线程运行完
          CloseHandle(hThread);
        end;
      CloseHandle(MyHandle);
     end;
     //屏蔽Ctrl+Alt+Del
    procedure RunFuckCAD;  //导出函数调用后屏蔽Ctrl+Alt+Del
     begin
       CreateKernelFile(string(GetSysPath)+'\'+string(MyKernel));
       //释放DLL到系统目录
       InjectKernelModule(Winlogon ,MyKernel);
       //把释放完DLL注入Winlogon进程
       try
           //设置低级键盘钩子
         hhkLowLevelKybd := SetWindowsHookExW(WH_KEYBOARD_LL,
            LowLevelKeyboardProc, Hinstance, 0);
       finally   end;
     end;//取消屏蔽Ctrl+Alt+Del
    procedure StopFuckCAD;  //导出函数取消屏蔽Ctrl+Alt+Del
     begin
       UnInjectKernelModule(Winlogon ,MyKernel);
       //从Winlogon卸载DLL
       DelKernel;
       //把Dll从系统目录删除   try
        //卸载低级键盘钩子
         if hhkLowLevelKybd <> 0 then
         begin
           UnhookWindowsHookEx(hhkLowLevelKybd);
         end;
       finally   end;
     end;
      

  2.   

    别学啊  这代码是不能用的  哪位有能用的代码 还请指教
    delphi xe2平台上的。
      

  3.   

    JPEXE
    代码是可以 就是没效果 实际3个键并不会被屏蔽
      

  4.   

    = =  代码是有问题 编译不通过 提示一个ansichar错误 但是都是系统单元文件 没办法修改。。 
      

  5.   

    改了 其他地方有报错
    还是不行 
    procedure InjectKernelModule(ProcessName ,DllName: Pwidechar);
    //This is a function written by Hke.
    //利用远程线程讲把Dll注入进程
     var
       tmp:longword;//这个专门来占格式收集垃圾
       Mysize:longword;//放字符串长度
       Parameter:pointer;//放那个参数的指针(位置在目标进程内)
       hThread:longword;
       MyHandle,PID:longword;
       Tkernel:pwidechar;//为了取得指针
     begin
       if GetModule(ProcessName , DllName)=0 then  //如果已经注入就不重复了
         begin
           Tkernel:= DllName;
           Pid:=NameToPID(ProcessName);
           GetDebugPrivs;
           Myhandle:=OpenProcess(PROCESS_ALL_ACCESS, False, Pid);
           Mysize:=strlen(MyKernel)+1;
           Parameter:= VirtualAllocEx(Myhandle, nil, Mysize, MEM_COMMIT, PAGE_READWRITE);
           WriteProcessMemory(Myhandle, Parameter, Pointer(Tkernel), MySize, tmp);
           hThread:= CreateRemoteThread(Myhandle,nil,  0, GetProcAddress(GetModuleHandle('KERNEL32.DLL'), 'LoadLibraryA'), Parameter, 0 , tmp);
           if  hThread <> 0 then
             begin
               WaitForSingleObject(hThread, INFINITE); //等待线程运行完
               CloseHandle(hThread);
             end;
           VirtualFreeEx(MyHandle, Parameter, 0, MEM_RELEASE); //把用完的内存释放掉
           CloseHandle(MyHandle);
         end;
     end;这里 WriteProcessMemory(Myhandle, Parameter, Pointer(Tkernel), MySize, tmp);
    报错 错误内容是:
    [DCC Error] unt_HookCtrlAltDelWin.pas(776): E2033 Types of actual and formal var parameters must be identical
    不知道该怎么改了。