我要做一个在非客户区的按扭控件。注:是控件,不单是绘制一个按扭并响应消息。
现在是继承自TComponent的类,但是要如何响应消息?

解决方案 »

  1.   

    这个需求,建议从TWinControl继承。个人觉得最好是TCustomControl
      

  2.   


    明明说的非客户区,不好意思.
    楼主的意思是不是一个控件,然后在具有客户区的Parent(如Form)上绘制东西并响应?如何是的话,从TGraphicControl开始继承
      

  3.   

    在繼承至TComponent的類...內崁私用以 Windows API 之 AllocateHWnd() 函式建立易隱藏窗口來響應消息...作法如同 VCL 程序架構的全域隱藏窗口 Application......
      

  4.   

    在原文書 Charlie Calvert's Borland C++ Builder 4 Unleashed: The Comprehensive Solution 裏有 LZ 所要的技術資料...不過範例是 C++Builder 的...我手上有一本台灣碁峯出版社所發行的中譯本...書名為 C++ Builder 4 Unleashed 深入淺出...不確定是不是中國大陸地區所發行的 C++ Builder 4  核心內幕中譯本......
      

  5.   

    本进程,就是getwindowDc(handle);和TCanvas来进行绘制的。
      

  6.   

    参考 Buttons.TSpeedButton 应该可以满足你的要求,继承自TGraphicControl
      

  7.   

    第一种:创建没有标题栏应用程序,在客户区让出一部分空间用一幅图片画一个标题栏,让人“误认为”是标题栏。
    第二种:处理应用程序接收到的WM_NCCALCSIZE消息,改变客户区在窗口中的位置,从而得到合适标题栏高度。
    ---------------------------
    我现在选择的是第二种
      

  8.   

    Type
      TFormMessage = class(TComponent)
      private
        fParentForm : TForm;
        fOldProc : TWndMethod;
        procedure MessageProc(var Message: TMessage);
      public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;    procedure SetForm(const Value: TForm);
      end;{ TFormMessage }
    constructor TFormMessage.Create(AOwner: TComponent);
    begin
      inherited;
      while AOwner<>NIL do begin
        if AOwner is TForm then begin
          SetForm(TForm(AOwner));
          Break;
        end;
        AOwner := AOwner.Owner;
      end;
    end;destructor TFormMessage.Destroy;
    begin
      SetForm(NIL);
      inherited;
    end;procedure TFormMessage.SetForm(const Value: TForm);
    begin
      if Value = fParentForm then exit;
      if fParentForm <> NIL then begin
        fParentForm.WindowProc := fOldProc;
        fParentForm := NIL;
        fOldProc := NIL;
      end;
      if Value <> NIL then begin
        fParentForm := Value;
        fOldProc := Value.WindowProc;
        Value.WindowProc := MessageProc;
      end;
    end;procedure TFormMessage.MessageProc(var Message: TMessage);
    var
      bCallDefault : Boolean;
    begin
      bCallDefault := True;
      if Message.Msg = WM_NCCALCSIZE then begin
        //该消息的处理代码
        //bCallDefault := False; //覆盖选项
        fParentForm.Caption := fParentForm.Caption + 'a';
      end;
      if bCallDefault and Assigned(fOldProc) then fOldProc(Message);
    end;
      

  9.   

    楼上的方法是可行,但是有一个问题,是如果有两个类,
    都是通过截获父窗口的WindowProc来响应的话,那最终执行的消息响应代码是类B的,就是后面窗口的类。而类A的应该不会响应到。
      

  10.   

    //bCallDefault := False; //覆盖选项
    如果B中设置了这个,A就得不到消息,类推