The CallWndProc hook procedure can examine the message, but it cannot modify it. 
Hook一下WH_CBT当类型为HCBT_CREATEWND的时候,或者就是hook一下ShowWindow方法

解决方案 »

  1.   

    我是参考了这段代码后修改成VC的代码,再去试试拦截 HCBT_CREATEWNDlibrary ShowHook;{ Important note about DLL memory management: ShareMem must be the
      first unit in your library's USES clause AND your project's (select
      Project-View Source) USES clause if your DLL exports any procedures or
      functions that pass strings as parameters or function results. This
      applies to all strings passed to and from your DLL--even those that
      are nested in records and classes. ShareMem is the interface unit to
      the BORLNDMM.DLL shared memory manager, which must be deployed along
      with your DLL. To avoid using BORLNDMM.DLL, pass string information
      using PChar or ShortString parameters. }uses
      SysUtils,
      Classes,
      Windows,
      Messages;var
      hhook: Windows.HHOOK;
      oldWndProc: Integer;{$R *.res}function WindowProc(hwnd: HWND; msg: UINT; wp: WPARAM; lp: LPARAM): LRESULT; stdcall;
    var
      wndPos: PWindowPos;
    begin
      if msg = WM_WINDOWPOSCHANGING then
      begin
        wndPos := PWindowPos(lp);
        if (wndPos^.flags and SWP_SHOWWINDOW) <> 0 then
        begin
          wndPos^.flags := (wndPos^.flags and (not SWP_SHOWWINDOW));
        end;
      end;  Result := CallWindowProc(TFNWndProc(oldWndProc), hwnd, msg, wp, lp);  if msg = WM_WINDOWPOSCHANGING then
      begin
        SetWindowLong(hwnd, GWL_WNDPROC, Integer(oldWndProc));
      end;
    end;function ShowHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): Integer; stdcall;
    var
      cwp: PCwpStruct;
      wndPos: PWindowPos;
      clsName: array[0..31] of Char;  str: WideString;
    begin
      if (nCode < 0) then //  or (nCode = HC_NOREMOVE)
      begin
        Result := CallNextHookEx(hhook, nCode, wParam, lParam);
        exit;
      end;  OutputDebugString('Hook procedure entered.');
      cwp := PCwpStruct(lParam);
      if cwp^.message <> WM_WINDOWPOSCHANGING then
      begin
        Result := CallNextHookEx(hhook, nCode, wParam, lParam);
        exit;
      end;  OutputDebugString('WM_WINDOWPOSCHANGING captured.');
      wndPos := PWindowPos(cwp^.lParam);
      if (wndPos^.flags and SWP_SHOWWINDOW) = 0 then
      begin
        Result := CallNextHookEx(hhook, nCode, wParam, lParam);
        exit;
      end;  OutputDebugString('SWP_SHOWWINDOW found.');  // 其他代码及记录日志 ......
      if (wndPos^.hwnd <> 0) and IsWindow(wndPos^.hwnd) then
      begin
        OutputDebugString('Window handle is valid.');    if GetClassName(wndPos^.hwnd, clsName, 32) <> 0 then
        begin
          OutputDebugString('Window class name is: ');
          OutputDebugString(clsName);      if CompareText(clsName, 'Notepad') = 0 then
          begin
    {$if false}
            MessageBox(0, 'Notepad will show.', nil, MB_OK);        str := Format('0x%X', [wndPos^.flags]);
            MessageBox(0, PWideChar(str), nil, MB_OK);        wndPos^.flags := (wndPos^.flags and (not SWP_SHOWWINDOW));        str := Format('0x%X', [wndPos^.flags]);
            MessageBox(0, PWideChar(str), nil, MB_OK);        Result := 0;
            exit;
    {$ifend}
            oldWndProc := SetWindowLong(wndPos^.hwnd, GWL_WNDPROC, Integer(@WindowProc));
          end;
        end;
      end;
      Result := CallNextHookEx(hhook, nCode, wParam, lParam);
    end;procedure Hook(bEnable: Boolean); stdcall; export;
    begin
      if bEnable then
      begin
        if hhook = 0 then
        begin
          hhook := SetWindowsHookEx(WH_CALLWNDPROC, ShowHookProc, HInstance, 0);
        end;
      end
      else
      begin
        if hhook <> 0 then
        begin
          UnhookWindowsHookEx(hhook);
          hhook := 0;
        end;
      end;
    end;exports
      Hook;begin
      hhook := 0;
      oldWndProc := 0;
    end.
      

  2.   

    一旦  窗口进行了create,然后就接着会执行了showWIndow(1),所以你想效果好,就得
    窗口初始化完毕,也就是他执行了UpdateWindow SHowWindow 之前隐藏了,这才是根本的方法。
      

  3.   

    即将显示的窗口要隐藏好像一定会闪一下的]
    先不说钩子不钩子
    直接自己写的窗口想实现类似的功能一般是在OnNcPaint里
    这样窗口不会闪
    但是焦点还是会闪