Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Desactivar teclas de función en todo el sistema (https://www.clubdelphi.com/foros/showthread.php?t=96769)

buenarquero 30-06-2024 02:11:44

Desactivar teclas de función en todo el sistema
 
Tengo una aplicación en la que necesito desactivar algunas teclas de función, para que no produzcan ningún efecto en otra aplicación externa, de uso y distribución gratuitos, que ejecuto desde mi aplicación y muestro dentro de la ventana principal de ésta, con el objeto de que el usuario no pueda acceder a determinadas funciones de dicha aplicación a través del teclado (creo que me he explicado bien, si no decidmelo). He probado con hooks para interceptar las pulsaciones de dichas teclas de función a nivel de sistema, pero, no se por qué, solo funcionan si el foco está en mi aplicación, con lo cual no me sirve para nada (no se si el código que encontré no estaba correcto o yo lo hice mal, pero creo que lo hice bien). He buscado y rebuscado en otros hilos y no he encontrado más que los susodichos hooks y una función que desactiva todo el teclado y el ratón, lo cual no me sirve. A ver si alguien puede ayudarme con esto. ¡Gracias de antemano! Aviso que no soy un programador experto sino solo aficionado.

Casimiro Notevi 30-06-2024 13:42:09

O sea, quieres que desde tu programa desactivar las teclas de función de otro programa que no es tuyo ni tienes el código, ¿es eso?

Neftali [Germán.Estévez] 01-07-2024 10:10:09

Cita:

Empezado por buenarquero (Mensaje 556464)
Tengo una aplicación en la que necesito desactivar algunas teclas de función, para que no produzcan ningún efecto en otra aplicación externa, de uso y distribución gratuitos, que ejecuto desde mi aplicación y muestro dentro de la ventana principal de ésta, con el objeto de que el usuario no pueda acceder a determinadas funciones de dicha aplicación a través del teclado

Este comportamiento es a todas luces "raro".
No da muchos detalles de las 2 aplicaciones, ni de qué teclas quieres desactivar.
Tampoco explicas qué código has utilizado "que no te funciona".

Cita:

Empezado por buenarquero (Mensaje 556464)
He probado con hooks para interceptar las pulsaciones de dichas teclas de función a nivel de sistema, pero, no se por qué, solo funcionan si el foco está en mi aplicación, con lo cual no me sirve para nada (no se si el código que encontré no estaba correcto o yo lo hice mal, pero creo que lo hice bien). He buscado y rebuscado en otros hilos y no he encontrado más que los susodichos hooks y una función que desactiva todo el teclado y el ratón, lo cual no me sirve.


Yo sigo pensando que la solución son los hooks de teclado a nivel de sistema. De otra forma sólo funcionarán cuando tu aplicación esté abierta.
Hay diferentes hilos en los foros que hablan sobre el tema, si buscas encontrarás.
Había hace tiempo un componente de [Roman] que solucionaba esto, y aunque actualmente la web no está disponible, "tirando" de WayBackMachine, se puede acceder a ella.
Revisa este enlace:
https://web.archive.org/web/20050908...m/users/roman/
Y concretamente a este componentes (dentro está la explicación):
https://web.archive.org/web/20050214...oman/hooks.php

buenarquero 01-07-2024 16:28:00

Tienes razón
 
Tienes razón Neftalí, no doy indicaciones de que aplicaciones se trata porque no lo creía necesario. Y en cuanto a lo de raro, te aseguro que no se trata de nada raro, solo incorporo una aplicación de lectura de PDF gratuita a mi aplicación, pero no quiero que el PDF, que es original mío, lo puedan imprimir ni tampoco capturar la pantalla, ni interrumpir el proceso mediante ctrl+alt+supr. Esto último lo solucioné sin hooks de teclado, cerrando mediante un timer, la ventana del administrador de tareas en cuanto esta se abre. Lo de imprimir también mediante la misma técnica, pero hay otra funciones del software gratuito, a las que se accede por menú que aparece al pulsar determinadas teclas de función y que no se pueden bloquear de esta forma, o al menos yo no he podido. Son funciones como la de guardar el PDF, abrirlo con Adobe reader etc..., lo cual le daría paso al usuario a todo lo que quiera hacer con el PDF y que no debe poder hacer, para lo cual, originalmente está incrustado en el ejecutable de mi aplicación. Por eso necesito bloquear algunas o todas las teclas de función (F1 a F12) y que su pulsación no llegue al programa lector de PDF, independientemente de que el foco esté en él o no.

buenarquero 01-07-2024 16:39:29

Enlaces
 
En cuanto a los links que incluyes, el primero no tiene activo el enlace a la parte de hooks y el segundo, parece que solo ofrece solución para determinadas teclas o combinaciones, pero no para las teclas de función, al menos yo veo como se podría adaptar para que sirva para las teclas de función.

buenarquero 01-07-2024 16:52:00

código que usé
 
Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 556472)
Este comportamiento es a todas luces "raro".
No da muchos detalles de las 2 aplicaciones, ni de qué teclas quieres desactivar.
Tampoco explicas qué código has utilizado "que no te funciona".

Yo sigo pensando que la solución son los hooks de teclado a nivel de sistema. De otra forma sólo funcionarán cuando tu aplicación esté abierta.
Hay diferentes hilos en los foros que hablan sobre el tema, si buscas encontrarás.
Había hace tiempo un componente de [Roman] que solucionaba esto, y aunque actualmente la web no está disponible, "tirando" de WayBackMachine, se puede acceder a ella.
Revisa este enlace:
https://web.archive.org/web/20050908...m/users/roman/
Y concretamente a este componentes (dentro está la explicación):
https://web.archive.org/web/20050214...oman/hooks.php


Transcribo el código que usé para los hooks. A ver si lo hago bien porque no lo he hecho nunca y no se si cumplirá las recomendaciones del foro.
El código lo saqué de Trucos Delphi, si no recuerdo mal.

INTERCEPTAR EL TECLADO MEDIANTE HOOKS

Declarar variables

Código Delphi [-]
var    Form1: TForm1;  
KBHook: HHook;
 
function KeyboardHookProc(Code: Integer; WordParam: Word; LongParam: LongInt): LongInt; stdcall;

implementation.

Instalar el Hook

procedure TForm1.FormCreate(Sender: TObject) ;
begin 
KBHook:=SetWindowsHookEx(WH_KEYBOARD,{callback >}@KeyboardHookProc,  HInstance, GetCurrentThreadId()) ;
end;

Función que intercepta el teclado

function KeyboardHookProc(Code: Integer; WordParam: Word; LongParam: LongInt) : LongInt;
begin 
  case WordParam of  
  vk_Left:   begin {Instrucciones a realizar} end;  
  vk_Right:  begin {Instrucciones a realizar} end; 
  vk_Up:     begin {Instrucciones a realizar} end;  
  vk_Down:   begin {Instrucciones a realizar} end;  
  end; 
  Result:=0; { Para evitar que Windows pase las pulsaciones de teclas a la ventana de
  destino, el valor del resultado debe ser un valor distinto de cero.}
end;

Liberar el hook

procedure TForm1.FormDestroy(Sender: TObject) ;
begin  
  UnHookWindowsHookEx(KBHook) ;
end;

lucho6007 01-07-2024 20:55:13

Me parece que es imposible de hacer
 
No termino de entender por qué alguien querría evitar que capturen la pantalla. ¿y si le sacan una foto a la pantalla? ¿y si el software corre virtualizado y hacen captura de pantalla en la PC host? ¿si corren algún software de captura automática de pantalla o de grabación del estilo de OBS? Es imposible enviar que se capture la pantalla, si se muestra, se puede capturar.


Saludos

Casimiro Notevi 02-07-2024 09:13:20

Cita:

Empezado por lucho6007 (Mensaje 556484)
No termino de entender por qué alguien querría evitar que capturen la pantalla. ¿y si le sacan una foto a la pantalla? ¿y si el software corre virtualizado y hacen captura de pantalla en la PC host? ¿si corren algún software de captura automática de pantalla o de grabación del estilo de OBS? Es imposible enviar que se capture la pantalla, si se muestra, se puede capturar.
Saludos

Es así, no vale la pena complicarse tanto.

Neftali [Germán.Estévez] 02-07-2024 09:25:23

Cita:

Empezado por buenarquero (Mensaje 556477)
...solo incorporo una aplicación de lectura de PDF gratuita a mi aplicación, pero no quiero que el PDF, que es original mío, lo puedan imprimir ni tampoco capturar la pantalla, ni interrumpir el proceso mediante ctrl+alt+supr. Esto último lo solucioné sin hooks de teclado, cerrando mediante un timer, la ventana del administrador de tareas en cuanto esta se abre. Lo de imprimir también mediante la misma técnica, pero hay otra funciones del software gratuito, a las que se accede por menú que aparece al pulsar determinadas teclas de función y que no se pueden bloquear de esta forma...

Creo sinceramente que este enfoque no es el adecuado, pero simplemente es una opinión.

Por un lado, porque al final me parece muy difícil (por no decir imposible) poder controlar todas esas opciones. Al final en los sistema actuales (S.O.) hay tantas opciones que le veo agujeros de funcionamiento. Hay aplicaciones de terceros (capturadores de pantalla, administradores de procesos/tareas,...) que pueden sustituir a las originales que no veo forma de bloquearlos. Incluso pueden cambiar las teclas predefinidas para determinadas operaciones, por lo tanto capturar el PRINTPANTALLA o el CTRL+ALT+SUPR tampoco te asegura nada.

Por otro lado, me parece peligroso "bloquear" determinadas teclas que pueden afectar a otros aspectos del sistema, digamos que estás excediendo los límites de tu aplicación (por decirlo de alguna manera).

fjcg02 02-07-2024 12:38:31

No sé si lo que buscas lo cubre la firma digital del documento.

Siempre podrán como comentan hacerle una foto o echar una tarde y transcribir de pé a pá el documento completo.

Suerte, y nos comentas cómo lo has solucionado.

Saludos

Neftali [Germán.Estévez] 02-07-2024 12:42:25

Cita:

Empezado por fjcg02 (Mensaje 556504)
Siempre podrán como comentan hacerle una foto o echar una tarde y transcribir de pé a pá el documento completo.

Es que no es necesario, yo uso un capturador "no estandard" con las siguientes teclas:



Pero es que se pueden personalizar o simplemente se puede lanzar la copia utilizando el menú contextual de la aplicación desde la barra de tareas.
Hay tantas alternativas, que por eso me parece un enfoque que no tiene buena salida.

buenarquero 03-07-2024 12:34:11

Os agradezco vuestro interés
 
De entrada os agradezco vuestro interés en mi tema, pero de momento no me está sirviendo para mucho. Os estáis centrando en el tema de la captura de pantalla y eso ya lo tengo resuelto puesto que la aplicación se ejecuta en un escritorio alternativo sin barra de tareas y que no guarda los datos del portapapeles, lo mismo que tampoco se puede iniciar ninguna aplicación, ya que sin barra de tareas y ocupando toda la pantalla, es imposible. Por otra parte, que se puedan hacer fotos es obvio, pero no es lo mismo que obtener la imagen de la pantalla directa. Solo se trata de dificultar lo más posible que se copie el contenido del PDF para distribuirlo, nada más. Si alguien me puede decir si hay algún error en el código que he usado para el hook de teclado o tiene otra forma de bloquear las teclas de función o incluso todo el teclado, que no es necesario para usar mi aplicación, lo agradecería.

Casimiro Notevi 03-07-2024 14:23:07

Pregunto: Suponiendo que pongas tantos controles para que no puedan hacer nada con el pdf salvo leerlo, imagino que el usuario tendrá el pdf para poder leerlo.
Si tiene el pdf ¿qué le impide regalarlo?
Saludos.

Neftali [Germán.Estévez] 03-07-2024 15:02:41

Cita:

Empezado por buenarquero (Mensaje 556532)
Os estáis centrando en el tema de la captura de pantalla...

Saltanto lo que te hemos dicho y volviendo al tema de los hooks....

Cita:

Empezado por buenarquero (Mensaje 556478)
En cuanto a los links que incluyes, el primero no tiene activo el enlace a la parte de hooks y el segundo, parece que solo ofrece solución para determinadas teclas o combinaciones, pero no para las teclas de función, al menos yo veo como se podría adaptar para que sirva para las teclas de función.

Cita:

Empezado por buenarquero (Mensaje 556477)
...Por eso necesito bloquear algunas o todas las teclas de función (F1 a F12) y que su pulsación no llegue al programa lector de PDF, independientemente de que el foco esté en él o no.

En el segundo enlace:
https://web.archive.org/web/20050214...oman/hooks.php

Se hace referencia a teclas para inhabilitar. Entre las que aparecen SI aparece alguna tecla de función (F4), en este caso con ALT:

Código Delphi [-]
    
if (VkCode = VK_F4) and AltDown and (lkAltF4 in Keys)  then begin       
  Result := 1;       
  exit;     
end;

Si buscas esas constantes en Delphi (VK_F4) llegarás a la unit Winapi.Windows.pas, y ahí está definida esa constante y las de las demás teclas de función. VK_F1 hasta VK_F12.

escafandra 03-07-2024 22:16:03

Pongo un ejemplo con un Hook a bajo nivel del teclado que bloquea F1 si se pulsa junto con ALT


Código Delphi [-]
...........
var
  WHookKeyboard: HHOOK = 0;

implementation

{$R *.dfm}


function KeyboardHook(Code, wParam, lParam: Integer): Integer; stdcall;
var
  vkCode:    DWORD;
  AltDown:   boolean;
  CtlDown:   boolean;
  ShiftDown: boolean;
begin
  vkCode:= PDWORD(lParam)^;
  AltDown   := (GetAsyncKeyState(VK_LMENU) and $8000 <> 0) or (GetAsyncKeyState(VK_RMENU) and $8000 <> 0);
  CtlDown   := GetAsyncKeyState(VK_CONTROL) and $8000 <> 0;
  ShiftDown := GetAsyncKeyState(VK_SHIFT) and $8000 <> 0;
  if (Code = HC_ACTION and (wParam = WM_KEYDOWN) then
  begin
    if vkCode = VK_F1 then
    begin
      if AltDown then Windows.Beep(1000, 100);
      Result:= 1;
      exit;
    end;
  end;
  Result:= CallNextHookEx(WHookKeyboard, Code, wParam, lParam);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  WHookKeyboard:= SetWindowsHookEx(13{WH_KEYBOARD_LL}, @KeyboardHook, GetModuleHandle(nil), 0);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  UnhookWindowsHookEx(WHookKeyboard);
end;


El hook tipo WH_KEYBOARD_LL es necesario para que actúe en todo el sistema y la puesta en marcha del hook debe hacerse global para que no falle:
SetWindowsHookEx(WH_KEYBOARD_LL, @KeyboardHook, GetModuleHandle(nil), 0);




Saludos.

buenarquero 04-07-2024 11:05:05

Cita:

Empezado por Casimiro Notevi (Mensaje 556534)
Pregunto: Suponiendo que pongas tantos controles para que no puedan hacer nada con el pdf salvo leerlo, imagino que el usuario tendrá el pdf para poder leerlo.
Si tiene el pdf ¿qué le impide regalarlo?
Saludos.

Como ya dije en otra contestación, el archivo no lo tiene el usuario, porque está incrustado en el ejecutable de la aplicación.

Casimiro Notevi 04-07-2024 11:19:25

Cita:

Empezado por buenarquero (Mensaje 556547)
Como ya dije en otra contestación, el archivo no lo tiene el usuario, porque está incrustado en el ejecutable de la aplicación.

Entonces sí que lo tiene, extraerlo del ejecutable es bastante simple, si tiene intención de hacerlo.
Por eso no vale la pena complicarse demasiado, porque todo dependerá de cuánto interés tenga en conseguirlo.

buenarquero 04-07-2024 11:24:39

Gracias
 
Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 556535)
Saltanto lo que te hemos dicho y volviendo al tema de los hooks....





En el segundo enlace:
https://web.archive.org/web/20050214...oman/hooks.php

Se hace referencia a teclas para inhabilitar. Entre las que aparecen SI aparece alguna tecla de función (F4), en este caso con ALT:

Código Delphi [-]
    
if (VkCode = VK_F4) and AltDown and (lkAltF4 in Keys)  then begin       
  Result := 1;       
  exit;     
end;

Si buscas esas constantes en Delphi (VK_F4) llegarás a la unit Winapi.Windows.pas, y ahí está definida esa constante y las de las demás teclas de función. VK_F1 hasta VK_F12.

OK, ¡Gracias! Las constantes ya las conocía pero no entendí en el momento el código. Intentaré adaptar ese código a ver si funciona al nivel que necesito.
De todas formas, probando he conseguido sortear las teclas de función con un truco un poco chapucero pero que lo explico por si a alguien le puede resultar eficaz en casos similares o para otras cosas. Lo que hago es, mediante el timer que cierra la ventana del administrador de tareas cuando aparece, detecto si la zona donde aparece el menú que no quiero que usen, toma el color de la pantalla en tres puntos diferentes, y si es el color del menú, que es siempre el mismo, independientemente de la configuración de colores de Windows, se cierra el menú simulando una pulsación de teclado.

buenarquero 04-07-2024 11:40:19

¡Gracias!
 
Cita:

Empezado por escafandra (Mensaje 556544)
Pongo un ejemplo con un Hook a bajo nivel del teclado que bloquea F1 si se pulsa junto con ALT


Código Delphi [-]
...........
var
  WHookKeyboard: HHOOK = 0;

implementation

{$R *.dfm}


function KeyboardHook(Code, wParam, lParam: Integer): Integer; stdcall;
var
  vkCode:    DWORD;
  AltDown:   boolean;
  CtlDown:   boolean;
  ShiftDown: boolean;
begin
  vkCode:= PDWORD(lParam)^;
  AltDown   := (GetAsyncKeyState(VK_LMENU) and $8000 <> 0) or (GetAsyncKeyState(VK_RMENU) and $8000 <> 0);
  CtlDown   := GetAsyncKeyState(VK_CONTROL) and $8000 <> 0;
  ShiftDown := GetAsyncKeyState(VK_SHIFT) and $8000 <> 0;
  if (Code = HC_ACTION and (wParam = WM_KEYDOWN) then
  begin
    if vkCode = VK_F1 then
    begin
      if AltDown then Windows.Beep(1000, 100);
      Result:= 1;
      exit;
    end;
  end;
  Result:= CallNextHookEx(WHookKeyboard, Code, wParam, lParam);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  WHookKeyboard:= SetWindowsHookEx(13{WH_KEYBOARD_LL}, @KeyboardHook, GetModuleHandle(nil), 0);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  UnhookWindowsHookEx(WHookKeyboard);
end;


El hook tipo WH_KEYBOARD_LL es necesario para que actúe en todo el sistema y la puesta en marcha del hook debe hacerse global para que no falle:
SetWindowsHookEx(WH_KEYBOARD_LL, @KeyboardHook, GetModuleHandle(nil), 0);




Saludos.

¡Gracias por tu aportación! No tengo ni idea de como adaptar el código para capturar solo las teclas de función sin Alt o si funcionará tal cual solo con la tecla de función, pero lo probaré. Lo que me gustaría que me explicaras es lo de que el hook hay que hacerlo a nivel global. ¿Que hay que hacer para que sea a nivel global? ¿no está implícito en el código? ¿Hay que declarar la función en una parte determinada del .Pas?

buenarquero 04-07-2024 13:46:18

No solo depende del interes que tenga
 
Cita:

Empezado por Casimiro Notevi (Mensaje 556548)
Entonces sí que lo tiene, extraerlo del ejecutable es bastante simple, si tiene intención de hacerlo.
Por eso no vale la pena complicarse demasiado, porque todo dependerá de cuánto interés tenga en conseguirlo.

No solo depende del interés que tenga sino de los conocimientos de programación. Es obvio que si hay gente que es capaz de piratear un Adobe Premiere, un Windows o un Photoshop y colgarlo en internet, habrá quien pueda obtener mi pdf sin demasiado problema, pero esta aplicación no va dirigida a un gran público sino solo a algunos que comparten la afición artística de la que trata el pdf y, generalmente, no tienen ni idea de programación y, en muchos casos, ni siquiera de informática. Y quien piratea un Photoshop, no le interesa piratear un PDF que es solo para una afición muy concreta de una minoría. Ya dije que no soy un profesional y que esta aplicación no es para venderla en masa, por ello, solo se trata de protegerla lo más posible y nada más, que ya lleva otras protecciones, no solo esta del bloqueo de teclas, simplemente para que el usuario normal no pueda duplicar el pdf.
De todas formas ya he resulto el tema con el código que me paso Neftalí. Funciona perfectamente para lo que quiero solo con una ligera modificación.
¡Gracias de todas formas por tu interés y tu aportación!


La franja horaria es GMT +2. Ahora son las 00:40:35.

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