La filosofía es la siguiente:
Cualquier programa puede registrarse como Visor del portapapeles. Cuando el usuario copia algo en el portapapeles, windows mira quien es el primer programa "visor del portapapeles" (obviamente el programa de windows) y le pasa un mensaje indicando que el contenido del portapapeles ha cambiado. Ese programa, debe continuar la cadena, es decir, seguir informando al resto de programas que son visores del portapapeles del cambio surgido.
Por tanto tenemos que:
- Registrar nuestro programa para que capture cosas del Portapapeles automaticamente, y guardar quien es el siguiente programa "visor del portapapeles". Además debemos quitarnos de esa lista al cerrar nuestro programa:
Código Delphi
[-]
var NextClipboard:Thandle; procedure RegistrarVisor;
begin
NextClipboard := SetClipboardViewer(frmppal.Handle);
end;
procedure EliminarVisor;
begin
ChangeClipboardChain(FrmPpal.Handle, NextClipboard)
end;
- Obviamente necesitamos responder cuando cambie el portapapeles:
Código Delphi
[-]
Tform1 = class(TForm)
private
procedure CambioPortapapeles(var Msg: TWMDrawClipboard); message wm_drawclipboard;
end;
implementation
procedure TFrmPpal.CambioPortapapeles(var Msg: TWMDrawClipboard);
var
i: Integer;
found: Boolean;
str: String;
begin
found := False;
if (Clipboard.HasFormat(CF_TEXT)) then
begin
Str := clipboard.AsText;
SendMessage(NextClipboard, Msg.Msg, Msg.Msg, Msg.Msg);
end
end;
El error que yo veo, es que la linea
Código Delphi
[-]
DrawClipBoardMessage.Result:= SendMessage(SiguienteHandle, WM_DRAWCLIPBOARD, 0, 0);
tienes que ponerlo al final de la rutina ¿por qué?, porque un programa "visor del portapapeles" puede cambiar el contenido del mismo, y si lo hace, tu línea
Código Delphi
[-]Memo1.Text:= ClipBoard.AsText
está desfasada con el contenido real del portapapeles.
Es más yo lo modificaba y solo ponía esto:
Código Delphi
[-]
SendMessage(NextClipboard, Msg.Msg, Msg.Msg, Msg.Msg);
Tu procedimiento WMChangeCBCHain creo que es inconsistente, simplemente elimínalo.
Saludos