Solved

What TStatusPanel clicked in TStatusBar

Posted on 1998-05-29
13
419 Views
Last Modified: 2010-04-06
When a user double clicks on a Tstatusbar is there an easy way of knowing what TStatusPanel they clicked on? That way one could essentially assign OnDoubleClick events, etc, to each TStatusBar by checking what TSatusPanel they clicked first. This would seem to be the downside of TStatusBar, a reason to stick using groups of panels. Thanks, Tom.
0
Comment
Question by:tomcorcoran
[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
  • 6
  • 4
  • 3
13 Comments
 
LVL 1

Expert Comment

by:Edo082297
ID: 1349215
Hi Tom,
  Here is a way to know what panel the user clicked on. What we do is to check the X coordinate OnMouseDown and then we add up the width of each panel until we know what panel the X coordinate falls into. This is not great code, however. You really should derive a new component for what you want to do.
   I leave it up to you to implement the same thing for the double click event and the like. If you have any questions, I will be glad to help you further.

HTH

Edo

procedure TForm1.StatusBar1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  i, j, WidthIndex : integer;
begin

  for i := 0 to (StatusBar1.Panels.Count - 1) do
  begin
    WidthIndex := 0;

    for j := 0 to i do
      WidthIndex := (WidthIndex + StatusBar1.Panels.Items[j].Width);

    if X <= WidthIndex then
    begin
      showmessage ('You clicked panel ' + IntToStr(i));
      Break;
    end;
  end;
end;
0
 
LVL 1

Expert Comment

by:Edo082297
ID: 1349216
You had better cut and paste the above code, this font does not differentiate between i and j very much!
0
 

Author Comment

by:tomcorcoran
ID: 1349217
This system frustrates me, I'd like to be able to award points and leave it open...

Sorry, I should have said that I had considered a solution like this and was wondering if there was a sweeter way.

Thanks, Tom.
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!

 
LVL 3

Accepted Solution

by:
rickpet earned 50 total points
ID: 1349218
Tom...

There is an easy way to always distinguish one component from another...Inprise (Borland) gave you  a nice property called Tag.
Set each TStatusBar to a unique value.  Then you can write one event handler and

Case (Sender as TStatusBar).Tag of
  0:...
  1:...
  2:...


Rick
0
 

Author Comment

by:tomcorcoran
ID: 1349219
I just finished using tags in creating TMenuItems at run-time for the pages of a TPageControl. Why didn't I think of that. Thanks a lot, Tom.
0
 

Author Comment

by:tomcorcoran
ID: 1349220
I just finished using tags in creating TMenuItems at run-time for the pages of a TPageControl. Why didn't I think of that? Thanks a lot, Tom.
0
 

Author Comment

by:tomcorcoran
ID: 1349221
RickPet. That doesn't work - the TStatusPanel doesn't have a tag property (I assume that was what you meant). How do I reopen the question? Tom.
0
 
LVL 3

Expert Comment

by:rickpet
ID: 1349222
Try this one...Sorry about that...was a sleep on the last one...

Rick

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, TypInfo;

type
  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    procedure StatusBar1DblClick(Sender: TObject);
    procedure StatusBar1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;


implementation
type
{$M+}
   spPanel = (spOne, spTwo, spThree);
{$M-}
var
  Panel: spPanel;
{$R *.DFM}

procedure TForm1.StatusBar1DblClick(Sender: TObject);
begin
  Case Panel of
    spOne: ShowMessage(GetEnumName(TypeInfo(spPanel), ord(spOne)));
    spTwo: ShowMessage(GetEnumName(TypeInfo(spPanel), ord(spTwo)));
    spThree: ShowMessage(GetEnumName(TypeInfo(spPanel), ord(spThree)));
  end;
end;

procedure TForm1.StatusBar1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  i, inStart: integer;
begin
  inStart := 0;
  Panel := spOne;
  for i := 0 to ord(high(spPanel))-1 do
    begin
      if (X >= instart) and (X <= instart + StatusBar1.Panels.items[i].Width) then
        exit
      else
      begin
        inc(Panel);
        instart := instart + StatusBar1.Panels.items[i].Width;
      end;
    end;
end;

end.
0
 
LVL 1

Expert Comment

by:Edo082297
ID: 1349223
I am disappointed.  
  RickPet's answer is a complex and worse version of exactly what I already posted. I don't think there is any advantage to the code either, other than confounding the sorry programmer who has to modify that code. Additionally, what if there are more than 3 panels? You had better write a case statement with at least 10 panels. (Oh no! The requirements changed). My solution works with ANY number of panels, and additionally doesn't require bizarre declarations.
  Sorry to be a party pooper.

Edo
0
 

Author Comment

by:tomcorcoran
ID: 1349224
Yes, it seems like there is no elegant solution. Unfortunaelty through the limits of this system this question is now closed. Tom.
0
 
LVL 3

Expert Comment

by:rickpet
ID: 1349225
actually I find it easier to code than
having to modify...an array of panels or some other solution...it works very similar to the tag value.  Basically on the mouse down you are assigning a value like the tag value.

I use something similar when working with TPageControls.  Because now I know what the link is between my Panels.  I'll I have to do is keep the enumerated types in the correct order(A very simple and intuitive process).  At anytime that I change the panels.  I'll I have to modify is  the enumerated types, and any new panels that I may want to add code for...Actually if you want to be serious your solution would be more of a headache to upkeep.  Evertime I want to add a panel I would have to check out where it is in the list and add the code...If I had to reorder the panels I would have to reorder all my code...With my solution I'll you have to do is reorder the enumerated types if the panel order changes or add any adition code for the panel for any new enumerations.

Also your's doesn't work with double click...mine does...and yours can't be expanded without a major hack...mine will easily port over to a click or any other mouse event...

Note...you don't need the {$M+} or getEnumName...that was just added to show that you can easily get the enumerated string names if you want them...

Rick
0
 

Author Comment

by:tomcorcoran
ID: 1349226
Rick, Thanks for taking the time. At the moment there is no real reason for me to change my multi TPanel implementatio I think. Tom.
0
 
LVL 1

Expert Comment

by:Edo082297
ID: 1349227
>"...Evertime I want to add a panel I would have to check out >where it is in the list and add the code..." :

Instead of the line that reads:
showmessage ('You clicked panel ' + IntToStr(i));

Put:
  DispatchAMethod(i : integer);
 
  Dispatch whatever you want for the first, second, or nth panel.

or:
  case i of
    1 : Panel1Method;
    2 : Panel2Method;
  end;

This is the same difference.


"Also your's doesn't work with double click...mine does...":

Yours doesn't work with single click. (...Sorry about that...was a sleep on the last one... ). For EITHER case, any two year old can select the same event handler (click) for the OnDoubleClick event.

"...and yours can't be expanded without a major hack...":

Are you joking? Your way is tied to a particular number of panels. Mine isn't. You have to declare a new enumerated type. (An enumerated type? To find out what panel was clicked?) Your method involves 26 lines of head scratching code versus 17 obvious lines. It does the job: what TStatusPanel was clicked on? After that it is up to the user to do what he will.

Think about it: if you were going to write a component, wouldn't you expose a PanelNumber property, and in a descended OnClick provide the user with the PanelNumber as part of the procedure's signature, to do what they will?

And you wanted to use the (absent) tag property? The tag property is akin to goto statement. There is nothing that tag can accomplish better than solid code.

End of discussion.

My email address is egarson@hotmail.com if you would like to discuss this any further (I am always interested in discussing style). I will not be returning to this thread.

Edo
0

Featured Post

Independent Software Vendors: 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!

Question has a verified solution.

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

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
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…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

710 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