Solved

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

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

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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

929 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

13 Experts available now in Live!

Get 1:1 Help Now