Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 11-08-2005
amadis amadis is offline
Miembro
 
Registrado: may 2005
Ubicación: San José, Colón, Entre Ríos, Argentina
Posts: 315
Poder: 19
amadis Va por buen camino
Question CONTROL+TAB en PAGECONTROL dentro de MDI-CHILD

CONTROL+TAB en PAGECONTROL dentro de MDI-CHILD

El titulo lo dice todo!

Deseo utilizar CONTROL+TAB en un PAGECONTROL que está dentro de MDI-CHILD y en lugar de cambiar de tabsheet cambia se mdi activo (en el caso de que haya 2 mdi creado sino no hace nada)

No he visto nada en el foro sobre esto!

Pero he encontrado un trozo de codigo que no comprendí y no pude usar que segun dice sirve para solucionar mi problema!

Les agradeceria su ayuda
------------------------------------------------------------------------
To get around this one needs to intervene before IsMDIMsg is even called. There is only one opportunity to do this: the Application.OnMessage event. So add a handler for the main form OnCreate event, and add a private method to the form called AppMessage:


Código Delphi [-]

procedure TMainForm.FormCreate(Sender: TObject);
begin
  Application.OnMessage := AppMessage;
end;

procedure TMainform.Appmessage(var Msg: TMsg; var Handled: Boolean);
var
  message: TWMKey;
begin
  if (msg.message = WM_KEYDOWN) and (LoWord(msg.wparam) = VK_TAB) and
    (GetKeyState(VK_CONTROL) < 0) and Assigned(ActiveMDIChild) then
  begin
    Move(msg.message, message.msg, 3 * sizeof(Cardinal));
    message.result := 0;
    Handled := ActiveMDIChild.IsShortcut(message);
  end;
end;

This will redirect Ctrl+Tab (and Ctrl+Shift+Tab) to the active MDI childs IsShortcut function. This fires the OnShortcut event, so we can use that event on the child form to further handle the key event:

Código Delphi [-]
function IsOnTabsheet(aControl: TWinControl; var pc: TPageControl): Boolean;
begin
  while Assigned(aControl) and not (aControl is TTabsheet) do
    aControl := aControl.Parent;
  Result := Assigned(aControl);
  if result then
    pc := TTabSheet(aControl).Pagecontrol;
end;

procedure TMDIChild.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
var
  pc: TPageControl;
begin
  if (msg.CharCode = VK_TAB) and (GetKeyState(VK_CONTROL) < 0) then
  begin
    if IsOnTabsheet(ActiveControl, pc) then
    begin
      pc.Perform(CM_DIALOGKEY, msg.CharCode, 0);
      Handled := true;
    end;
  end;
end;

Desde ya Gracias
Responder Con Cita
  #2  
Antiguo 11-08-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
No cabe duda que Peter Below (autor del código que pones) es genial.

No entiendo bien del todo su código pero vamos a intentarlo.

Toda aplicación consiste básicamente de un ciclo:

Código:
repeat
  obtener_mensaje(msg)
  procesar_mensaje(msg)
end
Los mensajes, sean del ratón, del teclado, etc. se van colocando en una cola de mensajes para la aplicación y se van procesando conforme llegan a esta cola.

Según lo que explica Peter Below, procesar_mensaje() lo primero que hace (en una aplicación MDI) es llamar a la función IsMDIMsg que determina si el mensaje es especial para ventanas MDI. En el caso de Ctrl-Tab así es y el mensaje se transforma para hacer el cambio de ventana hija de manera que el mensaje original nunca llega al formulario activo. (Si el mensaje no es MDI entonces el mensaje se redirige al formulario activo)

Tal como él dice, hay un único punto donde se puede interceptar esto y es en el evento OnMessage de una componente TApplicationEvents. Dependiendo de la versión que uses de Delphi, es posible que no dispongas de tal componente. En tal caso procedes como él lo hace asignando el evento al objeto Application en el constructor del formulario principal.

En este evento, él detecta cuando el mensaje corresponde a Ctrl-Tab.

Ahora bien, el parámetro Handled del evento se usa para indicar a la VCL si ha de dejar que el mensaje siga su ruta normal o no. Prueba poniendo Handled := true sin más y verás que el efecto del Ctrl-Tab se deshabilita por completo.

Claro que esto no es lo que quieres pues no sólo evitas que se cambie la ventana activa sino que también inhabilitas el cambio de pestaña.

Lo que Peter Below hace es redirigir el mensaje al evento OnShortCut del formulario activo (la llamada a IsShortCut genera dicho evento).

Si no hay evento asignado IsShortCut devolverá false por lo que el valor de Handled en el evento OnMessage será false y el mensaje proseguirá su ruta normal. De esta forma logra que si se está en cualquier otro formulario, el cambio de ventana activa aún sea posible.

En el formulario con el PageControl debes colocar el evento OnShortcut. En este evento, Peter Below determina si estás parado sobre el PageControl (función IsOnTabSheet). Si no lo estás pone el valor de Handled en false. Aquí Handled es similar al del evento OnMessage y será lo que devuelva la función IsShortCut llamada allá de manera que el Handled de OnMessage será false indicando que se siga la ruta normal y se cambia la ventana activa.

Pero si sí estás parado sobre el PageControl, el código de Peter Below hace el cambio de pestaña (Perform(CM_DIALOGKEY...)) y pone Handled en true que a su vez hará que IsShortCut regrese true y por tanto el Handled de OnMessage sea true indicando que se deje de procesar el mensaje y evitando así el cambio de ventana activa.

// Saludos

Última edición por roman fecha: 11-08-2005 a las 07:54:39.
Responder Con Cita
  #3  
Antiguo 11-08-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Revisando un poco más a fondo el código creo que lo puedes reducir.

En el evento OnMessage simplemente pones:

Código Delphi [-]
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
begin
  if
    (Msg.message = WM_KEYDOWN) and (LoWord(Msg.wparam) = VK_TAB) and
    (GetKeyState(VK_CONTROL) < 0) and Assigned(ActiveMDIChild)
  then
  begin
    Handled := Boolean(ActiveMDIChild.Perform(CM_DIALOGKEY, Msg.wParam, Msg.lParam));
  end;
end;

y ya no haces uso ni de la función IsOnTabSheet ni del evento OnShortCut del formulario con el PageControl.

// Saludos
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 16:37:45.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi