Solved

Change image on mouseover

Posted on 2004-08-18
12
2,038 Views
Last Modified: 2008-01-09
Hi. I'd like to have an application in which I have 6 images. The first image should be a menu that is full unselected. The second should be the menu full selected. The third should be depressed (when I am holding the mouse button down). And the 4th should be a new image. The 5th should be when the new image is being displayed, but when I am holding my mouse over it. And the 6th should be when I am clicking it. For example, I have a mute button. When the mouse is not over it, it should be unselected. When the mouse is over it it should be selected. The third should be when I am holding the mouse button down. And the 4th should be when I have already clicked on it and it changed to another image (muted). The 5th should be when I am holding my mouse over the muted image (and it being highlighted), and the 6th should be when I am clicking on the mute button and it become unmuted.

But also this code has to have the other parts of the menu be clickable, but not to change to a different image after being clicked. Oh, it also needs to be FAST.

Here is some code. http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21061934.html#11745650

Thanks,
David Burban
0
Comment
Question by:the_modder
  • 4
  • 2
  • 2
  • +2
12 Comments
 
LVL 1

Author Comment

by:the_modder
ID: 11838547
bump? Points increased to 175!
0
 
LVL 5

Expert Comment

by:Darth_helge
ID: 11838594
well, i won't be doing your whole task, but you have to implement the mouseEnter and mouseLeave events on an image component (or a button component or whatever you want to use)

here is code for an image component with those events. Just open this is in delphi and choose component-->install component


unit InfoImg;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  ExtCtrls;
type
  TInfoImage = class(TImage)
  private
    FOnMouseLeave: TNotifyEvent;
    FOnMouseEnter: TNotifyEvent;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
  protected
  public
  published
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
    property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Info Components', [TInfoImage]);
end;

procedure TInfoImage.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  if Assigned(FOnMouseEnter) then FOnMouseEnter(Self);
end;

procedure TInfoImage.CMMouseLeave(var Message: TMessage);
begin
  inherited;
  if Assigned(FOnMouseLeave) then FOnMouseLeave(Self);
end;

end.
0
 
LVL 1

Author Comment

by:the_modder
ID: 11838661
The thing is that I have a menu of like 13 items. I want to do the 6 image thing to only 2 of them. The rectangles in the link that I gave pull parts of the selected image onto the deselected image over where my mouse is. That's what I want, except with 6 images (just two buttons like this, the rest should be like in the link, but with mousehold).
0
 
LVL 5

Expert Comment

by:Darth_helge
ID: 11838694
maybe I didn't read your whole question. But your question title is "Change image on mouseover"....
0
 
LVL 1

Author Comment

by:the_modder
ID: 11838781
Yeh, I can't really summarize it in a few words :|
0
 
LVL 7

Expert Comment

by:sftweng
ID: 11838906
Look at Delphi Help for TSpeedButton. I think you'll find it's what you want.
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 1

Expert Comment

by:aruana
ID: 11842301
Use the TToolbar. Add six TImageList to your form.  One set each for every stage you mentioned.
For those buttons uneffeced, load the same image into the image list.
Set the first two sets to Images and HotImages property of TToolbar.  This takes care of mouse over image change event. For onclick and when selected, change the Images and HotImages property to point to the correct sets of image list.  Refresh the toolbar if need to, depends on what you are doing.
0
 
LVL 1

Author Comment

by:the_modder
ID: 11852767
The thing is that I don't want to cut out every image and then do that. If you look at the link, it has code that just needs some improvement on how many iages it has. Cutting out a lot of images would be a waste of time because it can be done in code.
0
 
LVL 33

Expert Comment

by:Slick812
ID: 11862438
the_modder
do you have much of an idea what my code (in your other question) does?
can you show some code that you have made, to try and do what you say you want?
or do I have to code the whole thing again?

did you try a new TRectShow Record?
can you show what you added to it?

TRectShow = record // record type to keep Show and Rect info
    Show: Boolean;
    Muted: Boolean; // maybe add a muted boolean
    ImgRect: TRect;
    end;

and where whould you test for this Muted boolean value to get it to show a muted picture?

and wouldn't your sixth image be the same as your second image?
goes from muted (image 4)  BACK TO unmuted (image 2)
0
 
LVL 7

Expert Comment

by:sftweng
ID: 11862474
Slick812, by now I think it should be clear that the_modder wants full solutions written for him rather than ideas about how to solve the problem himself. This may be because he is a total novice to programming, just lazy, genuinely confused or has decided that EE is a great place to get cheap consulting. Given my experience with the previous thread and his responses here, I have to wonder what he'd be satisified with short of a complete implementation (from his very nebulous specs).
0
 
LVL 33

Accepted Solution

by:
Slick812 earned 175 total points
ID: 11865317
there is almost nothing that is clear to me anymore

the following is code that works for me, as near or far off as I can understand the design specs - -


type
  TRectShow = record
    TwoImages: Boolean;
    ShowImage2: Boolean;
    ImgRect: TRect;
    end;



  private
    { Private declarations }
    aryBmp: Array[0..5] of TBitmap;
  {because there are so many Bitmaps, I use an Array of Bitmaps}
    LastPaint, DownIndex: Integer;
  {I need global var to track the hilight and Down rect}
    aryRectShow: Array[0..5] of TRectShow;



procedure TForm1.FormDestroy(Sender: TObject);
var
i: Integer;
begin
for i := 0 to High(aryBmp) do
  FreeAndNil(aryBmp[i]);
end;



procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
LastPaint := -1;
DownIndex := -1;
for i := 0 to High(aryBmp) do
  aryBmp[i] := TBitmap.Create;

aryBmp[0].Canvas.Brush.Color := $BBBBBB; // 0 is "Normal" bitmap
  // aryBmp[0].LoadFromFile('C:\Normal.bmp');
aryBmp[1].Canvas.Brush.Color := $EEEEEE; // 1 is Normal Hilight
aryBmp[2].Canvas.Brush.Color := $888888; // 2 is Normal Down
aryBmp[3].Canvas.Brush.Color := $0000BF; // 3 is Second (mute) normal image
aryBmp[4].Canvas.Brush.Color := $AAAAFF; // 4 is Second Hilight
aryBmp[5].Canvas.Brush.Color := $000090; // 5 is Second Down

for i := 0 to High(aryBmp) do
  begin
  //only set width and height if not already set
  aryBmp[i].Width := PaintBox3.Width;
  aryBmp[i].Height := PaintBox3.Height;
  end;

for i := 0 to High(aryRectShow) do
  begin
 // set all of your rectangles
  aryRectShow[i].ImgRect := Rect(1,i * 32, 70, (i * 32)+26);
  aryRectShow[i].TwoImages := False;  // set all TwoImages
  aryRectShow[i].ShowImage2 := False;
  end;
aryRectShow[1].TwoImages := True; // sets the rect to have a second Image - Mute
aryRectShow[3].TwoImages := True;
end;


procedure TForm1.PaintBox3Paint(Sender: TObject);
var
i: Integer;
begin
PaintBox3.Canvas.Draw(0,0, aryBmp[0]);
for i := 0 to High(aryRectShow) do
  if aryRectShow[i].ShowImage2 then // ShowImage2 is true for a second (mute) image
    PaintBox3.Canvas.CopyRect(aryRectShow[i].ImgRect, aryBmp[3].Canvas,
                              aryRectShow[i].ImgRect);
end;


procedure TForm1.PaintBox3MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
i, index: Integer;
InRect: Boolean;
begin
InRect := False;
for i := 0 to High(aryRectShow) do
  if PtInRect(aryRectShow[i].ImgRect, Point(X, Y)) then
    begin
    InRect := True;
    if LastPaint = i then Exit; // already painted, exit out
    if aryRectShow[i].ShowImage2 then // ShowImage2 will be true for second Image
      index := 4 // index for second Image hilight
      else
      index := 1; // index for normal Image hilight
    PaintBox3.Canvas.CopyRect(aryRectShow[i].ImgRect, aryBmp[index].Canvas,
                              aryRectShow[i].ImgRect);

    if (LastPaint > -1) then
      begin
      if aryRectShow[LastPaint].ShowImage2 then
        index := 3
        else
        index := 0;
      PaintBox3.Canvas.CopyRect(aryRectShow[LastPaint].ImgRect,
                          aryBmp[index].Canvas, aryRectShow[LastPaint].ImgRect);
      end;
    LastPaint := i;
    Break
    end;

if (not InRect) and  (LastPaint > -1) then
  begin
  if aryRectShow[LastPaint].ShowImage2 then
    index := 3  // second image
    else
    index := 0; // normal image
  PaintBox3.Canvas.CopyRect(aryRectShow[LastPaint].ImgRect,
                          aryBmp[index].Canvas, aryRectShow[LastPaint].ImgRect);
  LastPaint := -1;
  end;
end;


procedure TForm1.PaintBox3MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
i, index: Integer;
begin
if Button <> mbLeft then Exit; // only use left button
for i := 0 to High(aryRectShow) do
  if PtInRect(aryRectShow[i].ImgRect, Point(X, Y)) then
    begin
    if aryRectShow[i].ShowImage2 then
      index := 5  // set index to mute Hilight
      else
      index := 2; // set index to normal Hilight
    PaintBox3.Canvas.CopyRect(aryRectShow[i].ImgRect, aryBmp[index].Canvas, aryRectShow[i].ImgRect);
    DownIndex := i;
    LastPaint := -1;

    if aryRectShow[i].TwoImages then // test for TwoImages to set the ShowImage2
      aryRectShow[i].ShowImage2 := not aryRectShow[i].ShowImage2;
    // ShowImage2 will be tested for the display of second Image - mute
    Break;
    end;
end;


procedure TForm1.PaintBox3MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
i, index: Integer;
Pt1: TPoint;
begin
if Button <> mbLeft then Exit;

if (DownIndex > -1) then
  begin
  // redraw Dowm Rect
  if aryRectShow[DownIndex].ShowImage2 then
    index := 4 // second hilight
    else
    index := 1; // normal hilight
  PaintBox3.Canvas.CopyRect(aryRectShow[DownIndex].ImgRect, aryBmp[index].Canvas, aryRectShow[DownIndex].ImgRect);
  LastPaint := DownIndex;
  DownIndex := -1;
  end;

for i := 0 to High(aryRectShow) do
  if PtInRect(aryRectShow[i].ImgRect, Point(X, Y)) then
    begin
    Label1.Caption := 'Click on rect '+IntToStr(i);
    case i of
  // click events here
      0: Label2.Caption := 'So the Zero was clicked';
      1: Label2.Caption := 'and The One was clicked';
      2: Label2.Caption := 'What Happend? Got Clicked';
      3: ShowMessage('Number 3 was clicked');
      4: Label2.Caption := 'This was a Four Click';
      5: ShowMessage('5 clicked');
      end;

    Pt1 := PaintBox3.ScreenToClient(Mouse.CursorPos);
    // in case modal window like showmessage
    if not PtInRect(aryRectShow[i].ImgRect, Pt1) then
      begin
      if aryRectShow[i].ShowImage2 then
        index := 3
        else
        index := 0;
      PaintBox3.Canvas.CopyRect(aryRectShow[i].ImgRect, aryBmp[index].Canvas, aryRectShow[i].ImgRect);
      LastPaint := -1;
      end;
  Break;
  end;

end;
0
 
LVL 1

Expert Comment

by:aruana
ID: 11867269
....Cutting out a lot of images would be a waste of time because it can be done in code....

how many button images can a program have?
If it would make you feel better. use only two TImageList and change the ImageIndex property on the fly.  six TImageList make beter image management because the images are all in the same sequence.
With HotImage and Images property, combined with mouse events, TToolButton has all the thing you need to implement this.  And if TToolbar gets in the way of your background, put only one button on each toolbar and make the toolbar the same size as the button.
Why go to such extreme coding ? Unless you have cut the code from somewhere and keep insisting to make it work.
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This video discusses moving either the default database or any database to a new volume.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now