TLama

Untitled

Aug 12th, 2014
587
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 2.77 KB | None | 0 0
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
  8.  
  9. type
  10.   TComboBox = class(Vcl.StdCtrls.TComboBox)
  11.   private
  12.     FMouseInList: Boolean;
  13.     FListBoxHandle: HWND;
  14.     FListBoxWndProc: Pointer;
  15.     FListBoxInstance: Pointer;
  16.     FOnDropListLeave: TNotifyEvent;
  17.     procedure WMParentNotify(var AMessage: TMessage); message WM_PARENTNOTIFY;
  18.   protected
  19.     procedure ListBoxWndProc(var AMessage: TMessage); virtual;
  20.   public
  21.     destructor Destroy; override;
  22.     property OnDropListLeave: TNotifyEvent read FOnDropListLeave write FOnDropListLeave;
  23.   end;
  24.  
  25. type
  26.   TForm1 = class(TForm)
  27.     ComboBox1: TComboBox;
  28.     procedure FormCreate(Sender: TObject);
  29.     procedure ComboBox1MouseEnter(Sender: TObject);
  30.   private
  31.     procedure DropListLeave(Sender: TObject);
  32.   end;
  33.  
  34. var
  35.   Form1: TForm1;
  36.  
  37. implementation
  38.  
  39. {$R *.dfm}
  40.  
  41. { TComboBox }
  42.  
  43. destructor TComboBox.Destroy;
  44. begin
  45.   if (FListHandle <> 0) and Assigned(FListBoxInstance) then
  46.   begin
  47.     SetWindowLong(FListHandle, GWL_WNDPROC, IntPtr(FListBoxWndProc));
  48.     FreeObjectInstance(FListBoxInstance);
  49.     FListBoxInstance := nil;
  50.   end;
  51.   inherited;
  52. end;
  53.  
  54. procedure TComboBox.WMParentNotify(var AMessage: TMessage);
  55. begin
  56.   if (FListBoxHandle = 0) and (AMessage.WParamLo = WM_CREATE) then
  57.   begin
  58.     FMouseInList := False;
  59.     FListBoxHandle := AMessage.LParam;
  60.     FListBoxWndProc := Pointer(GetWindowLong(FListBoxHandle, GWL_WNDPROC));
  61.     FListBoxInstance := MakeObjectInstance(ListBoxWndProc);
  62.     SetWindowLong(FListBoxHandle, GWL_WNDPROC, IntPtr(FListBoxInstance));
  63.   end
  64.   else
  65.     inherited;
  66. end;
  67.  
  68. procedure TComboBox.ListBoxWndProc(var AMessage: TMessage);
  69. var
  70.   R: TRect;
  71.   P: TPoint;
  72.   InRect: Boolean;
  73. begin
  74.   if (FListBoxHandle <> 0) and (AMessage.Msg = WM_MOUSEMOVE) then
  75.   begin
  76.     if Winapi.Windows.GetClientRect(FListBoxHandle, R) then
  77.     begin
  78.       P.X := TWMMouseMove(AMessage).XPos;
  79.       P.Y := TWMMouseMove(AMessage).YPos;
  80.       InRect := PtInRect(R, P);
  81.  
  82.       if InRect xor FMouseInList then
  83.       begin
  84.         FMouseInList := InRect;
  85.         if not InRect and Assigned(FOnDropListLeave) then
  86.           FOnDropListLeave(Self);
  87.       end;
  88.     end;
  89.   end;
  90.  
  91.   AMessage.Result := CallWindowProc(FListBoxWndProc,
  92.     FListBoxHandle, AMessage.Msg, AMessage.WParam, AMessage.LParam);
  93. end;
  94.  
  95. { TForm1 }
  96.  
  97. procedure TForm1.FormCreate(Sender: TObject);
  98. begin
  99.   ComboBox1.OnDropListLeave := DropListLeave;
  100. end;
  101.  
  102. procedure TForm1.ComboBox1MouseEnter(Sender: TObject);
  103. begin
  104.   ComboBox1.DroppedDown := True;
  105. end;
  106.  
  107. procedure TForm1.DropListLeave(Sender: TObject);
  108. begin
  109.   ComboBox1.DroppedDown := False;
  110. end;
  111.  
  112. end.
Advertisement
Add Comment
Please, Sign In to add comment