Solved

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

Posted on 2004-08-28
14
1,658 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
 

Author Comment

by:annas
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility

   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
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 12

Expert Comment

by:Ivanov_G
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
I am glad I could help. :)))
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

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…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

771 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

9 Experts available now in Live!

Get 1:1 Help Now