Vcl封装Win32的标准控件后,实际的窗口处理函数就是WndProc了,可为什么如下处理后,还会执行
Win32的标准控件的原操作呢?3Q......
protected        ......
      procedure WndProc(var Message: TMessage); override;
        ......procedure TPathComboBox.WndProc(var Message: TMessage);
begin
     if  TWMCommand(Message).NotifyCode = CBN_DROPDOWN  then
     begin
       AdjustDropDown;
       Exit;//应该中途退出了,为什么如下处理后,还会执行Win32的标准控件的原操作?                 
end;
     inherited WndProc(Message);
end;

解决方案 »

  1.   

    cnhgj(戏子) (极度(╭∩╮(︶︿︶)╭∩╮)B4不结贴者) :
    拦截到这个消息了,应该不执行什么了,可还执行Win32的标准控件的原操作,这儿是还出现下拉框,为什么?这个是组合框控件
      

  2.   

    曾经告诉过你,你不要指望再VCL的那个控件上能开发出个下拉是树的控件,要不就是实现起来非常麻烦.
    你收到的这个消息是Win32控件发给你的,不是你发给控件的,这个消息只是通知你,下拉列表要开始下拉了,不管你处理不处理,下拉是肯定了.
    本人拙见,高手指正.建议看看第三方控件的源码,看看别人是怎么实现的.
    如果可以从VCL的那个上继承的话,我想,第三方控件的下拉都从那里继承李,别的控件写的好复杂啊.
      

  3.   

    xthmpro_cn(安徽农民*在外打工):TComboBox subclass 了Windows的标准 "COMBOBOX",成了它的父亲,并接收它发来的通知消息,
    其实放一个TComboBox控件到Form上,实际上是放了两个窗口,我这样理解对吗?
    但这两个窗口的Handle是否同一个值呢?请指点附上一个将Windows窗口类封装成Delphi控件的实例:
    -------------------------------
    为Delphi/C++Builder增添IP控件西安交通大学 刘明华  在进行网络设置时,我们常常碰到需要填写IP地址的情况,为此Windows引入了一个专门用来接受IP地址输入的控件(如图所示)。Windows IP地址编辑控件(IP Address edit control)是随着微软的Internet Explorer 4.0的推出而引入Windows操作系统的(Windows 98 和Windows 2000中都已经包含了此控件)。但是令人遗憾的是在Inprise公司最新版本的 Delphi 5和C++ Builder 5中,Borland可视化控件库(Visual Component Library)中居然没有提供IP地址编辑控件。  为了让Delphi和C++ Builder开发人员更方便地使用IP 控件,本文介绍如何将它包装成一个可以在Delphi和C++ Builder的IDE环境中使用的可视化Delphi控件。同时本文也为读者学习Delphi控件编写提供了一个比较好的示例;它涉及了Delphi控件编写的以下方面的知识:将Windows窗口类封装成Delphi控件,将 Windows消息映射成事件属性,多个属性共享read和write方法,以及属性编辑器(Property Editor)的构造。    一、IP控件的属性、方法及事件
      本文将为Delphi/C++ Builder的IP控件实现下面的属性、方法和事件。它们的简单介绍如下: 
      IP属性:IP控件中的IP地址值(32位整数LongWord)。为了获取IP控件的IP值,我们只需要读取此属性即可;通过对IP属性赋值,我们就能够改变IP控件的内容。   Field0..Field3属性:Field0到Field3分别为IP控件的4个部分的值。这四个属性也是为了读取和改变IP控件的IP值而设置的。   Field0Range..Field3Range 属性:Field0Range到 Field3Range限制IP控件各部分的取值的范围。   Blank属性:判断IP控件的IP串是否为空,此属性为只读属性。   About属性:在Object Inspector中点击它可以显示控件的版本信息,添加此属性是为了提供一个编写属性编辑器的简单例子。   以下属性继承自TWinControl类:Font、TabOrder、 TabStop、 ParentShowHint、ShowHint、Hint及Visible。   TIPEdit的事件属性有:OnFieldChange、OnChange、 OnEnter以及OnExit。   Clear方法:清空IP控件中的IP串。   SetFieldFocus方法:设置IP控件的输入焦点。   二、IP控件的实现
    //文件名:IPEdit.PAS
        {~~~~~~~~~~~~~~~~~~~~~~~}
        // IP address edit control for Borland Delphi 5
        // Implemented by Simon Liu ([email protected])
        {~~~~~~~~~~~~~~~~~~~~~~~}
        unit IPEdit;
        interface
        uses Windows, Messages, SysUtils, Classes,
         Forms, Controls, ComCtrls, CommCtrl, DsgnIntf;    type
          TFieldRange = record
            LowRange: Byte;
            HighRange: Byte;
          end;      TFieldChangeEvent = procedure(Sender: TObject; 
            OldField, Value: Byte) of Object;      //定义TAboutProperty属性编辑器
          TAboutProperty = class(TPropertyEditor)
          public
            procedure Edit; override;
            function GetAttributes: TPropertyAttributes;override;
            function GetValue: string; override;
          end;      TIPEdit = class(TWinControl)
          private
            fAbout:TAboutProperty;
            FIP: LongWord;
            FFields:array[0..3] of Byte;
            FFieldRanges: array [0..3] of TFieldRange;
            FCreating: Boolean;
            FOnChange: TNotifyEvent;
            FOnEnter: TNotifyEvent;
            FOnExit: TNotifyEvent;
            FOnFieldChange: TFieldChangeEvent;
            procedure SetIP(Value: LongWord);
            function GetIP: LongWord;
            function  GetField(Index:Integer):Byte;
            procedure SetField(Index:Integer; B:Byte);
            function GetFieldRange(Field: Integer): 
            TFieldRange;
            procedure SetFieldRange(Field:integer; Value: 
              TFieldRange);
            procedure SetIPAddress;
            function GetBlank: Boolean;
            procedure WMNotifyFormat(var Message: TMessage);
             message WM_NOTIFYFORMAT;
            //处理IP控件的通知消息IPN_FIELDCHANGED
            procedure CNNotify(var Message: TWMNotify);
              message CN_NOTIFY;
            procedure CNCommand(var Message: TWMCommand);
              message CN_COMMAND;
            procedure WMSetFont(var Message: TWMSetFont);
              message WM_SETFONT;
          protected
         procedure CreateParams(var Params: TCreateParams); override;
            procedure CreateWnd; override;
            procedure DestroyWnd; override;
      public
         constructor Create(AOwner: TComponent); override;
            destructor Destroy; override;
            //清除IP控件中的IP串
            procedure Clear;
           //设置IP控件的输入焦点(field的有效取值为0..3)
          procedure SetFieldFocus(Field:Byte);
          published
            //判断IP控件的IP串是否为空
            property Blank: Boolean read GetBlank;
            //Field0到Field3分别为IP控件的4个部分的值
            property Field0: Byte index 0 read 
                GetField write SetField;
            property Field1: Byte index 1 read 
                GetField write SetField;
            property Field2: Byte index 2 read 
                GetField write SetField;
            property Field3: Byte index 3 read 
                 GetField write SetField;
           //Field0Range到Field3Range
                限制IP控件各部分的取值的范围
            property Field0Range: TFieldRange index 0 read 
               GetFieldRange write SetFieldRange;
            property Field1Range: TFieldRange index 1 read 
               GetFieldRange write SetFieldRange;
            property Field2Range: TFieldRange index 2 read 
               GetFieldRange write SetFieldRange;
            property Field3Range: TFieldRange index 3 read 
               GetFieldRange write SetFieldRange;
            //IP地址值(32位整数LongWord)
            property IP: LongWord read GetIP write SetIP;
            //The About box
            property About:TAboutProperty read fAbout;
            //事件属性
            property OnChange: TNotifyEvent read FOnChange write
              FOnChange;
            property OnEnter: TNotifyEvent read FOnEnter write 
              FOnEnter;
            property OnExit: TNotifyEvent read FOnExit write
               FOnExit;
            property OnFieldChange: TFieldChangeEvent read
               FOnFieldChange 
            write FOnFieldChange;
           //以下属性继承自TWinControl控件
            property Enabled;
            property TabOrder;
            property TabStop;
            property ParentShowHint;
            property ShowHint;
            property Hint;
            property Visible;
          end;    procedure Register;    implementation    {~~~~~TAboutProperty~~~~~~~~~~~}
        procedure TAboutProperty.Edit;
        begin
        Application.MessageBox(
          ‘TIPEdit for Delphi 5'#13
          +‘(C) 2000 by Simon Liu'#13
          +‘Email:[email protected]',
          ‘About TIPEdit',MB_ICONINFORMATION);
        end;    function TAboutProperty.GetAttributes: TPropertyAttributes;
        begin
          Result := [paDialog, paReadOnly];
        end;    function TAboutProperty.GetValue: string;
        begin
          Result := ‘(Simon)';
        end;    {~TIPEdit~~~~~~~~~~~~~~~~~~}
        constructor TIPEdit.Create(AOwner: TComponent);
        var
          i: integer;
        begin
          //初始化ICC_INTERNET_CLASSES类控件
         CheckCommonControl(ICC_INTERNET_CLASSES);
          inherited Create(AOwner);
          for i:= 0 to 3 do
          begin
            FFieldRanges[i].LowRange:= 0;
            FFieldRanges[i].HighRange:= 255;
            FFields[i]:=0;
          end;
          FIP:=0;
          Height:= 25;
          Width:= 152;
          TabSTop:= True;
        end;    procedure TIPEdit.DestroyWnd;
        begin
          inherited DestroyWnd
        end;    destructor TIPEdit.Destroy;
        begin
          inherited Destroy;
        end;
      

  4.   

    procedure TIPEdit.CreateParams(var Params: 
          TCreateParams);
        begin
          inherited CreateParams(Params);
          CreateSubClass(Params, WC_IPADDRESS);
          with Params do
          begin
          end;
        end;    procedure TIPEdit.CreateWnd;
        begin
          FCreating := True;
          try
            inherited CreateWnd;
            SetIPAddress;
          finally
            FCreating := False;
          end;
        end;    function TIPEdit.GetBlank: Boolean;
        begin
     Result:= Boolean(SendMessage(Handle, IPM_ISBLANK, 0, 0));
        end;    procedure TIPEdit.Clear;
        begin
       SendMessage(Handle, IPM_CLEARADDRESS, 0, 0);
        end;    procedure TIPEdit.SetFieldFocus(Field:Byte);
        begin
          SendMessage(Handle, IPM_SETFOCUS, Field, 0);
        end;    function TIPEdit.GetFieldRange(Field: Integer): TFieldRange;
        begin
          Result:= FFieldRanges[Field];
        end;procedure TIPEdit.SetFieldRange(Field: Integer; 
       Value: TFieldRange);
        begin
          if Value.LowRange > Value.HighRange then exit;
          if (FFieldRanges[Field].LowRange <> Value.LowRange) or
            (FFieldRanges[Field].HighRange <> Value.HighRange) then
          begin
            FFieldRanges[Field]:= Value;
            SendMessage(Handle, IPM_SETRANGE, Field,
      MakeIPRange(Value.LowRange, Value.HighRange));
          end;
        end;    function TIPEdit.GetField(Index: Integer): Byte;
        begin
          if (Index>=0)and(Index<=3) then Result:=FFields[Index]
          else Result:=0;
        end;    procedure TIPEdit.SetField(Index:Integer; B:Byte);
        begin
          if (FFields[Index] <> B)then
          begin
            FFields[Index]:=B;
            SetIPAddress;
          end;
        end;    procedure TIPEdit.SetIPAddress;
        var
          i:LongWord;
        begin
      i:=MAKEIPADDRESS(FFields[0], FFields[1], FFields[2], 
           FFields[3]);
          SendMessage(Handle, IPM_SETADDRESS, 0, i);
          FIP:=i;
        end;    procedure TIPEdit.SetIP(Value: LongWord);
        begin
          if (FIP <> Value) then
          begin
            FFields[0]:= First_IPAddress(Value);
            FFields[1]:= Second_IPAddress(Value);
            FFields[2]:= Third_IPAddress(Value);
            FFields[3]:= Fourth_IPAddress(Value);
            SetIPAddress;
          end;
        end;    function TIPEdit.GetIP: LongWord;
        begin
        SendMessage(Handle, IPM_GETADDRESS, 0,Integer(@Result));
        end;   procedure TIPEdit.WMSetFont(var Message: TWMSetFont);
        begin
        //不可以调用父控件的此方法
        //否则,控件不能正常工作
        end;procedure TIPEdit.WMNotifyFormat(var Message:
          TMessage);
        begin
          with Message do
        Result := DefWindowProc(Handle, Msg, WParam, LParam);
        end;    procedure TIPEdit.CNNotify(var Message: TWMNotify);
        var
          pNM: PNMIPAddress;
        begin
          with (Message.NMHdr)^ do
          begin
            case Code of
            IPN_FIELDCHANGED:
            begin
            pNM:=PNMIPADDRESS(Message.NMHdr);
            if (pNM^.iField>=0)and(pNM^.iField<=3) then
            FFields[pNM^.iField]:=pNM^.iValue;
            if Assigned(FOnFieldChange) then
           FOnFieldChange(self, pNM^.iField, pNM^.iValue);
            end;
            end;
          end;
        end;  procedure TIPEdit.CNCommand(var Message: TWMCommand);
        begin
          case Message.NotifyCode of
            EN_CHANGE:
            begin
             if not FCreating then
             if Assigned(FOnChange) then FOnChange(self);
            end;
            EN_KILLFOCUS: if Assigned(FOnExit) then FOnExit(self);
            EN_SETFOCUS: if Assigned(FOnEnter) then FOnEnter(self);
          end;
        end;    //注册TIPEdit控件以及TAboutProperty属性编辑器
        procedure Register;
        begin
          RegisterComponents(‘Simon', [TIPEdit]);
          RegisterPropertyEditor(typeInfo(TAboutProperty),
            TIPEdit, ‘ABOUT', TAboutProperty);
        end;
        end. 
      

  5.   

    你把帖子结了,其实文中提到的IP控件是对一个控件的功能进行限制,你要求的是对控件的聚合.TComboBox 是一个标准的Windows控件,其中的按钮和下拉列表,都是由系统负责画出,Delphi的代码不负责做任何事情,只是,window控件在进行动作前会以消息的形式通知你.可以在MSDN中查
    Combo Boxes项,特别注意:COMBOBOXINFO项目
    如果TComboBox 是一个Delhpi聚合的控件,那么你从它继承是可以的.
    如果你需要下拉一个树,你可能只有自画下拉列表.
    拙见!