2017-01-27 20 views
2

Я преобразовал DLL с 32-битного в 64-разрядный без проблем, но когда я загружаю эту DLL из 64-разрядного приложения, которое занимает большой объем памяти, приложение падает и закрывается при загрузке DLL.Delphi 64-разрядная DLL: проблемы с событиями OleCtrls

DLL - это простая форма с TWebBrowser на нем. Я использую Delphi 10 Seattle.

После отладки я обнаружил проблему в 64 разрядное преобразование в блоке VCL «Vcl.OleCtrls.pas» решена таким образом:

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; 

Это решает проблему аварии, но TWebBrowser события не стреляли больше и происходит только на 64-битной основе.

Как исправить события TWebBrowser firig?

У вас есть аналогичная проблема или workaroud для исправления событий?

Благодаря

+0

В этом разделе есть проблема с этим дефектом в 'WebBrowserEx'. Очень сложно идентифицировать проблему без [mcve]. Мой совет заключается в том, что вы разрешаете распределение памяти сверху вниз на системном уровне и устраняете все дефекты. Emba были ужасно плохи в исправлении их сломанного 64-битного кода. –

+0

FWIW, вам не нужно менять 'GetWindowLong', поскольку он реализуется, вызывая' GetWindowLongPtr'. Как и 'SetWindowLong'. Проблема в том, что это просто приведение к «Longint». Фактически вы могли бы использовать 'SetWindowLong (WindowHandle, GWL_WNDPROC, LONG_PTR (@InitWndProc))'. –

+0

['SetWindowSubclass()'] (https://msdn.microsoft.com/en-us/library/windows/desktop/bb762102.aspx) [лучше и безопаснее] (https://blogs.msdn.microsoft. com/oldnewthing/20031111-00 /? p = 41883) для использования, чем 'SetWindowLongPtr (GWL_WNDPROC)' –

ответ

1

я нашел другую ошибку произнесения, порождающую проблему событий TWebBrowser. В блоке Эмбинского «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} 

Целое отливать генерировать переполнение, по ситуации использования памяти высоты, а выход процедуры InvokeEvent не вызывая фактическое событие. Решено с применением Int64.

Надеюсь, что Emba интегрирует это исправление и найдет подобное.