Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

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

Posted on 2004-08-28
14
Medium Priority
?
1,695 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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 1000 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: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering 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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses

618 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