Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Mouse Event Combobox 1

Status
Not open for further replies.

umyeah

Programmer
May 25, 2004
6
US
Is there any way to execute some code for a mouse over event for a combobox?

When the user opens a combobox and puts the mouse over each option to highlight it, I want a corresponding image to be loaded from a file.

I already load it once an options is selected but they would like to view each option more readily. Is this possible?
 
I would solve it by using the event OnDrawItem.

Code:
with TComboBox(Sender).Canvas do
begin
  FillRect(Rect);
  // ...draw Image for the ItemIndex
  TextOut(Rect.Left +16, Rect.Top+2, TheString);
end;



//Nordlund
 
An alternative would be to use a TListBox as it has a OnMouseMove event. The following piece of code identifies the item as the mouse passes it. Meanwhile I'll look at how to do the same for a TComboBox.
Code:
var
  point: TPoint;
  list: TListBox;
  itemNum: Integer;
begin
  point.X := X;
  point.Y := Y;
  list := (Sender as TListBox);
  itemNum := list.ItemAtPos(point, true);
  if itemNum <> -1 then
    ShowMessage(list.Items[itemNum]); // change pic in here
end;

Clive [infinity]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"To err is human, but to really foul things up you need a computer."
Paul Ehrlich
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To get the best answers from this forum see: faq102-5096
 
I have found a way to do it now using a TComboBox and its OnDrawItem event:
1) Set the Style property to csOwnerDrawFixed or csOwnerDrawVariable, this means you will now have to draw each item's output yourself.
2) Populate the combobox items with the filenames of your images, either at design-time in the property editor or at run-time.
3) Use the following code in the OnDrawItem event of the combobox:
Code:
procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
var
  combo: TComboBox;
begin
  combo := (Control as TComboBox);
  combo.Canvas.TextOut(Rect.Left, Rect.Top, combo.Items[Index]);
  Image1.Picture.LoadFromFile(combo.Items[Index]);
end;

The 1st line of the method is not essential but aids reading. Therefore, the combo variable declaration can be removed and all references to "combo" can be replaced with "(Control as TComboBox)".

The 2nd line is writing the text for each item onto the drop-down box, you have to do this manually because of the Style setting we made earlier.

The 3rd line loads a TImage component with the item the mouse is currently hovering over. Apparently, the phrase is "hotlighting" an item, but it doesn't seem to be used much.

Hope this helps!

Clive [infinity]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"To err is human, but to really foul things up you need a computer."
Paul Ehrlich
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To get the best answers from this forum see: faq102-5096
 
I've also found an alternative that can cope with the TComboBox Style property being csDropDown. It's a little more complicated and a bit of a fudge but it works nicely:
1) Place a TEdit on your form and set its Visible property to False
2) Place an ApplicationEvents component on your form
3) In the OnIdle event of this component place the following code:
Code:
var
  pt: TPoint;
  wnd: HWND;
  buf: array[0..128] of Char;
  i: Integer;
begin
  GetCursorPos(pt);
  wnd := WindowFromPoint(pt);
  If wnd <> 0 then begin
    buf[0] := #0;
    GetClassName(wnd, buf, SizeOf(buf));
    If StrIComp(buf, 'ComboLBox') = 0 Then Begin
      Windows.ScreenToClient(wnd, pt);
      i := SendMessage(wnd, LB_ITEMFROMPOINT, 0, lparam(PointToSmallpoint(pt)));
      If i >= 0 Then Begin
        SendMessage(wnd, LB_GETTEXT, i, integer(@buf));
        Edit1.Text := buf;
        Exit;
      End;
    End;
  end;
end;
The above code obtains the currently hotlighted combobox item and stores the text of this item in Edit1.

4) In the OnChange event of the TEdit place this code:
Code:
begin
  if FileExists((Sender as TEdit).Text) then
    Image1.Picture.LoadFromFile((Sender as TEdit).Text);
end;
The above code checks to see if the TEdit contains a valid filename then loads the image into the Image1 (TImage) component.

Clive [infinity]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"To err is human, but to really foul things up you need a computer."
Paul Ehrlich
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To get the best answers from this forum see: faq102-5096
 
The following article has just appeared on delphi.about.com:

Implementing OnMouseOver for Items in a TComboBox, with custom hints


It gives more of an explanation of the code in my previous post.

Clive [infinity]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"To err is human, but to really foul things up you need a computer."
Paul Ehrlich
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To get the best answers from this forum see: faq102-5096
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top