Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   API de Windows (https://www.clubdelphi.com/foros/forumdisplay.php?f=7)
-   -   Detectar texto seleccionado (https://www.clubdelphi.com/foros/showthread.php?t=87016)

dblx 04-11-2014 20:53:26

Detectar texto seleccionado
 
Saludos desarrolladores del mundo que usan este maravilloso sitio web, tengo una duda que quizas ya alguien haya resuelto pero que no ha compartido o al menos no lo he visto en el sitio, mi situación es la siguiente, tengo una aplicación que se ejecuta en segundo plano (lo cual hace perfectamente), cuando hago una combinación de teclas la aplicación entra en un procedimiento el cual hace lo que debe hacer, pero tengo un problema, debo capturar el texto que este seleccionado en la aplicación que este actualmente siendo utilizada, sea bloc de notas, word, excel, firefox, chrome, sea cualquier aplicación, al yo presionar una combinación de teclas (utilicé las HotKeyManager), el texto que este seleccionado debo capturarlo y poder pasarselo a mi aplicación en segundo plano, supuse que eso debe ser con comunicacion con la API de windows, ya que el sistema operativo sabe lo que esta seleccionado en cualquier momento en la aplicacion que este en primer plano, entonces esa es mi duda, quiero capturar de cualquier aplicación el texto que esté seleccionado y poder utilizarlo en mi aplicacion, muchas gracias de antemano y un saludo a todos mis colegas desarrolladores, un abrazo desde VENEZUELA :D

escafandra 04-11-2014 21:50:38

Usa el clipborad y un visor del mismo en tu app

Saludos.

nlsgarcia 05-11-2014 00:58:12

dblx,

Cita:

Empezado por dblx
...debo capturar el texto que este seleccionado en la aplicación que este actualmente siendo utilizada, sea Bloc de Notas, Word, Excel, Firefox, Chrome, sea cualquier aplicación...

:rolleyes:

Revisa este código:
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, ClipBrd;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Timer1: TTimer;
    Image1: TImage;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// Inicializa la aplicación
procedure TForm1.FormCreate(Sender: TObject);
begin
   Timer1.Interval := 1000;
end;

// Monitorea el Clipboard
procedure TForm1.Timer1Timer(Sender: TObject);
begin

   // Captura Texto del Clipboard
   if Clipboard.HasFormat(CF_TEXT) then
   begin
      Memo1.Clear;
      Memo1.Text := Clipboard.AsText;
   end;

   // Captura Pictures del Clipboard
   if Clipboard.HasFormat(CF_PICTURE) then
   begin
      Image1.Picture := nil;
      Image1.Picture.Assign(Clipboard);
   end;

end;

end.
El código anterior en Delphi 7 sobre Windows 7 Professional x32, Monitorea el Clipboard y captura el contenido relacionado a Texto y Pictures, como se puede ver en la siguiente imagen:



Espero sea útil :)

Nelson.

escafandra 05-11-2014 08:34:48

La propuesta de nlsgarcia funciona perfectamente, pero yo me refería a un verdadero visor del clipboard, tal como lo define Microshoft con la API SetClipboardViewer. Procesando el mensaje M_DRAWCLIPBOARD cada vez que se coloca algo en el clipboard.

Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Clipbrd;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    NextViewer: HWND;
    procedure GetData;
  protected
    procedure WndProc(var Message: TMessage); override;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  //Clipboard.Clear;  // Podemos limpiar o no el clipboard al comenzar
  // Nos registramos como ClipboardViewer y guardamos el anterior de la cadena
  NextViewer:= SetClipboardViewer(Handle);
end;

procedure TForm1.WndProc(var Message: TMessage);
begin
  case Message.Msg of
  WM_DRAWCLIPBOARD:
  begin
    // Si tenemos un visor en la cadena, le reenviamos el mensaje
    if NextViewer <> 0 then
      SendMessage(NextViewer, WM_DRAWCLIPBOARD, 0, 0);
    // Miramos el ClipBoard
    GetData();
  end;
  WM_DESTROY:
    // Dejamos de ser visor del ClipBoard
    ChangeClipboardChain(Handle, NextViewer);
  end;
  inherited WndProc(Message);
end;

procedure TForm1.GetData;
begin
  Memo1.Lines.Add(Clipboard.AsText);
end;

end.


Saludos.

dblx 05-11-2014 13:35:20

Gracias
 
Muchisimas gracias a ambos, hoy intentaré esto que me recomendaron y comentaré :D

escafandra 06-11-2014 12:15:53

Perfeccionando el visor del ClipBoard:

Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Clipbrd;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    NextViewer: HWND;
    procedure GetData;
  protected
    procedure WndProc(var Message: TMessage); override;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  //Clipboard.Clear;  // Podemos limpiar o no el clipboard al comenzar
  // Nos registramos como ClipboardViewer y guardamos el anterior de la cadena
  NextViewer:= SetClipboardViewer(Handle);
end;

// Procesamos los mensajes a bajo nivel
procedure TForm1.WndProc(var Message: TMessage);
begin
  case Message.Msg of
  WM_DRAWCLIPBOARD:
  begin
    // Si tenemos un visor en la cadena, le reenviamos el mensaje
    if NextViewer <> 0 then
      SendMessage(NextViewer, WM_DRAWCLIPBOARD, 0, 0);
    // Miramos el ClipBoard
    GetData();
  end;

  WM_DESTROY:
    // Notificamos que dejamos de ser visor del ClipBoard
    ChangeClipboardChain(Handle, NextViewer);

  WM_CHANGECBCHAIN:
    // Nos notifican que otra App deje de ser visor del ClipBoard
    if HWND(Message.WParam) = NextViewer then
      // Alctualizamos NextViewer
      NextViewer:= Message.LParam
    else if NextViewer <> 0 then
      // Si no se actualizó reenviamos el mensaje
      SendMessage(NextViewer, WM_CHANGECBCHAIN, Message.WParam, Message.LParam);
  
  end;
  inherited WndProc(Message);
end;

procedure TForm1.GetData;
begin
  if Clipboard.HasFormat(CF_TEXT) then
    Memo1.Lines.Add(Clipboard.AsText);
end;

end.

Saludos.

escafandra 06-11-2014 13:01:51

El anterior código es apropiado para S.O. Win2000 en adelante, en el caso de que nuestra aplicación sólo queramos que funcione desde Windows Vista, podemos optar por esta otra técnica, más sencilla pero que no funcionará en WinXP:

Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Clipbrd;

  function AddClipboardFormatListener(hWindow: HWND): BOOL; stdcall; external  User32;
  function RemoveClipboardFormatListener(hWindow: HWND): BOOL; stdcall; external  User32;

  const WM_CLIPBOARDUPDATE = $031D;
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    procedure GetData;
  protected
    procedure WndProc(var Message: TMessage); override;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  AddClipboardFormatListener(Handle);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  RemoveClipboardFormatListener(Handle);
end;

procedure TForm1.GetData;
begin
  if Clipboard.HasFormat(CF_TEXT) then
    Memo1.Lines.Add(Clipboard.AsText);
end;

// Procesamos los mensajes a bajo nivel
procedure TForm1.WndProc(var Message: TMessage);
begin
  if Message.Msg = WM_CLIPBOARDUPDATE then
    GetData();
  
  inherited WndProc(Message);
end;

end.

Saludos.

nlsgarcia 06-11-2014 17:27:24

escafandra,

Cita:

Empezado por escafandra
...Perfeccionando el visor del ClipBoard...Apropiado para S.O. Win2000 en adelante...En el caso de que nuestra aplicación sólo queramos que funcione desde Windows Vista, podemos optar por esta otra técnica, más sencilla pero que no funcionará en WinXP...

^\||/

Nelson.

escafandra 06-11-2014 19:13:40

Nelson, no entiendo tu cita :eek:

Saludos.

roman 06-11-2014 20:48:16

Es como el like de facebook.

// Saludos

nlsgarcia 06-11-2014 20:57:50

escafandra,

Cita:

Empezado por escafandra
...no entiendo tu cita...

:rolleyes:

En resumen que tu código es muy interesante :D

Saludos,

Nelson.

escafandra 06-11-2014 21:22:43

Es que al ver citas mezcladas y no ver el emoticono (desde mi smartphone) no entendía...

Gracias por tu apreciación, nlsgarcia.

Saludos.


La franja horaria es GMT +2. Ahora son las 13:27:25.

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