• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Delphi中用MessageBox()API函数做倒计时对话框(使用Hook安装CBTHookCallback,计时器 ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

API有隐藏的MessageBoxTimeOut函数可以做计时对话框,缺点是不能显示还剩下多少秒关闭。

  1. const
  2.   IDTIMEDOUT = 32000;
  3. function MessageBoxTimeOut(hWnd: HWND;
  4.   lpText: PChar; lpCaption: PChar; uType: UINT; wLanguageId: WORD;
  5.   dwMilliseconds: DWORD): Integer; stdcall; external
  6.   user32 name 'MessageBoxTimeoutA';

其实只要获得对话框的句柄就可以用时间器修改窗体或者按钮标题实现倒计时提示。
窗体激活后可以通过Hook CBT捕获HCBT_ACTIVATE
参考如下方法:

  1. var
  2.   hookHandle: THandle;
  3.   dialogHandle: THandle;
  4.   second: Integer;
  5. function CBTHookCallback(nCode: Integer;
  6.   wParam: WPARAM;
  7.   lParam: LPARAM
  8.   ): Integer; stdcall;
  9. begin
  10.   case nCode of
  11.     HCBT_ACTIVATE:
  12.       begin
  13.         dialogHandle := wParam;
  14.         second := 5;
  15.         UnhookWindowsHookEx(hookHandle);
  16.       end;
  17.   end;
  18.   Result := CallNextHookEx(hookHandle, nCode, wParam, lParam);
  19. end;
  20. procedure TForm1.Button1Click(Sender: TObject);
  21. begin
  22.   Timer1.Enabled := True;
  23.   hookHandle := SetWindowsHookEx(WH_CBT, CBTHookCallback, HInstance, 0);
  24.   MessageBox(Handle, 'Zswang 路过', '倒计时(5)', 0);
  25. end;
  26. procedure TForm1.Timer1Timer(Sender: TObject);
  27. begin
  28.   Dec(second);
  29.   if second <= then
  30.   begin
  31.     PostMessage(dialogHandle, WM_CLOSE, 0, 0);
  32.     TTimer(Sender).Enabled := False;
  33.   end;
  34.   SetWindowText(dialogHandle, PChar(Format('倒计时(%d)', [second])));
  35. end;

相对来说,C#中写得更麻烦一些,因为要自己什么API,如下是修改按钮标题的例子:

    1. public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
    2. [DllImport("user32.dll")]
    3. public static extern IntPtr SetWindowsHookEx(int hookid,
    4.     HookProc pfnhook, IntPtr hinst, int threadid);
    5. [DllImport("user32.dll")]
    6. public static extern IntPtr CallNextHookEx(IntPtr hhook,
    7.     int code, IntPtr wparam, IntPtr lparam);
    8. [DllImport("kernel32.dll")]
    9. public static extern IntPtr GetModuleHandle(string modName);
    10. [DllImport("user32.dll")]
    11. public static extern bool UnhookWindowsHookEx(IntPtr hhook);
    12. public const int WH_CBT = 5;
    13. public const int HCBT_ACTIVATE = 5;
    14. IntPtr hookHandle = IntPtr.Zero;
    15. public delegate bool WNDENUMPROC(IntPtr hwnd, int lParam);
    16. [DllImport("user32.dll")]
    17. public static extern int EnumChildWindows(IntPtr hWndParent,
    18.     WNDENUMPROC lpEnumFunc, int lParam);
    19. [DllImport("user32.dll")]
    20. public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName,
    21.     int nMaxCount);
    22. [DllImport("user32.dll")]
    23. public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString,
    24.     int nMaxCount);
    25. [DllImport("user32.dll")]
    26. public static extern void SetWindowText(IntPtr hwnd, string lpString);
    27. public bool EnumChild(IntPtr hwnd, int lParam)
    28. {
    29.     StringBuilder vBuffer = new StringBuilder(256);
    30.     GetClassName(hwnd, vBuffer, vBuffer.Capacity);
    31.     if (vBuffer.ToString().ToLower() == "button") // 按钮
    32.     {
    33.         StringBuilder vText = new StringBuilder(256);
    34.         GetWindowText(hwnd, vText, vText.Capacity);
    35.         if (vText.ToString().ToLower().IndexOf("&a") >= 0) // 终止
    36.             SetWindowText(hwnd, "停不要动");
    37.         if (vText.ToString().ToLower().IndexOf("&r") >= 0) // 重试
    38.             SetWindowText(hwnd, "再来一次");
    39.         if (vText.ToString().ToLower().IndexOf("&i") >= 0) // 忽略
    40.             SetWindowText(hwnd, "就这样吧");
    41.     }
    42.     return true;
    43. }
    44. private IntPtr CBTHookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    45. {
    46.     switch (nCode)
    47.     {
    48.         case HCBT_ACTIVATE:
    49.             EnumChildWindows(wParam, new WNDENUMPROC(EnumChild), 0);
    50.             UnhookWindowsHookEx(hookHandle);
    51.             break;
    52.     }
    53.     return CallNextHookEx(hookHandle, nCode, wParam, lParam);
    54. }
    55. private void button1_Click(object sender, EventArgs e)
    56. {
    57.     hookHandle = SetWindowsHookEx(WH_CBT, new HookProc(CBTHookCallback),
    58.         GetModuleHandle(null), 0);
    59.     MessageBox.Show("Zswang 路过", "提示", MessageBoxButtons.AbortRetryIgnore);
    60. }

 

http://blog.csdn.net/zswang/article/details/3081063


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
(转)Matlab深度学习工具试玩手册一:基本操作与迁移学习发布时间:2022-07-18
下一篇:
MATLAB实现PCA算法发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap