PDA

Ver la Versión Completa : como usar el BalloonTip


lmpadron
23-02-2012, 18:18:37
Hola amigos

en este post (http://www.clubdelphi.com/foros/newreply.php?do=newreply&p=425897) Chris me indica que use BalloonTip en ves de mensajes de dialogo y realmente cuando lo piensas tiene toda la razón, como ese post se había abierto por otra razón entonces abro este con la siguiente pregunta

Como uso el BalloonTip en c++ builder ? :confused::confused::confused::confused:

Busque en internet y no encontré mucho excepto algunos ejemplo de como implementarlo sobre el TryIcon y aquí en el club no hay ningún post en c++ que trate el tema. Chris posteo un ejemplo pero esta escrito en Delphi y no he podido encontrar la forma de hacerlo en c++.

Este sería el código Delphi para implementar lo que te digo:

procedure Form1.Edit1OnKeyPress(var Key: Char);
var
BalloonTip: _tagEDITBALLOONTIP;
begin
if (B > C) then
begin
Key := 0; // no aceptar el caracter ingresado

// mostrar un mensaje sutíl al usuario
// indicandole que el problema.
BalloonTip.cbStruct := SizeOf(BalloonTip);
BalloonTip.pszTitle := 'B es mayor que C';
BalloonTip.pszText := 'TODO: EXPLICAR POR QUE B NO PUEDE SER MAYOR QUE C';
BalloonTip.ttiIcon := 4;

SendMessage(Edit1.Handle,
EM_SHOWBALLOONTIP,
0,
Integer(@BalloonTip));
end;
end;


Tienes que agregar a la sección uses la unidad CommCtrl para hacer uso de los BalloonTips de Windows.

¿Alguien que pueda traducir este código?

Saludos!


Gracias de antemano por su ayuda

Chris
23-02-2012, 20:19:37
Puedes consultar este hilo en CodeGuru http://www.codeguru.com/forum/showthread.php?t=478992 está en inglés.

Además, la API de Windows tiene un macro llamado Edit_ShowBalloonTip. Lee la documentación oficial. Talvez te ayuda a realizarla http://msdn.microsoft.com/en-us/library/windows/desktop/bb761707(v=vs.85).aspx

Saludos!

ecfisa
23-02-2012, 20:41:20
Hola Impadron.

No he usado los BalloonTip ni en Delphi ni en Builder C++. La primera traducción que intenté no me resultó:

typedef struct tagEDITBALLOONTIP {
DWORD cbStruct;
LPCWSTR pszTitle;
LPCWSTR pszText;
INT ttiIcon;
} EDITBALLOONTIP, *PEDITBALLOONTIP;

void __fastcall TForm1::Button1Click(TObject *Sender) {
EDITBALLOONTIP ebt;
ebt.cbStruct = sizeof(EDITBALLOONTIP);
ebt.pszTitle = (wchar_t *)"B es mayor que C";
ebt.pszText = (wchar_t *)"TODO: EXPLICAR POR QUE B NO PUEDE SER MAYOR QUE C";
ebt.ttiIcon = TTI_INFO;
SendMessage(Edit1->Handle, EM_SHOWBALLOONTIP, 0, (LPARAM) &ebt);
}

Sin embargo, de este modo logré el efecto:


void ShowBalloonTip(TWinControl *Control,int Icon, char *Title, char *Text,
TColor BackColor, TColor TextColor) {
HWND hWndTip;
TOOLINFO ti;
HWND hWnd;
TPoint p;
p.x = Control->Left + Control->Width - 5;
p.y = Control->Top + 5;
Mouse->CursorPos = Control->Parent->ClientToScreen(p);
hWnd = Control->Handle;
hWndTip = CreateWindow(TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX |
TTS_BALLOON | TTS_ALWAYSTIP, 0, 0, 0, 0, hWnd, 0, HInstance, NULL);
if( hWndTip ) {
SetWindowPos(hWndTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE |
SWP_NOMOVE | SWP_NOSIZE);
ti.cbSize = sizeof(ti);
ti.uFlags = TTF_CENTERTIP | TTF_TRANSPARENT | TTF_SUBCLASS;
ti.hwnd = hWnd;
ti.lpszText = Text;
GetClientRect(hWnd, &ti.rect);
SendMessage(hWndTip, TTM_SETTIPBKCOLOR, BackColor, 0);
SendMessage(hWndTip, TTM_SETTIPTEXTCOLOR, TextColor, 0);
SendMessage(hWndTip, TTM_ADDTOOL, 1, (int) &ti);
SendMessage(hWndTip, TTM_SETTITLE, Icon % 4, (int)Title);
}
}

void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key) {
if (Key < '0' || Key > '5') { // evaluación trivial
ShowBalloonTip(Edit1, 1, "ERROR", "Sólo números del 0 al 5", clYellow, clBlack);
Key = 0;
}
}
...

Aunque dada mi inexperiencia con los BalloonTip, seguramente te darán una mejor propuesta. ;)

Saludos.

roman
23-02-2012, 20:55:31
en este post (http://www.clubdelphi.com/foros/newreply.php?do=newreply&p=425897) Chris me indica que use BalloonTip en ves de mensajes de dialogo y realmente cuando lo piensas tiene toda la razón, como ese post se había abierto por otra razón entonces abro este con la siguiente pregunta

A ver, yo no entiendo. De por sí los globitos me parecen un recurso horroroso y no sé por qué quieres cotejar lo que se escribe contra un valor en cada tecla que se oprime. ¿Por qué no simplemente dejas que el usuario introduzca el número, apriete un botón y si no cumple los requisitos le presentas un cuadro modal. Sí, modal. Los cuadros modales tienen su razón de ser: evitar que se pueda hacer otra cosa hasta no cumplirse otra: en este caso, parar el proceso hasta que no se tenga un valor correcto.

A menos, claro, que el valor no tenga importancia, y el proceso pueda seguir sin estar correcto.

Por otra parte, aún suponiendo que de verdad necesitas cotejar mientras se escribe, basta que pongas un Label a un lado del Edit con una pequeña indicación mientras no se cumpla el requisito:


[ 84] (el valor es mayor que 10)


// Saludos

Chris
23-02-2012, 21:17:17
A ver, yo no entiendo. De por sí los globitos me parecen un recurso horroroso y no sé por qué quieres cotejar lo que se escribe contra un valor en cada tecla que se oprime. ¿Por qué no simplemente dejas que el usuario introduzca el número, apriete un botón y si no cumple los requisitos le presentas un cuadro modal. Sí, modal. Los cuadros modales tienen su razón de ser: evitar que se pueda hacer otra cosa hasta no cumplirse otra: en este caso, parar el proceso hasta que no se tenga un valor correcto.

El problema de los cuadros Modales es que requieren de la Intervención del Usuario. Por lo menos hacer clic sobre "OK", apretar Alt+F4, apretar Esc o tirar la computadora por la ventana :p. Los BalloonTips no requiren ese tipo de interacción, por lo cual son menos intrusivos. Igual, al asignar Key := 0 en el evento OnkeyPress ya no deja al usuario continuar cuando algo está mal.

Mostrar un BalloonTip sobre el campo que está dando el problema y en el momento que se da el problema es como cuando te registras en un servicio web y el campo de "nombre de usario" te dice si ese nombre está disponible mientras lo vas escribiendo. Es algo mucho más usable y amigable con el usuario. ¿No te parecería incomodo un formulario de varias páginas, que al completar la última te diga que dejaste algo mal colocado en la primera?

Otro de los problemas con los MessageBox es que los usuarios no los leen.

Saludos!

roman
23-02-2012, 21:45:48
El problema de los cuadros Modales es que requieren de la Intervención del Usuario.

Pero es que esto no es un problema sino una característica. Justamente para eso están, para requerir la intervención del usuario.


Mostrar un BalloonTip sobre el campo que está dando el problema y en el momento que se da el problema es como cuando te registras en un servicio web y el campo de "nombre de usario" te dice si ese nombre está disponible mientras lo vas escribiendo.


Es una opción, pero yo en particular no usaría un globo.


Es algo mucho más usable y amigable con el usuario. ¿No te parecería incomodo un formulario de varias páginas, que al completar la última te diga que dejaste algo mal colocado en la primera?


Hombre, aquí ya estás hablando de otra cosa. Y, de entrada, quizá el sistema no debió dejarlo avanzar de página, si había datos incorrectos. Pero en aplicaciones de escritorio, no es tan común tener formularios de varias páginas, y si los hay, entonces puedes validar en cada cambio.


Otro de los problemas con los MessageBox es que los usuarios no los leen.


Y, ¿por qué sí habrían de leer los globitos?

Yo creo que aquí estamos más bien hablando de dos estrategias de validación de datos: validar en cada campo o validar todos los campos al final. Y no creo que inherentemente una sea mejor que otra.

Como tú lo propones, creo, sería por ejemplo mantener inhabilitado el botón OK mientras los datos no estén todos correctos. De todas maneras, los globos son demasiado distractores para mi gusto.

// Saludos

lmpadron
23-02-2012, 23:14:13
Sin embargo, de este modo logré el efecto:


Pues de ese modo definitivamente se logra sin problemas

(...) al asignar Key := 0 en el evento OnkeyPress ya no deja al usuario continuar cuando algo está mal.(...)


Esa es exactamente la idea, solucionar el problema sin necesidad de la interacción del usuario, salvo la notificacion del globito.


Yo creo que aquí estamos más bien hablando de dos estrategias de validación de datos: validar en cada campo o validar todos los campos al final.


Si definitivamente es así y dado este caso prefiero validar en el momento.

muchas gracias a todos por su ayuda

jorosmtz
19-03-2012, 04:15:48
Pues hablando del tema, estoy usando "globitos" (perdón Roman, jeje, a mi si me parecen más estéticos en esta aplicación que estoy haciendo, aunque no para todos los casos).

Mi problema es que cuando en el OnKeyPress pongo la instruccion


if not (key in ['0'..'9'] + ['.'] + [','] + [#8]) then
begin
BalloonHint.ShowHint;
Key := #0;
end;


Mi problema principal es que el "globito" sale en la parte superior izquiera de la pantalla, y no sobre el edit sobre el que estoy ejecutando el ShowHint.

¿Alguna idea de como hacerle para que aparezca sobre el componente Edit?

Gracias.

Chris
19-03-2012, 17:59:28
No sé de dónde viene ni que hace `BalloonHint.ShowHint´. El código de ese procedimiento es el que hay que depurar. Por otro lado, has probado el código que me citan al inicio de este hilo?

Saludos!

jorosmtz
22-03-2012, 03:35:32
BalloonHint.ShowHint hace que, en ese caso pasrticular, el globito aparezca cuando se teclea otra cosa que no sea un número, un punto, una compa o la tecla retroceso, y funciona, pero no como espero, ya que el globito aparece en la parte superior izquierda de la pantalla.

A tu otra pregunta, no, no he probado el código, lo voy a hacer y luego posteo aquí, tengo que hacer algo por el momento más importante :D

escafandra
22-03-2012, 08:07:02
Cuando Chris pregunta por el significado de BalloonHint.ShowHint lo está haciendo pensando que usas algún componente o clase (TBalloonHint por ejemplo) que no mencionas. No siendo API y no conociendo dicho componente o clase, no se te puede contestar. Lee la documentación de ese componente o clase.


Saludos.

beginner01
22-03-2012, 14:11:41
BalloonHint.ShowHint hace que, en ese caso pasrticular, el globito aparezca cuando se teclea otra cosa que no sea un número, un punto, una compa o la tecla retroceso, y funciona, pero no como espero, ya que el globito aparece en la parte superior izquierda de la pantalla.

A tu otra pregunta, no, no he probado el código, lo voy a hacer y luego posteo aquí, tengo que hacer algo por el momento más importante :D

Hola.

Asumiendo que es un componente TBalloonHint te puedo decir que en la llamada a BalloonHint.ShowHint puedes pasar como parámetro el punto donde quieres que se muestre "Parámetro de tipo Tpoint".
Ej.



procedure TForm1.btn1Click(Sender: TObject);
begin
BalloonHint1.ShowHint(TButton(Sender).ClientOrigin);
end;