弹出式窗口管理单元备忘

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.

你可能感兴趣的:(管理)