Ver Mensaje Individual
  #6  
Antiguo 11-11-2005
fdelamo fdelamo is offline
Miembro
 
Registrado: oct 2005
Ubicación: Sotoca de Tajo - Guadalajara (ESP)
Posts: 86
Reputación: 21
fdelamo Va por buen camino
¿Solución encontrada?

Hola a todos,

Creo que he encontardo una solución, aunque seguramente no sea la mejor, ya que lo he hecho por medio de hooks.

Lo que hago es crear un hook de teclado, para capturar las teclas pulsadas.

Os explico con el código:

Variables que me hacen falta, yo las he puesto globales en la unidad
Código Delphi [-]
var
  HookKbd: HHook; //Identificador del Hook creado
  EsSegundaVez: Boolean; //Para solo procesarlo una vez, el caso es que para
                         //cade tecla lo captura dos veces ¿el Down y el Up?

En la parte del Create del componente:
Código Delphi [-]
  HookKbd := 0; //Inicializamos
  //Con el IDE da un error y cierra el programa y el IDE ¿por que?
  if not((FindWindow('TAppBuilder',nil) > 0) and
     (FindWindow('TPropertyInspector',nil) > 0) and
     (FindWindow('TAlignPalette',nil) > 0)) then
  begin
    //Comprobamos la version de windows (en 98 no tira)
    Version.dwOSVersionInfoSize:=SizeOf(Version);
    GetVersionex(Version);
    if Version.dwPlatformId <> VER_PLATFORM_WIN32_WINDOWS then
    begin
      //Creamos el Hook
      HookKbd := SetWindowsHookEx(WH_KEYBOARD, @KbdHook, HInstance, 0);
      EsSegundaVez := False; //Inicializacion
    end;
  end;

En el destroy del componente:

Código Delphi [-]
 
  //Liberamos el Hook
  if HookKbd <> 0 then UnhookWindowsHookEx(HookKbd);

y la función KbdHook:

Código Delphi [-]
 
function KbdHook(Code: Integer; WParam, LParam: DWORD): HHook;
var
  tmpClase: array[0..30] of Char; //Aqui guardaremos el nombre de la clase 
                                  //del control que tiene el foco
begin
  //Averiguamos el nombre de la clase del control que tiene el foco
  GetClassName(GetFocus, tmpClase, 30);

  //Controlamos que no esté pulsado el ALT o CONTROL
  //Que el foco esté en un control de la clase del Grid ('TMiGrid')
  //Y que se pulse un caracter alfanumérico
  if ((HiWord(GetKeyState(VK_MENU)) = 0) and
     (HiWord(GetKeyState(VK_CONTROL)) = 0) and
     (tmpClase = 'TMiGrid') and
     (Chr(WParam) in ['A'..'Z', '0'..'9', 'Ñ', 'ñ'])) then
  begin
    //No se exactamente por qué, pero cada caracter lo capta dos veces
    if EsSegundaVez then
    begin
      EsSegundaVez := False;
      Result := 1; //Si ponemos 0, sigue ejecutando el siguiente hook (por lo menos el del shortcut del botón)
      Exit;
    end;
    EsSegundaVez := True;
    //Mandamos el mensaje del KeyDown al control que tiene el foco
    //Este ya no lo captura el shortcut del boton
    SendMessage(GetFocus, WM_KEYDOWN, WParam, LParam);
    Result := 1; //Si ponemos 0, sigue ejecutando el siguiente hook (por lo menos el del shortcut del botón)
  end
  else
  begin
    //Llamamos al siguiente Hook, es decir no hacemos nada
    Result := CallNextHookEx(HookKbd, Code, wParam, lParam);
  end;
end;

Y eso es todo, seguramente el código se puede mejorar (por ejemplo solo crear un Hook independientemente de los controles que haya), pero es un primer intento.

Por mi parte nada más, sólo que si tenéis alguna sugerencia, duda o comentario aquí estoy.

Un saludo,

Kiko
Responder Con Cita