Ver Mensaje Individual
  #1  
Antiguo 26-08-2006
Avatar de Faust
Faust Faust is offline
Miembro
 
Registrado: abr 2006
Ubicación: México D.F.
Posts: 930
Reputación: 18
Faust Va por buen camino
Cool Error al copiar texto

Saludos compas del Club Delphi

Hace tiempo estaba desarrollando una aplicación que monitoreaba el portapapeles en busca de contenido apto para mi aplicación, pero al encontrar un error que jamás pude erradicar, me dí por vencido, ahora he retomado esta aplicación de nuevo, y e identifico más o menos por donde va el error, usé el truco 214 de Trucomania y un artículo que leí en la revista Síntesis no. 17 de Grupo Albor, lo que hago es que al crear el form registrarme para ver los mensajes del portapapeles;

Código Delphi [-]
Self.SiguienteHandle := SetClipboardViewer(Self.Handle)

al destruir el form, informar que salgo de la cadena de mensajes del portapapeles:

Código Delphi [-]
ChangeClipboardChain(Self.Handle, Self.SiguienteHandle);

al detectar un cambio en la cadena del portapapeles trato el mensaje:

Código Delphi [-]
procedure TForm1.WMChangeCBCHain(var ChangeCBCHainMessage: TMessage);
begin
  if (ChangeCBCHainMessage.WParam = Self.SiguienteHandle) then
  begin
    SiguienteHandle := ChangeCBCHainMessage.LParam;
    ChangeCBCHainMessage.Result:= 0
  end
    else
      if (SiguienteHandle <> 0) then
        ChangeCBCHainMessage.Result:= SendMessage(SiguienteHandle, WM_CHANGECBCHAIN, ChangeCBCHainMessage.WParam, ChangeCBCHainMessage.LParam);
end;

y al recibir el mensaje de que ha cambiado el portapapeles ejecuto lo siguiente

Código Delphi [-]
procedure TForm1.WMDrawClipboard(var DrawClipboardMessage: TMessage);
begin
  DrawClipBoardMessage.Result:= SendMessage(SiguienteHandle, WM_DRAWCLIPBOARD, 0, 0);
  if ClipBoard.HasFormat(CF_TEXT) then
    begin
      Memo1.Clear;
      Memo1.Text:= ClipBoard.AsText  //Aquí sucede el error
    end
end;
Ahora algo importante: el error sucede aquí:
Código Delphi [-]
Memo1.Text:= ClipBoard.AsText  //Aquí sucede el error
Solo cuando estoy ejecutando algún programa de Office, por ejemplo Excel y solamente cuando efectúo una operación de arrastre y lo raro es que algunas veces aparece el mensaje de error en Office y otras en mi aplicación, el mensaje de error de Office es: "No se puede vaciar el portapapeles"y el que aparece en mi aplicación es: "Cannot open clipboard", lo que me hace pensar que al efectuar una operación de arrastre del contenido de algún documento de Office sucede lo siguiente:
  1. Office almacena el contenido previo del portapapeles a una variable temporal.
  2. Office ocupa el portapapeles para realizar su operación de arrastre, esto desencadena el mensaje WM_DRAWCLIPBOARD, pero antes de hacer esto bloquea el acceso al portapapeles.
  3. Al terminar la operación de arrastre Office restaura el contenido del portapapeles previo a la operación de arrastre y libera el portapapeles.
Y es así como mi aplicación capta el mensaje WM_DRAWCLIPBOARD y trata de obtener acceso al portapapeles, pero al estar bloqueado por Office cae en el error "Cannot open clipboard", y cuando mi programa llega a obtener acceso al portapapeles, en Office ocurre el error "No se puede vaciar el contenido del portapapeles", creo que la solución a mi problema es saber cuando está bloqueado el acceso al portapapeles, si estoy en lo correcto, como se hace eso, si no por favor que alguien me ayude y tengo otra pequeña duda, en dónde, cómo y que debo asignar como valor al campo Result de los mensajes WM_CHANGECBCHAIN y WM_DRAWCLIPBOARD, según la ayuda de Windows se debe devolver cero despues de una operación exitosa con el mensaje.

El código de aquí es solo de prueba, una vez que funcione exitosamente lo implementaré en mi aplicación.

Bueno, después de alargarme un poco con la explicación de mi problema me despido, enviando un saludo y un abrazo amistoso a todos los delphimaniacos de Club Delphi y agradeciendo de una vez a todos aquellos que me puedan ayudar.

Gracias
__________________
Herr Heins Faust
Responder Con Cita