我在使用TComboBox的时候发现一个很奇怪的bug,示例:
拖放一个TComboBox放到窗体上,将AutoComplete设为False,将Text清空,再将Items里面的值设为:
123
456运行程序,在组合框里输入1,然后点击下拉按钮,这个时候输入框的Text竟然会自动变为123,而且没有触发OnChange事件;如果再随便点其他位置,下拉框会Close Up,并不会触发OnSelect事件,但Text的值保留下来了。(如果输入5就不会)
我跟踪了一下代码,是程序调用AdjustDropDown之后值发生了改变。还请高手指点一二。

解决方案 »

  1.   

    TcomboBox 继承于 TCustomComboBox 类
    property AutoComplete: Boolean read FAutoComplete write FAutoComplete default True;
    也就是当Tcombox 文本框输入字符的时候 (KeyPress)时 就调用了
    TCustomComboBox.KeyPress(var Key: Char); 方法  因为在TcomboBox  没有重载此方法
    可以自己去单元里面看看方法
    你把AutoComplete设为False  里面
    inherited KeyPress(Key);
    if not AutoComplete then exit;//你将AutoComplete设为False 就不执行下面的代码所以输入'1'时 还是'1'
    if Style in [csDropDown, csSimple] then
    FFilter := Text如果将AutoComplete设为True的话
     if HasSelectedText(StartPos, EndPos) then  
          SaveText := Copy(FFilter, 1, StartPos) + Key
        else
          SaveText := FFilter + Key;
     {function HasSelectedText(var StartPos, EndPos: DWORD): Boolean;
      begin
        SendMessage(Handle, CB_GETEDITSEL, Integer(@StartPos), Integer(@EndPos));
        Result := EndPos > StartPos;
      end;    //如果你输入的字符在item(Tstring)里面存在 如1 或者12  都在123 里面存在就赋值SAVATEXT成123
       ....
            if SelectItem(SaveText) then   
            Key := #0
    你可以自己去看看 TCustomComboBox 类的KeyPress方法;
     
      

  2.   

    procedure TCustomCombo.AdjustDropDown;
    var
      Count: Integer;
    begin
      Count := ItemCount; 
      if Count > DropDownCount then Count := DropDownCount
      if Count < 1 then Count := 1;//如果item没有赋值 则让下拉框 显示一行
      FDroppingDown := True;
      try
          SetWindowPos(FDropHandle, 0, 0, 0, Width, ItemHeight * Count +
          Height + 2, SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOREDRAW or
          SWP_HIDEWINDOW);  //改变下拉框的位置和状态   
    //SetWindowPos(
    ///hWnd: HWND;            {窗口句柄}
    //hWndInsertAfter: HWND; {窗口的 Z 顺序}
    //X, Y: Integer;         {位置}
    //cx, cy: Integer;       {大小}
    //uFlags: UINT           {选项}
    //): BOOL;
    //SWP_NOSIZE         = 1;    {忽略 cx、cy, 保持大小}
    //SWP_NOMOVE         = 2;    {忽略 X、Y, 不改变位置}
    //SWP_NOZORDER       = 4;    {忽略 hWndInsertAfter, 保持 Z 顺序}
    //SWP_NOREDRAW       = 8;    {不重绘}
    //SWP_NOACTIVATE     = $10; {不激活}
    //SWP_FRAMECHANGED   = $20; {强制发送 WM_NCCALCSIZE 消息, 一般只是在改变大小时才发送此消息}
    //SWP_SHOWWINDOW     = $40; {显示窗口}
    //SWP_HIDEWINDOW     = $80; {隐藏窗口}
    //SWP_NOCOPYBITS     = $100; {丢弃客户区}
    //SWP_NOOWNERZORDER = $200; {忽略 hWndInsertAfter, 不改变 Z 序列的所有者}
    //SWP_NOSENDCHANGING = $400; {不发出 WM_WINDOWPOSCHANGING 消息}
    //SWP_DRAWFRAME      = SWP_FRAMECHANGED; {画边框}
    //SWP_NOREPOSITION   = SWP_NOOWNERZORDER;{}
    //SWP_DEFERERASE     = $2000;            {防止产生 WM_SYNCPAINT 消息}
    //SWP_ASYNCWINDOWPOS = $4000;            {若调用进程不拥有窗口, 系统会向拥有窗口的线程发出需求}  finally
        FDroppingDown := False;
      end;
      SetWindowPos(FDropHandle, 0, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or
        SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOREDRAW or SWP_SHOWWINDOW);
    end;
      

  3.   


    AutoComplete设为False  是FALSE變成這樣嗎??
    這個問題在DBGRIDEH中的PICKUP中也存在。 不過上面的沒太明白你的操作方法。
      

  4.   

    @starluck
    AutoComplete是设为False。
      

  5.   

    确实是个问题,感觉AutoComplete用处不大,网上也有类似的解决方法,但是似乎不完整:
    http://www.cnblogs.com/SouthAurora/archive/2010/04/21/1716967.html