Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Component Trouble 5

Status
Not open for further replies.

BobbaFet

Programmer
Feb 25, 2001
903
NL
Hi there,

I'm trying to make a button which detects when the mouse
is over itself and when it isnt. Now I figured out how to
do that but the compiler says that there is something wrong
with it. Can you please tell me whats wrong because I dont
see it. This is my code :

unit CWMOverOut;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type
TCWMOverOut = class(TButton)
protected
procedure MouseOver (var Msg: TMessage);
message cm_mouseEnter;
procedure MouseOut (var Msg: TMessage);
message cm_mouseLeave;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('CWCon', [TCWMOverOut]);
end;

end.

Thanx allot,

BobbaFet Everybody has a right to my opinion.
E-mail me at cwcon@programmer.net
 
These are the errors I keep getting :

[Error] CWOverOut1.pas(15): Unsatisfied forward or external declaration: 'TCWOverOut1.CMMouseEnter'
[Error] CWOverOut1.pas(16): Unsatisfied forward or external declaration: 'TCWOverOut1.CMMouseLeave'
[Fatal Error] dclusr50.dpk(42): Could not compile used unit 'CWOverOut1.pas' Everyone has a right to my opinion.
E-mail me at cwcon@programmer.net
 
These are the errors I keep getting :

[Error] CWOverOut1.pas(15): Unsatisfied forward or external declaration: 'TCWOverOut1.CMMouseEnter'
[Error] CWOverOut1.pas(16): Unsatisfied forward or external declaration: 'TCWOverOut1.CMMouseLeave'
[Fatal Error] dclusr50.dpk(42): Could not compile used unit 'CWOverOut1.pas'

BobbaFet Everyone has a right to my opinion.
E-mail me at cwcon@programmer.net
 
Try using the following procedures:

procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;

procedure TmyButton.CMMouseEnter(var Message: TMessage);
begin
FMouseInControl := true;
end;

procedure TmyButton.CMMouseLeave(var Message: TMessage);
begin
FMouseInControl := false;
end;
 
Hi Nordlund,

I think you misunderstood me. It doesn't let me install the
component because it accept the procedure name or something.
But thats where I need the help because I dont know whats
wrong with it.

BobbaFet Everyone has a right to my opinion.
E-mail me at cwcon@programmer.net
 
[Error] CWOverOut1.pas(15): Unsatisfied forward or external declaration: 'TCWOverOut1.CMMouseEnter'
[Error] CWOverOut1.pas(16): Unsatisfied forward or external declaration: 'TCWOverOut1.CMMouseLeave'

Bobbafet:

I think Nordlund understood perfectly, if those are the errors you are getting. The problem is that you have declared two functions (CMMouseEnter and CMMouseLeave) in your class, but have not written an implementation for those functions. So, you need to implement them like he suggested.

TealWren
 
Hi TealWren,

I guess that I dont understand then. Where should I put
the suggested procedures then? (Please forgive but this is the first component I have ever worked on ...)

BobbaFet Everyone has a right to my opinion.
E-mail me at cwcon@programmer.net
 
Ok. This is your first component.

Here you have a simple component that uses the asked functions...




unit myButton;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TmyButton = class(TButton)
private
FMouseInControl: Boolean;
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
procedure MouseProcedure;
protected
public
constructor Create(AOwner: TComponent); override;
published
end;

procedure Register;

implementation

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

{ TmyButton }

// When mouse enter, this procedure will be executed
procedure TmyButton.CMMouseEnter(var Message: TMessage);
begin
FMouseInControl := true;
MouseProcedure;
end;

// When mouse exit, this procedure will be executed
procedure TmyButton.CMMouseLeave(var Message: TMessage);
begin
FMouseInControl := false;
MouseProcedure;
end;

// The constructor, FMouseInControl has to be set and I execute Mouseprocedure as well, just to set the Caption.
constructor TmyButton.Create(AOwner: TComponent);
begin
inherited;
FMouseInControl := false;
MouseProcedure;
end;

// Write your mouse Enter/Exit code here
procedure TmyButton.MouseProcedure;
begin
if FMouseInControl then
Caption := 'Mouse in.'
else
Caption := 'MouseOut';
end;

end.

 
Hi Nordlund,

Thank you for writing that code, but now have to put everthing in the button, but what I wanted to do with
was to make a PopupMenu popup when the mouse passes over,
and to destroy it when the mouse isn't over anymore.
So I wanted the MouseOver and MouseOut procedures to act events, so that they can be used over and over again.

Please forgive me for misinforming you.

BobbaFet Everyone has a right to my opinion.
E-mail me at cwcon@programmer.net
 
I'm not postive that CM_MOUSEENTER and CM_MOUSELEAVE will work as expected, but assuming that they do - here is how you make a new event. (I just stole Nordland's code and made a couple of changes. It might need some help for compiling but you should get the idea!)

TealWren


unit myButton;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;
type
  TmyButton = class(TButton)
  private
fOnMouseEnter: TNotifyEvent;
fOnMouseLeave: TNotifyEvent;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure MouseProcedure;
  protected
  public
    constructor Create(AOwner: TComponent); override;
  published
property OnMouseEnter: TNotifyEvent read fOnMouseEnter write fOnMouseEnter;
property OnMouseLeave: TNotifyEvent read fOnMouseLeave write OnMouseLeave;
  end;
procedure Register;
implementation
procedure Register;
begin
  RegisterComponents('Samples', [TmyButton]);
end;
{ TmyButton }
// When mouse enter, this procedure will be executed
procedure TmyButton.CMMouseEnter(var Message: TMessage);
begin
inherited CMMouseEnter(message);
if assigned(fOnMouseEnter) then fOnMouseEnter(self);
end;
// When mouse exit, this procedure will be executed
procedure TmyButton.CMMouseLeave(var Message: TMessage);
begin
inherited CMMouseLeave(Message);
if assigned(fOnMouseLeave) then fOnMouseLeave(self);
end;

end.
 
Hi again,

I'm almost there now, you guys have been a great help so
far. I have got only two problems left with your code
TealWren (two undeclared identifiers: CMMOuseEnter and
CMMouseLeave). I don't know whats wrong know because I
checked the declarations twice.

Code:
unit myButton;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;
type
  TmyButton = class(TButton)

  private
    fOnMouseEnter: TNotifyEvent;
    fOnMouseLeave: TNotifyEvent;
    procedure MouseEnter(var Message: TMessage); Message CM_MOUSEENTER;
    procedure MouseLeave(var Message: TMessage); Message CM_MOUSELEAVE;

  protected
    // Protected Declarations

  public
    // Public Declarations

  published
    property OnMouseEnter: TNotifyEvent read fOnMouseEnter write fOnMouseEnter;
    property OnMouseLeave: TNotifyEvent read fOnMouseLeave write fOnMouseLeave;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Sample', [TmyButton]);
end;

// When mouse enter, this procedure will be executed
procedure TmyButton.MouseEnter(var Message: TMessage);
begin
  inherited MouseEnter(Message);
  if assigned(fOnMouseEnter) then fOnMouseEnter(self);
end;

// When mouse exit, this procedure will be executed
procedure TmyButton.MouseLeave(var Message: TMessage);
begin
  inherited MouseLeave(Message);
  if assigned(fOnMouseLeave) then fOnMouseLeave(self);
end;

end.
Everyone has a right to my opinion.
E-mail me at cwcon@programmer.net
 
By the way TealWren
(or whoever understands the problem he sees),

Why are you not sure the CM_MouseEnter and CM_MouseLeave
effect will work? They work perfectly for a fixed function-
ality, so why shouldnt it work with this?

BobbaFet Everyone has a right to my opinion.
E-mail me at cwcon@programmer.net
 
I just remembered a funny thing...

Why dont just use the standard PopupMenu property in the button, and execute the popupmenu when entering the button, then you doesnt have to create and destroy a popupmenu.

Something like this:

// When mouse enter, this procedure will be executed
procedure TmyButton.CMMouseEnter(var Message: TMessage);
begin
inherited;
if assigned(PopupMenu) then PopupMenu.Popup(10, 10);
end;



The standard function of the popup menu is that it doesn't disappear when leaving the component, it will disappear when klicking another object such as the Form or another button...
 
Bobbafet,

CM_MOUSEENTER and CM_MOUSELEAVE are declared in controls.pas so you need to add controls to your uses clause after the interface directive.

Why are you not sure the CM_MouseEnter and CM_MouseLeave effect will work? They work perfectly for a fixed functionality, so why shouldnt it work with this?

I'm not sure it will work because a base class (TObject?) has functions which capture those mouse messages, so I'm not sure if they'll get to your control. You can't override the functions they have because they aren't virtual. It's certainly worth a try though! Don't let my worries stop you! :)

TealWren
 
Hi TealWren,

If they do not work what would you try to get it to work?
I thought my reasoning was pretty logical.

BobbaFet Everyone has a right to my opinion.
E-mail me at cwcon@programmer.net
 
Did it not work? Rats! I'm not sure what I would try next.


TealWren
 
It needed a little bit of help, but I compiled it and it works!!


unit mybutton;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls;
type
TmyButton = class(TButton)
private
fOnMouseEnter: TNotifyEvent;
fOnMouseLeave: TNotifyEvent;
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
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', [TmyButton]);
end;
{ TmyButton }
// When mouse enter, this procedure will be executed
procedure TmyButton.CMMouseEnter(var Message: TMessage);
begin
if assigned(fOnMouseEnter) then fOnMouseEnter(self);
end;
// When mouse exit, this procedure will be executed
procedure TmyButton.CMMouseLeave(var Message: TMessage);
begin
if assigned(fOnMouseLeave) then fOnMouseLeave(self);
end;
end.
TealWren
 
Hi TealWren,

Thank you for the great help you have given me.
I owe you one.

BobbaFet

Everyone has a right to my opinion.
E-mail me at cwcon@programmer.net
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top