2017-01-27 5 views
2

J'ai converti une DLL de 32 bits en 64 bits sans problème, mais quand je charge cette DLL à partir d'une application 64 bits qui occupe une grande quantité de mémoire l'application se bloque et se ferme lorsque la DLL est chargée.Delphi 64 bits DLL: OleCtrls problèmes d'événements

La DLL est une forme simple avec un TWebBrowser dessus. J'utilise Delphi 10 Seattle.

Après le débogage j'ai trouvé un problème de conversion 64 bits dans l'unité de vlc « Vcl.OleCtrls.pas » résolus de cette façon:

procedure TOleControl.HookControlWndProc; 
var 
    WndHandle: HWnd; 
begin 
    if (FOleInPlaceObject <> nil) and (WindowHandle = 0) then 
    begin 
    WndHandle := 0; 
    FOleInPlaceObject.GetWindow(WndHandle); 
    if WndHandle = 0 then raise EOleError.CreateRes(@SNoWindowHandle); 
    WindowHandle := WndHandle; 
    //DefWndProc := Pointer(GetWindowLong(WindowHandle, GWL_WNDPROC));//OLD 
    DefWndProc := Pointer(GetWindowLongPtr(WindowHandle, GWL_WNDPROC)); 
    CreationControl := Self; 
    //SetWindowLong(WindowHandle, GWL_WNDPROC, Longint(@InitWndProc));//OLD 
    SetWindowLongPtr(WindowHandle, GWL_WNDPROC, LONG_PTR(@InitWndProc)); 
    SendMessage(WindowHandle, WM_NULL, 0, 0); 
    end; 
end; 

Cela résout le problème de l'accident, mais les événements TWebBrowser ne sont pas déclenchés plus et arrive sur 64bit seulement.

Comment réparer les événements TWebBrowser?

Avez-vous trouvé un problème similaire ou un problème de travail pour résoudre des événements?

Merci

+0

Il y a une charge plus de ce défaut dans 'WebBrowserEx'. Très difficile pour nous d'identifier le problème sans [mcve]. Mon conseil est que vous activez l'allocation de mémoire descendante au niveau du système et éliminez tous les défauts. Emba a été terriblement mauvais à réparer leur code 64 bits cassé. –

+0

FWIW, vous n'avez pas besoin de changer 'GetWindowLong' car il est implémenté en appelant' GetWindowLongPtr'. Comme 'SetWindowLong'. Le problème est purement le casting à «Longint». En fait vous auriez pu utiliser 'SetWindowLong (WindowHandle, GWL_WNDPROC, LONG_PTR (@InitWndProc))'. –

+0

['SetWindowSubclass()'] (https://msdn.microsoft.com/en-us/library/windows/desktop/bb762102.aspx) est [mieux et plus sûr] (https://blogs.msdn.microsoft. com/oldnewthing/20031111-00 /? p = 41883) à utiliser que SetWindowLongPtr (GWL_WNDPROC) ' –

Répondre

1

J'ai trouvé une autre erreur de casting qui génèrent la question de l'événement TWebBrowser. Dans l'unité Emba « Vcl.OleCtrls.pas »:

procedure TOleControl.InvokeEvent(DispID: TDispID; var Params: TDispParams); 
{$IFDEF CPUX64} 
var 
    EventMethod: TMethod; 
    ParamBlock : TParamBlock; 
    i : Integer; 
    StackParams2 : array of Int64; 

begin 
    GetEventMethod(DispID, EventMethod); 
    //if Integer(EventMethod.Code) < $10000 then Exit; //OLD 
    if Int64(EventMethod.Code) < $10000 then Exit;  //NEW 

    ParamBlock.RegRCX := Int64(EventMethod.Data); 
    ParamBlock.RegRDX := Int64(Self); 

    if Params.cArgs > 2 then 
    begin 
    SetLength(StackParams2, Params.cArgs-2); 
    end; 

    for i := 1 to Params.cArgs do 
    case i of 
     1: ParamBlock.RegR8 := Int64(Params.rgvarg[Params.cArgs-1].unkVal); 
     2: ParamBlock.RegR9 := Int64(Params.rgvarg[Params.cArgs-2].unkVal); 
    else 
     StackParams2[i-3] := Int64(Params.rgvarg[Params.cArgs-i].unkVal); 
    end; 

    ParamBlock.StackDataSize := Length(StackParams2) * sizeof(Pointer); 
    ParamBlock.StackData := @StackParams2[0]; 

    RawInvoke(EventMethod.Code, @ParamBlock); 
end; 
{$ELSE !CPUX64} 

entier jettent provoquer un débordement, sur la situation d'utilisation de la mémoire Hight, et la sortie de la procédure de InvokeEvent ne pas appeler l'événement réel. Résolu avec le casting Int64.

J'espère que Emba va intégrer ce correctif et trouver des similaires.