Delphi XE2 - 实现无敌关机键


本文整理自网络,侵删。

 

当从开始菜单选择关机,很多时候会得到一些叽叽歪歪的提示,让你在是和否之间做抉择,其实你只想关机,其他什么你并不关心。

我们可以做一个热键程序,当你按下某个键或者组合键,然后立即强制关机,就象《生化危机》里的自毁键,一旦按下就不再有什么能够阻止。

这个程序里基本上有两个要点,一是注册热键,二是关机权限。

关于热键,万一写有“注册系统级热键”文章可以参考,原文链接如下:
http://www.cnblogs.com/del/archive/2008/04/15/976834.html

程序源代码(Delphi XE2)如下:

 

program Project1; { 运行本程序后随时按下WIN+Q组合键即可强制关机 }

uses Winapi.Windows;

procedure DoEvents; // 等同Application.ProcessMessages
var
  Msg: TMsg;
begin
  while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
  begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;
end;

procedure AdjustProcessPrivilege(const ProcessHandle: Cardinal; // 提升指定进程到某个权限
  const PrivilegeName: string; const Enable: Boolean);
var
  H: THandle;
  TP: TTokenPrivileges;
begin
  if OpenProcessToken(ProcessHandle, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, H) then
  try
    if LookupPrivilegeValue(nil, PChar(PrivilegeName), TP.Privileges[0].Luid) then
    begin
      TP.PrivilegeCount := 1;
      if Enable then
        TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
      else
        TP.Privileges[0].Attributes := 0;
      AdjustTokenPrivileges(H, False, TP, SizeOf(TP), nil, PCardinal(nil)^);
    end;
  finally
    CloseHandle(H);
  end;
end;

procedure ForceShutDown; // 强制关机
begin
  AdjustProcessPrivilege(GetCurrentProcess, 'SeShutdownPrivilege', True);  // 获得关机权限
  ExitWindowsEx(EWX_FORCE or EWX_POWEROFF, 0);                             // 关机
  AdjustProcessPrivilege(GetCurrentProcess, 'SeShutdownPrivilege', False); // 取消关机权限
end;

function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  Result := 0;
  if (LOBYTE(lParam) = MOD_WIN) and (LOBYTE(HiWord(lParam)) = Ord('Q')) then
  begin
    ForceShutDown;                       // 强制关机
    SetWindowLong(hWnd, GWL_WNDPROC, 0); // 还原窗口函数
  end;
end;

procedure Main;
const
  CN = 'STATIC'; // 窗口类名
  WN = 'HOTKEY'; // 窗口名称
var
  H: Cardinal;
  WL: NativeInt;
  ID: Word;
begin
  H  := CreateWindowEx(0, CN, WN, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, nil); // 创建message-only窗口
  WL := SetWindowLong(H, GWL_WNDPROC, NativeInt(@WndProc));                // 设置新的窗口函数
  ID := GlobalAddAtom('WIN+Q');                                            // 获得原子ID
  RegisterHotKey(H, ID, MOD_WIN, Ord('Q'));                                // 注册热键WIN+Q

  repeat
    DoEvents;
    Sleep(1);
  until GetWindowLong(H, GWL_WNDPROC) = WL; // 若已还原窗口函数则退出循环

  UnregisterHotKey(H, ID); // 注销热键
  GlobalDeleteAtom(ID);    // 删除原子ID
  DestroyWindow(H);        // 销毁message-only窗口
end;

begin
  Main;
end.

 

相关阅读 >>

Delphi 简单得多线程应用

Delphi从内存流加载图片

Delphi idhttp上传图给asp完美解决

Delphi 官方 processmessages 用法代码例子

Delphi 写日志函数

Delphi版进程间的相互调用与参数传递

Delphi md5加密base64加解密

Delphi memo1 统计行 列

Delphi获取宽带ip

Delphi 提高unigui开发效率的两个方法

更多相关阅读请进入《Delphi》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...

    正在狠努力加载,请稍候...