惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Archives - TechRepublic
Security Archives - TechRepublic
罗磊的独立博客
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
Apple Machine Learning Research
Apple Machine Learning Research
The Register - Security
The Register - Security
J
Java Code Geeks
V2EX - 技术
V2EX - 技术
Vercel News
Vercel News
N
News and Events Feed by Topic
腾讯CDC
P
Proofpoint News Feed
N
News | PayPal Newsroom
www.infosecurity-magazine.com
www.infosecurity-magazine.com
爱范儿
爱范儿
O
OpenAI News
酷 壳 – CoolShell
酷 壳 – CoolShell
月光博客
月光博客
Martin Fowler
Martin Fowler
Engineering at Meta
Engineering at Meta
D
Docker
Y
Y Combinator Blog
博客园 - 聂微东
G
Google Developers Blog
S
Security @ Cisco Blogs
Simon Willison's Weblog
Simon Willison's Weblog
S
Schneier on Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
S
SegmentFault 最新的问题
云风的 BLOG
云风的 BLOG
阮一峰的网络日志
阮一峰的网络日志
C
CXSECURITY Database RSS Feed - CXSecurity.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
CERT Recently Published Vulnerability Notes
I
Intezer
G
GRAHAM CLULEY
有赞技术团队
有赞技术团队
Attack and Defense Labs
Attack and Defense Labs
V
Visual Studio Blog
博客园 - Franky
博客园 - 三生石上(FineUI控件)
W
WeLiveSecurity
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Hugging Face - Blog
Hugging Face - Blog
Scott Helme
Scott Helme
T
Troy Hunt's Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
L
LINUX DO - 最新话题
C
Cybersecurity and Infrastructure Security Agency CISA

博客园 - Enli

IOS 命令行安装备忘 IOS开发备忘 MAC 编制计划任务 Wininet请求包装类简稿 自备工具库 多屏开发的备忘 界面方面的备忘 rc资源文件的中英文应用备忘 Wininet下载类初稿 Dephi调用C#编写的WebService的一些问题与解决 (转) 关于Window的快捷方式,图标缓存的清理 Delphi 备忘五 http断点续传的单元 Delphi 代码优化(转) [转载]Delphi的四舍五入函数 同名派生的应用(转) 关于delphi的程序在英文操作系统下乱码问题 - Enli - 博客园 TWebBrowser备忘 组件开发中的技巧(转)
弹出式窗口管理单元备忘
Enli · 2012-06-01 · via 博客园 - Enli

unit uWnTrackPopupWnd;

interface

uses Forms, Windows, Messages;

procedure TrackPopupWnd(const AForm: TForm; X, Y: Integer);
//function MouseWndProc(ACode: Integer; AWParam: WPARAM; ALParam: LPARAM): LRESULT;stdcall;
function CallWndProc(ACode: Integer; AWParam: WPARAM; ALParam: LPARAM): LRESULT;stdcall;
function GetMsgProc(ACode: Integer; AWParam: WPARAM; ALParam: LPARAM): LRESULT;stdcall;

implementation

uses
  IdGlobal;

const
  MouseMessages: array[0..5of Cardinal = (
    WM_LBUTTONDOWN, WM_RBUTTONDOWN, WM_MBUTTONDOWN, WM_NCLBUTTONDOWN, WM_NCRBUTTONDOWN, WM_NCMBUTTONDOWN
  );

var
  g_TrackForm: TForm;
  g_hkCall, {g_hkMouse,} g_hkGetMsg: HHOOK;

function IsMouseMessage(AMsg: Cardinal): Boolean;
var
  i: Integer;
begin
  Result := False;
  for i := 0 to High(MouseMessages) do
  begin
    if MouseMessages[i] = AMsg then
    begin
      Result := True;
      Break;
    end;
  end;
end;

procedure AttachHook;
begin
//  g_hkMouse := SetWindowsHookEx(WH_MOUSE, MouseWndProc, 0, GetCurrentThreadId);
  if g_hkCall = 0 then
  begin
    g_hkCall := SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, 0, GetCurrentThreadId);
    g_hkGetMsg := SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, 0, GetCurrentThreadId);
  end;
end;

procedure DetachHook;
begin
//  UnhookWindowsHookEx(g_hkMouse);
  if g_hkCall <> 0 then
  begin
    UnhookWindowsHookEx(g_hkCall);
    UnhookWindowsHookEx(g_hkGetMsg);
    g_hkCall := 0;
    g_hkGetMsg := 0;
  end;
end;

procedure TrackPopupWnd(const AForm: TForm; X, Y: Integer);
begin
  if (g_TrackForm <> niland (g_TrackForm <> AForm) then
  begin
    g_TrackForm.Visible := False;
  end;

  g_TrackForm := AForm;
  g_TrackForm.Left := X;
  g_TrackForm.Top := Y;
  if not g_TrackForm.Visible then
  begin
    g_TrackForm.Visible := True;
  end;
  g_TrackForm.Left := X;
  g_TrackForm.Top := Y;

  AttachHook;
end;

//function MouseWndProc(ACode: Integer; AWParam: WPARAM; ALParam: LPARAM): LRESULT;stdcall;
//
//var
//  LNeedDetach: Boolean;
//begin
//  if g_TrackForm = nil then
//  begin
//    Result := CallNextHookEx(g_hkMouse, ACode, AWParam, ALParam);
//    Exit;
//  end;
//
//  LNeedDetach := IsMouseMessage(AWParam);
//  LNeedDetach := False;
//  if (ACode >= 0then
//  begin
//    if (g_TrackForm <> niland IsMouseMessage(AWParam) then
//    begin
//      g_TrackForm.Visible := False;
//    end;
//  end;
//  Result := CallNextHookEx(g_hkMouse, ACode, AWParam, ALParam);
//
//  if LNeedDetach then
//  begin
//    DetachHook;
//  end;
//end;

function GetMsgProc(ACode: Integer; AWParam: WPARAM; ALParam: LPARAM): LRESULT;stdcall;
var
  LData: PMsg;
  LNeedDetach: Boolean;
  LHandled: Boolean;
//  LRect: TRect;
begin
  if g_TrackForm = nil then
  begin
    Result := CallNextHookEx(g_hkGetMsg, ACode, AWParam, ALParam);
    Exit;
  end;

  LNeedDetach := False;
  LHandled := False;
  if (ACode >= 0and (AWParam = PM_REMOVE) then
  begin
    if g_TrackForm <> nil then
    begin
      LData := PMsg(ALParam);
      if LData.message = WM_KEYDOWN then
      begin
        if LData.wParam = VK_ESCAPE then
        begin
          g_TrackForm.Visible := False;
          LNeedDetach := True;
          LHandled := True;
        end
        else if LData.wParam in [VK_UP, VK_DOWN, VK_RETURN] then
        begin
          if SendMessage(g_TrackForm.Handle, LData.message, LData.wParam, LData.lParam) = 0 then
          begin
            LHandled := True;
          end;
        end;
      end
      else if IsMouseMessage(LData.messagethen
      begin
        g_TrackForm.Visible := False;
        LNeedDetach := True;
      end;

      if LHandled then
      begin
        LData.message := WM_NULL;
      end;

    end;
  end;

  Result := CallNextHookEx(g_hkGetMsg, ACode, AWParam, ALParam);
  if LNeedDetach  then
  begin
    DetachHook;
  end;
end;

function CallWndProc(ACode: Integer; AWParam: WPARAM; ALParam: LPARAM): LRESULT;stdcall;
var
  LData: PCWPStruct;
  LNeedDetach: Boolean;
begin
  if g_TrackForm = nil then
  begin
    Result := CallNextHookEx(g_hkCall, ACode, AWParam, ALParam);
    Exit;
  end;

  LNeedDetach := False;
  if ACode >= 0 then
  begin
    LData := PCWPStruct(ALParam);
    //APP激活状态取消
    if (LData.message = WM_ACTIVATEAPP) and (LData.wParam = 0then
    begin
      g_TrackForm.Visible := False;
      LNeedDetach := True;
    end
    //外部程序请求取消隐藏
    else if (LData.message = WM_SHOWWINDOW) and (LData.hwnd = g_TrackForm.Handle) and (LData.wParam = 0then
    begin
      g_TrackForm := nil;
      LNeedDetach := True;
    end
  end;

  Result := CallNextHookEx(g_hkCall, ACode, AWParam, ALParam);
  if LNeedDetach then
  begin
    DetachHook;
  end;
end;

//initialization
//  g_hkMouse := SetWindowsHookEx(WH_MOUSE, MouseWndProc, 0, GetCurrentThreadId);
//  g_hkCall := SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, 0, GetCurrentThreadId);
//  g_hkMsg := SetWindowsHookEx(WH_GETMESSAGE, GetMessageWndProc, 0, GetCurrentThreadId);

end.