Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 16-03-2012
prietor prietor is offline
Registrado
NULL
 
Registrado: mar 2012
Posts: 2
Poder: 0
prietor Va por buen camino
Docking y borrado de contenido ActiveX (SftTree)

Hola,

Estoy trasteando con el docking nativo en Delphi 2006 y me he topado con un problema serio: Tengo un TForm dockado inicialmente en un TPanel que contiene un árbol cargado con varios items (control ActiveX SftTree). Al hacer un drag & dock del TForm (bien en otro TPanel, bien como ventana flotante), se disparan automáticamente eventos de borrado de items en el ActiveX quedando el árbol vacío de datos.

El efecto parece producirse con el cambio de Parent del TForm que se está desdockando/dockando. Este comportamiento no ocurre con componentes de la VCL: si pongo una TListBox al ladito cargada con items en el mismo TForm y hago el drag & dock, los items de la lista no se borran!.

Da la sensación de que el cambio de Parent del TForm solo produce un redibujado sobre componentes VCL hijos y, sin embargo, se carga el contenido del resto de componentes no VCL.

No he llegado a encontrar ningún workaround... Alguno os habéis encontrado con esto? Alguna propuesta de solución/workaround?

Os dejo una traza del disparo del borrado de un item del árbol (ActiveX SftTree) al hacer un undock.

TFVentanaSftTree.TForm2.m_arbolItemDeleted($1420700,???)
:00487f3d TOleControl.InvokeEvent + $B1
:00486ba9 TEventDispatch.Invoke + $3D
:4f329dd5 ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:4f361027 ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:4f35f1d5 ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:4f33d8fe ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:4f38c888 ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:4f3e2999 ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:4f3e0980 ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:7722c4e7 ; C:\Windows\system32\USER32.dll
:7722c5e7 ; C:\Windows\system32\USER32.dll
:77221b31 ; C:\Windows\system32\USER32.dll
:77221b57 USER32.CallWindowProcW + 0x1b
:4f35ca47 ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:4f35ca0c ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:4f35d5a0 ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:4f348010 ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:4f3b5566 ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:4f3635d9 ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:4f3bec80 ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:7722c4e7 ; C:\Windows\system32\USER32.dll
:7722c5e7 ; C:\Windows\system32\USER32.dll
:77224f0e USER32.GetScrollBarInfo + 0xfd
:77224f7d ; C:\Windows\system32\USER32.dll
:779e6fee ntdll.KiUserCallbackDispatcher + 0x2e
:4f3baf45 ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:4f3b77b0 ; C:\Windows\system32\SftTree_IX86_U_70.ocx
:00487774 TOleControl.DestroyWindowHandle + $38
:00478e1c TCustomForm.DefineProperties
:01463480
:0046872a TWinControl.RemoveControl + $4A
Responder Con Cita
  #2  
Antiguo 20-03-2012
prietor prietor is offline
Registrado
NULL
 
Registrado: mar 2012
Posts: 2
Poder: 0
prietor Va por buen camino
Thumbs up

Después de mucho buscar, he encontrado un workaround relativamente limpio basado en controlar el destroy y create del handler de la ventana del TOleControl embebido para cambiarlo de Parent a nivel de handler de Windows. Al parecer la VCL no está diseñada para tratar correctamente el ciclo de destroy-create con dockables. Es un error de diseño de la VCL...

La solución más sencilla pasa por tocar el wrapper TLB tras importar el ActiveX. Para mi caso concreto, que utilizo un TSftTree embebido en un TForm dockable:

Código Delphi [-]
...
TSftTree = class(TOleControl)
  private
    ...
    ActualHandle: HWND;
  protected
    ...
    procedure DestroyWnd; override;
    procedure CreateWnd; override;
 public
...
implementation
uses ComObj, Controls, Forms;
...
procedure TSftTree.DestroyWnd;
begin
  if (csDestroying in ComponentState) then
    inherited//TOleControl:estroyWnd();
  else
  begin
    //Parent to the Application window which is 0x0 in size
    windows.SetParent(WindowHandle,Forms.Application.Handle);
    //save the WindowHandle
    ActualHandle := WindowHandle;
    //set it to 0 so Createwnd will be called again...
    WindowHandle := 0;
  end;
end;

procedure TSftTree.CreateWnd;
begin
  if (ActualHandle <> 0) then
  begin
    if (IsWindow(ActualHandle)) then
    begin
      WindowHandle := ActualHandle;
      ActualHandle := 0;
      windows.SetParent( WindowHandle, TWinControl(Self).Parent.Handle );
      //Force a resize on the client window
      MoveWindow( WindowHandle, 0, 0, TWinControl(Self).Parent.Width,TWinControl(Self).Parent.Height,true );
      //quick exit because there is NO need to create the window
      exit;
    end
  end;
  inherited;
end;
...

Un saludo!
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Componente para docking lafirma OOP 8 15-12-2011 17:12:38
email yahoo, no muestra contenido..muestra todo menos contenido. sakuragi Linux 5 29-02-2008 18:11:27
docking Io Varios 4 07-08-2006 14:58:51
borrado logico @-Soft Conexión con bases de datos 0 25-06-2004 14:32:22
Borrado de un .pas? danytorres Varios 5 30-12-2003 17:28:33


La franja horaria es GMT +2. Ahora son las 09:25:36.


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
Copyright 1996-2007 Club Delphi