以下是我想用自己的窗口过程替换窗体本身的,但在MyCallWindowProc中只有当鼠标在标题栏上按下并抬起时才会激发WM_NCLBUTTONDOWN,苦恼,盼高手解决。const 
  htTitleBtn = htSizeLast + 1;procedure WMNCLButtonDown(var Msg: TWMNCLButtonDown);
begin
  if (Msg.HitTest = htTitleBtn) then
  begin
    SetCapture(FOwner.Handle);
    FLBDown := true;
    InRect := true;
    DrawTitleButton;
  end;
end;procedure WMNCHitTest(var Msg : TWMNCHitTest);
begin
  {Check to see if the mouse was clicked in the area of the button}
  if PtInRect(TitleButton, Point(Msg.XPos - FOwner.Left, Msg.YPos - FOwner.Top)) then
    Msg.Result := htTitleBtn;
end;function MyCallWindowProc(hWnd: HWND;
  Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
  tmpMsg: TMessage;
begin
  Result := CallWindowProc(SWindProc, hWnd, Msg, wParam, lParam);
  tmpMsg.Msg := Msg;
  tmpMsg.WParam := wParam;
  tmpMsg.LParam := lParam;
  case Msg of
    WM_NCLBUTTONDOWN:
    begin
      WMNCLButtonDown(TWMNCLBUTTONDOWN(tmpMsg));
    end;
    WM_NCHITTEST:
    begin
      WMNCHitTest(TWMNCHITTEST(tmpMsg));
    end;
  end;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
  FOwner := Self;
  SWindProc := Pointer(GetWindowLong(Handle, GWL_WNDPROC));
  SetWindowLong(Handle, GWL_WNDPROC, Integer(Addr(MyCallWindowProc)));
end;

解决方案 »

  1.   

    gaoys1979请问什么叫“如果只有点击客户区一次”?
      

  2.   

    直接重载窗体的WndProc就可以了,干嘛要用子类化。
      

  3.   

    "但在MyCallWindowProc中只有当鼠标在标题栏上按下并抬起时才会激发WM_NCLBUTTONDOWN"我希望是按下就激发该消息,而不是抬起才激发。希望BCB FANS指教
      

  4.   

    感谢taxi回复,我并不想直接重载窗体的WndProc,因为我还有别的用途,必须用这种方法实现,您看还有没有高招?
      

  5.   

    我是想做一个标题栏按钮,它只能有Owner就是说它是为哪个窗体工作的,但它不能直接接受Owner的各种消息,如在标题栏上按下左键:(
      

  6.   

    按照msdn的书法:WM_NCLBUTTONDOWN 消息是在鼠标按下时产生的,我试了一下在我的机器是按照这种规律产生的。
    不过我的代码和你的不同的是我先处理WM_NCLBUTTONDOWN 消息然后在传送到旧的过程中执行的。
    你只要把
     Result := CallWindowProc(SWindProc, hWnd, Msg, wParam, lParam);  放在最后就可以了。