Solved

replacing an image in Timage.picture(LoadFromFile())

Posted on 2004-08-28
14
1,672 Views
Last Modified: 2007-12-19
I have an image of a button in the up state. I want the image to chage to the down state while the mouse hovers over the button and then return to the up state when the mouse leaves the button. I have successfully caused the image to change once when I use the OnMouseMove event, but it stays in the down state when the mouse moves off the image. I don't see a OnMouseOver event in the Events list for the Timage component. BTW i am using Delphi 6.
Thanks,
Annas
0
Comment
Question by:annas
14 Comments
 
LVL 13

Expert Comment

by:BlackTigerX
ID: 11921664
you can implement a descendant of the TImage component and add the CM_MOUSELEAVE message to it, so that it would have the OnMouseLeave event, the code to create this descendant is very simple:

type
  TMyImage = class(TImage)
  private
    FOnMLeave: TNotifyEvent;
    procedure CMMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
  published
    property OnMouseLeave:TNotifyEvent read FOnMLeave write FOnMLeave;
  end;

procedure TMyImage.CMMouseLeave(var Msg: TMessage);
begin
  inherited;
  if Assigned(OnMouseLeave)then OnMouseLeave(Self);
end;

you could also add the CM_MOUSEENTER message...
if you don't want to create a component you can use this from Code... is just a bit harder:

to start you would have to create the image dinamically:
procedure TForm1.FormCreate(Sender: TObject);
begin
  MyImage:=TMyImage.Create(Self);
  MyImage.Left:=10;
  MyImage.Top :=100;
  MyImage.Parent:=Self;
  MyImage.Stretch:=True;
  MyImage.Picture.LoadFromFile('F:\somepic.jpeg');
  MyImage.OnMouseMove:=Image1MouseMove;
  MyImage.OnMouseLeave:=ImageOnMouseLeave
end;

and assign the events manually, etc... the easies would be to create a component
0
 

Author Comment

by:annas
ID: 11922426
yeah I do like the first method better. I had to put the:

procedure TMyImage.CMMouseLeave(var Msg: TMessage);
begin
  inherited;
  if Assigned(OnMouseLeave)then OnMouseLeave(Self);
end;

in the implementation section to get it to compile and run.
This is what I had:
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
image1.Picture.LoadFromFile('red.gif');
end;

Where do I put "image1.Picture.LoadFromFile('red.gif');" so that the image changes back to red?

I have looked everywhere on the web and I can't find any tutorial that walks you through adding a method like a mouseover event to an already created component.

Would adding a MouseOver event be more difficult than adding this Onmouseleave event?
Thanks,
Annas
0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 11923844
in addition to what BlackTigerX suggested, you can use his idea, but using TSpeedButton. You will put the first image as Glyph in the beginning, and then proceed the same way as the post above...

--------------------------------------------------------------------------------------------------------------

unit MySpeedButton;

interface

uses
  SysUtils, Classes, Controls, Buttons;

type
  TMySpeedButton = class(TSpeedButton)
  private
    FOnMouseEnter : TNotifyEvent;
    FOnMouseLeave : TNotifyEvent;
    procedure CMMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
    procedure CMMouseEnter(var Msg: TMessage); message CM_MOUSEENTER;
  published
    property OnMouseEnter : TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
    property OnMouseLeave : TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TMySpeedButton]);
end;

end.
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Comment

by:annas
ID: 11924027
Yes , but I am confused by both. Where do i put my code snippet, the one that loads the images? I really like this idea of creating new methods or maybe exposing old ones. someone told me that every class inherited from Tcomponent has a mouseenter and a Mouse Leave method. Thats what I want. I guess there is no such thing as a mouseOver method except in Javascript. Loading an image in Mouse enter and restoring the old one in MouseLeave is actualy what I want to do. I prefer the Timage component because then I can make my buttons exactly the shape I want. I use Anders Melande's Tgif code to let me use a gif with Timage and it's perfect. I confess that I'm not an expert Delphi programmer and I may need you to spell it out for me!
Thanks,
Paul :)
0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 11925942
Select the component, press F11 and in Object Inspector go to Events
there you have OnMouseEnter and OnMouseLeave. This is the place for your code...
0
 

Author Comment

by:annas
ID: 11926336
Well I placed the code(Tiger's) in and ran the program to save and compile and it ran. I selected the image component and looked in the events for mouseEnter and Mouse Leave but it's still not there. :(
Annas
0
 

Author Comment

by:annas
ID: 11926442

   Here is the code I have now( I put the button in just as an experiment to see if the load from file would work):
**********************************************************************************
type
  TForm1 = class(TForm)
    Image1: TImage;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
type
  Image1 = class(TImage)
  private
    FOnMLeave: TNotifyEvent;
    procedure CMMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
  published
    property OnMouseLeave:TNotifyEvent read FOnMLeave write FOnMLeave;
  end;
var
  Form1: TForm1;

implementation

{$R *.dfm}
 procedure Image1.CMMouseLeave(var Msg: TMessage);
begin
  inherited;
  if Assigned(OnMouseLeave)then OnMouseLeave(Self);
Image1.Picture.LoadFromFile('red.gif');
  end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Image1.Picture.LoadFromFile('red.gif');
end;

end.
*******************************************
When I put the Image1.Picture.LoadFromFile('red.gif'); in I get these error msgs:

[Error] Unit1.pas(37): Method identifier expected
[Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'

What's wrong? Why won't it compile?
Thanks,
Annas

0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 11926588
nooooo, you are doing this veeeeery wrong way.

note your type declaration

type
  Image1 = class(TImage)

and on your form you have Image1: TImage;
which is the standard Delphi class....
0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 11926593
the code (Tiger's) should be saved as separate .pas file.

The go to Component / Install and point to this file, the click compile and install in the box you will see. This way you will install the new component in the component palette.

The open the project, and put TMyImage on the form instead of TImage...
0
 

Author Comment

by:annas
ID: 11926798
Thanks Ivanov for setting me staight, but I can't install just the code Tiger gave me it won't install I think it needs something else. when I tried to install, it says missing unit. Then I closed everything and selected new-> unit. and pasted the code in it. This time I got the error "list index out of bounds (0)"
Annas
0
 
LVL 12

Accepted Solution

by:
Ivanov_G earned 250 total points
ID: 11928685
yes, his code is not full... here is what you have to do.

1) Component / New Component. For Ancestor Type choose TImage. For class name - the name of your class. For e.g. TMyImage. Palette Page - for e.g. Samples and click OK.

2) Delphi will generate you some code... Make it look like the code I paste below... Save it as a file

3) Component / Install Component. For unit file name select the unit you just saved in 2) and click OK. Then Compile and Install in the dialog.

4) Now on "Samples" tab you see your new component - TMyImage (which have events OnMouseEnter and OnMouseLeave). Use it instead of the standard TImage.

That's it. OK, here is the code:

-------------------------------------------------------------

unit MyImage;

interface

uses
  SysUtils, Classes, Controls, ExtCtrls;

type
  TMyImage = class(TImage)
  private
    FOnMouseEnter : TNotifyEvent;
    FOnMouseLeave : TNotifyEvent;
    procedure CMMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
    procedure CMMouseEnter(var Msg: TMessage); message CM_MOUSEENTER;
  protected
  public
  published
    property OnMouseEnter : TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
    property OnMouseLeave : TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TMyImage]);
end;

procedure TMyImage.CMMouseEnter(var Msg: TMessage);
begin
  if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);
end;

procedure TMyImage.CMMouseLeave(var Msg: TMessage);
begin
  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;

end.
0
 
LVL 3

Expert Comment

by:gandalf_the_white
ID: 11929079
i think the problem is that you are visually coding:
that means you are dropping you image on the form and manipulate its properties with the object inspector
if i am wrong just ignore the rest.

if this is true then its an overkill to install a new component in the ide only to get a new property to TImage
(as you would do this every time you need a new property)

you can create the TMyImage Object nonvisual and set its properties during runtime.

something like:

NowNonVisualImage := TMyImage.create(Form1); // Form1 is the Owner of the Image and will free it if Form1 is destroyed
with NowNonVisualImage do
begin
  // here you set all the properties you had adjusted in the object inspector
  left:= ;
  Top := ;

  // to see the image in your form you have to do a few things

  // Panel1 is the parent of the image and if the panel is invisible you won't see the image
  Parent := panel1;

  // if you set autosize to true the image area is equal to the bitmap area
  autosize := True;
  // otherwise you have to set width and height

  // to see anything you have to load something ;-)
  picture.loadfromfile ('c:\bitmaptoshow.bmp');

end;

if you have made you component nonvisually it should be easy for you
to use the changes from the other posts

regards

0
 

Author Comment

by:annas
ID: 11929130
Beautiful! Beautiful! Thank you so much for sticking with me, Ivanov! It went  perfect the first time, no errors. I have really learned something here and this is really going to expand my horizons! I think my next act will be to get a good book on the meaning of these statements like sender and Tmessage and the like. also one on creating and modifying controls. Can you reccomend some for me?

BTW I'm increasing the points. You've earned them!
Annas
0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 11931415
I am glad I could help. :)))
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

809 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