PDA

Ver la Versión Completa : Click en statusbar


Novás
21-09-2006, 15:16:01
Hola a todos de nuevo:

Se que la pregunta que voy a hacer es un poco "chorra" pero no encuentro solución... Quisiera saber como puedo saber en que panel del statusbar se hace click en un momento determinado para que, al hacer click en un panel determinado, salte un procedimiento.

Muchas gracias de antemano

seoane
21-09-2006, 15:55:01
Puede que exista un método mas sencillo, pero ahora mismo lo que se me ocurre es lo siguiente. En le evento OnMouseUp colocar esto:


uses CommCtrl; // Añade esto a las uses

procedure TForm1.StatusBar1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
i: Integer;
R: TRect;
begin
// Buscamos panel a panel hasta encontrar cual se ha pulsado
with (Sender as TStatusBar) do
for i:= 0 to Panels.Count - 1 do
begin
// Obtenemos las dimensiones del panel
SendMessage(Handle,SB_GETRECT,i,Integer(@R));
// Y comprobamos si se ha hecho click dentro de el
if PtInRect(R,Point(x,y)) then
begin
// El numero del panel esta en i, usalo para lo que quieras
ShowMessage('Has pulsado el panel: ' + IntToStr(i));
Exit;
end;
end;
end;

Bicho
21-09-2006, 15:55:17
Hola, quizá no sea tan chorra la pregunta. Yo al menos no lo he conseguido.

Yo lo que uso es lo siguiente:
- Los panels tienen una anchura definida y fija.
- El evento OnMouseDown te da la posición X e Y relativa al StatusBar donde se ha hecho en click.

Yo normalmente gestiono el primer panel para ejecutar eventos, así que aquí te dejo un ejemplo como el que uso.


procedure TForm1.StatusBar1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if x <= StatusBar1.panels[0].Width then begin
.... hacemos lo que queramos
end;
end;



Si la X es mayor que la anchura del Panel 0 pues pertenece a otro panel y habría que hacer la comprobación, y no sería mucho más complicado.

Espero te sirva.

Saludos

Novás
21-09-2006, 16:46:27
Muchas gracias a los dos, he tenido que optar por la solución de Bicho ya que la de Seone me da un error en

if PtInRect(R,Point(x,y)) then


algo con la coma dentro del Point.

seoane
21-09-2006, 16:54:36
Muchas gracias a los dos, he tenido que optar por la solución de Bicho ya que la de Seone me da un error en

if PtInRect(R,Point(x,y)) then

algo con la coma dentro del Point.


:confused: ¿Exactamente que error te da?. Según la definición de la función Point no debería de haber ningún problema siempre que X e Y fueran integer.


function Point(AX, AY: Integer): TPoint;

movorack
28-05-2008, 23:36:51
Yo tambien tengo la misma duda.... y vi el codigo de seoane, me pareció muy chevere, traté de hacer una función


function TFrmMain.GetStatusBarPanelClicked(StatusBar : TStatusBar; X, Y: Integer) : Integer;
var
i: Integer;
R: TRect;
begin
// Buscamos panel a panel hasta encontrar cual se ha pulsado
with StatusBar do
for i:= 0 to Panels.Count - 1 do
begin
// Obtenemos las dimensiones del panel
SendMessage(Handle,SB_GETRECT,i,Integer(@R));
if PtInRect(R,Point(x,y)) then
begin
Result := i;
Exit;
end else Result := -1;
end;
end;


pero al compilar me lanza este error:

[Error] FrmMainSrc.pas(281): Undeclared identifier: 'SB_GETRECT'


He añadido ComCtrls a los uses y buscando en la ayuda Windows SDK entiendo que este mensaje me devuelve el rectangulo del panel... pero hasta ahi... no se que corregir, añadir o lo que sea para compilar satisfactoriamente...

saludos...

el otro codigo (el de bicho) funciona tambien pero me da cosa cuando algo que a alguien le sale bien a mi me sale mal.

seoane
29-05-2008, 22:30:58
Prueba cambiando SB_GETRECT por WM_USER + 10


procedure TForm1.StatusBar1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
i: Integer;
R: TRect;
begin
// Buscamos panel a panel hasta encontrar cual se ha pulsado
with (Sender as TStatusBar) do
for i:= 0 to Panels.Count - 1 do
begin
// Obtenemos las dimensiones del panel
SendMessage(Handle,WM_USER + 10,i,Integer(@R));
// Y comprobamos si se ha hecho click dentro de el
if PtInRect(R,Point(x,y)) then
begin
// El numero del panel esta en i, usalo para lo que quieras
ShowMessage('Has pulsado el panel: ' + IntToStr(i));
Exit;
end;
end;
end;

movorack
29-05-2008, 23:29:10
Gracias de verdad, tu dato es muy útil...

la función entonces quedó así


function TForm.GetStatusBarPanelClicked(StatusBar : TStatusBar; X, Y: Integer) : Integer;
var
i: Integer;
R: TRect;
begin
// Buscamos panel a panel hasta encontrar cual se ha pulsado
with StatusBar do
for i:= 0 to Panels.Count - 1 do
begin
// Obtenemos las dimensiones del panel
SendMessage(Handle,WM_USER + 10,i,Integer(@R));
if PtInRect(R,Point(x,y)) then
begin
Result := i;
Exit;
end else Result := -1;
end;
end;


Y para llamarla, dentro del procedimiento así:


procedure TForm.StatusBarMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
case GetStatusBarPanelClicked(TSTatusBar(Sender), X, Y) of
2 : //aquí ejecutamos algo;
end;
end;


Lo he probado también con el MouseMove y funciona de pelos... además no importa si uso la TSTatusBar o un descendiente.

Nuevamente gracias.

movorack
29-05-2008, 23:39:10
El de bicho lo había hecho así...


function TForm.GetStatusBarPanelClicked(StatusBar : TStatusBar; X, Y: Integer) : Integer;
var i, PanelWidthSum : integer;
begin
PanelWidthSum := 0;
for i := 0 to StatusBar.Panels.Count - 1 do
begin
if (x >= PanelWidthSum) and (x <= PanelWidthSum+StatusBar.Panels[i].Width) then
begin
Result := i;
exit;
end else
Inc(PanelWidthSum, StatusBar.Panels[i].Width);
end;

Result := -1;
end;


Hago la salvedad que usando cualquiera de los dos códigos; NO tienes que agregar nada a Uses... :D El mismo compilador lo hace :D