Advertisement
tarakan1983

TACComboBox

Feb 11th, 2024
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 6.33 KB | Help | 0 0
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5.  
  6. interface
  7.  
  8. uses
  9.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, LMessages, StdCtrls,
  10.   Messages, LCLType, LCLIntf, Variants;
  11.  
  12. type // Класс, реализующий выпадающее окно автозавершения
  13.  
  14.   { TDropDownListBox }
  15.  
  16.   TDropDownListBox = class(TListBox)
  17.   protected
  18.     procedure WMActivateApp(var M: TMessage); message WM_ACTIVATEAPP;
  19.     procedure WMMouseMove(var M: TLMMouseMove); message WM_MOUSEMOVE;
  20.     procedure WMLButtonUp(var M: TLMLButtonUp); message WM_LBUTTONUP;
  21.     procedure CreateParams(var Params: TCreateParams); override;
  22.     procedure UpdateItemIndex;
  23.   end;
  24.  
  25. type
  26.   TCheckStringEvent = procedure(Sender: TObject; const EditText, S: String; var AddString: Boolean) of object;
  27.  
  28. type
  29.   TAutoCompleteType = (actSimple, actSubString, actCustom);
  30.  
  31. type // Комбо-бокс с выпадающем окном автозавершения
  32.  
  33.   { TACComboBox }
  34.  
  35.   TACComboBox = class(TComboBox)
  36.  
  37.     private
  38.       FACItems : TStrings;
  39.       FOldFormWndProc, FNewFormWndProc: Pointer; // Используется для подмены оконной процедуры родительской формы
  40.       FParentFormWnd: hWnd; // Handle родительской формы
  41.       FDropped: Boolean; // True, когда показано выпадающее окно
  42.       FACType: TAutoCompleteType;
  43.       FOnCheckString : TCheckStringEvent;
  44.       procedure SetACItems ( AValue : TStrings ) ;
  45.     protected
  46.       FDropDown: TDropDownListBox; // Выпадающее окно автозавершения
  47.       procedure SetParent(AParent: TWinControl); override;
  48.       procedure ParentFormWndProc(var Message: TMessage);  // Оконная процедура, которой подменяем оконную процедуру родительской формы
  49.     public
  50.       constructor Create(AOwner: TComponent); override;
  51.       destructor Destroy; override;
  52.     published
  53.       property ACItems: TStrings read FACItems write SetACItems;
  54.       property ACType: TAutoCompleteType read FACType write FACType default actSubString;
  55.       property OnCheckString: TCheckStringEvent read FOnCheckString write FOnCheckString;
  56.   end;
  57.  
  58. type
  59.  
  60.   { TForm1 }
  61.  
  62.   TForm1 = class ( TForm )
  63.     ListBox1 : TListBox;
  64.     procedure FormCreate ( Sender : TObject ) ;
  65.   private
  66.  
  67.   public
  68.  
  69.   end;
  70.  
  71. var
  72.   Form1 : TForm1;
  73.   CA : TACComboBox;
  74.  
  75. implementation
  76.  
  77. {$R *.lfm}
  78.  
  79. { TForm1 }
  80.  
  81. procedure TForm1.FormCreate ( Sender : TObject ) ;
  82. begin
  83.   CA := TACComboBox.Create(Self);
  84.   CA.Parent := Self;
  85.   CA.Align := alTop;
  86.  
  87.  
  88. end;
  89.  
  90. { TDropDownListBox }
  91.  
  92. procedure TDropDownListBox.WMActivateApp ( var M : TMessage ) ;
  93. begin
  94.  
  95. end;
  96.  
  97. procedure TDropDownListBox.WMMouseMove ( var M : TLMMouseMove ) ;
  98. begin
  99.  
  100. end;
  101.  
  102. procedure TDropDownListBox.WMLButtonUp ( var M : TLMLButtonUp ) ;
  103. begin
  104.  
  105. end;
  106.  
  107. procedure TDropDownListBox.CreateParams ( var Params : TCreateParams ) ;
  108. begin
  109.   inherited CreateParams ( Params ) ;
  110.   Params.ExStyle := WS_EX_TOOLWINDOW;
  111.   Params.WndParent := GetDC(0);
  112.   Params.Style := WS_CHILD or WS_BORDER or WS_CLIPSIBLINGS or WS_OVERLAPPED or WS_VSCROLL or LBS_NOINTEGRALHEIGHT;
  113. end;
  114.  
  115. procedure TDropDownListBox.UpdateItemIndex;
  116. begin
  117.  
  118. end;
  119.  
  120. { TACComboBox }
  121.  
  122. constructor TACComboBox.Create ( AOwner : TComponent ) ;
  123.   var
  124.     H : HWND;
  125.     F : TCustomForm;
  126. begin
  127.   inherited Create ( AOwner ) ;
  128.   FACItems := TStringList.Create;
  129.   FACType := actSubString;
  130.   FDropped := False;
  131.   FParentFormWnd := 0;
  132.  
  133.   if not (csDesigning in ComponentState) then
  134.     begin
  135.       FDropDown := TDropDownListBox.Create(Self);
  136.       //F := GetParentForm(AOwner as TControl);
  137.       //FDropDown.Parent := Self;
  138.       //ShowMessage(VarToStr(F.Name));
  139.       //FDropDown.Left := 10; // Например, установка координат
  140.       //FDropDown.Top := 10;
  141.       ////FDropDown.Width := 100;
  142.       //FDropDown.Height := 80;
  143.       //if Assigned(FDropDown) then
  144.       //  begin
  145.       //    FDropDown.CreateWnd;
  146.       //    ShowMessage(IntToStr(FDropDown.Handle));
  147.       //  end;
  148.  
  149.       Exit;
  150.  
  151.       // Теперь вы можете безопасно обращаться к Handle
  152.       // Например,
  153.       ShowMessage(IntToStr(FDropDown.Handle));
  154.  
  155.  
  156.  
  157.       //SetWindowLong(FDropDown.Handle, GWL_HWNDPARENT, GetDC(0));
  158.       H := FDropDown.Handle;
  159.       ShowWindow(FDropDown.Handle, SW_SHOW);
  160.     end;
  161. end;
  162.  
  163. destructor TACComboBox.Destroy;
  164. begin
  165.   if not (csDesigning in ComponentState) then FDropDown.Free;
  166.   FACItems.Free;
  167.   inherited Destroy;
  168. end;
  169.  
  170. procedure TACComboBox.SetACItems ( AValue : TStrings ) ;
  171. begin
  172.   if FACItems = AValue then Exit;
  173.   FACItems := AValue;
  174. end;
  175.  
  176. procedure TACComboBox.ParentFormWndProc ( var Message : TMessage ) ;
  177.   procedure Default;
  178.   begin
  179.     with Message do Result := CallWindowProc(FOldFormWndProc, FParentFormWnd, Msg, wParam, lParam);
  180.   end;
  181. begin
  182.   //case Message.Msg of // при изменении положения родительской формы прячем окно автозавершения
  183.   //  WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED: ;//HideAC(False);
  184.   //end; // case
  185.   Default;
  186. end;
  187.  
  188. procedure TACComboBox.SetParent ( AParent : TWinControl ) ;
  189.   var
  190.     Frm : TCustomForm;
  191. begin
  192.   // Если вдруг (что маловероятно :)) компонент переносится с одной формы на другую,
  193.   // возвращаем форме ее "родную" оконную процедуру
  194.   if not (csDesigning in ComponentState) and (FParentFormWnd <> 0) then
  195.     SetWindowLong(FParentFormWnd, GWL_WNDPROC, Integer(FOldFormWndProc));
  196.  
  197.   inherited SetParent ( AParent ) ;
  198.  
  199.   // Подменяем оконную процедуру родительской формы. Делаем это только в Run-Time,
  200.   // т.к. в Design-Time список автозавершения не создается
  201.   if not (csDesigning in ComponentState) then
  202.     begin
  203.       Frm := GetParentForm(Self);
  204.       if Assigned(Frm) then
  205.     begin
  206.       FParentFormWnd := Frm.Handle;
  207.       FNewFormWndProc := MakeObjectInstance(@ParentFormWndProc);
  208.       FOldFormWndProc := Pointer(GetWindowLong(FParentFormWnd, GWL_WNDPROC));
  209.       SetWindowLong(FParentFormWnd, GWL_WNDPROC, Integer(FNewFormWndProc));
  210.     end;
  211.     end;
  212. end;
  213.  
  214. end.
  215.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement