Регистрация DLL с помощью regsvr32.exe останавливается при использовании модуля HtmlHelpViewer в Delphi XE или Delphi XE2 - PullRequest
1 голос
/ 24 декабря 2011

Регистрация DLL с помощью regsvr32.exe останавливается, когда модуль HtmlHelpViewer используется в источниках DLL в Delphi XE или Delphi XE2 Update 3. Просто добавьте модуль в список использований интерфейса.Основной проект (который использует DLL) тоже зависает при выходе.

Как решить проблему?

Спасибо за помощь!

ШАГИ, ЧТОБЫ УЗНАТЬ ВОПРОСИ ВЫПУСК В ПРЕДЛАГАЕМОМ ИСПРАВЛЕНИИ:

1).Пожалуйста, создайте следующую DLL:

library Test;

uses
  ComServ,
  HtmlHelpFixer,
  HtmlHelpViewer;

exports
  DllGetClassObject,
  DllCanUnloadNow,
  DllRegisterServer,
  DllUnregisterServer;

begin
end.

2).Также создайте следующий BPL, связанный с этой DLL (например, параметром -LUTestBpl dcc32):

package TestBpl;

requires
  Vcl;

end.

3).Затем просто выполните: regsvr32.exe /s Test.dll.ОС Windows 7 32-битная.

Ответы [ 2 ]

9 голосов
/ 24 декабря 2011

Обновление

Согласно последним комментариям к отчету QC , представленному Altaveron, эта проблема будет решена в следующем обновлении Delphi, обновлении 4. Идействительно, Altaveron теперь подтверждает, что обновление 4 действительно решает проблему.


Это известная проблема с элементом справки MS HTML, hhctrl.ocx.Лучшее описание, о котором я знаю, - в HelpWare FAR HTML FAQ.Существует множество отчетов о контроле качества, описывающих проблему: 48983 , 67463 , 78998 , 89616 .

Согласнопоследний отчет о контроле качества, это исправлено в XE2, но вы сообщаете иначе, и я был бы склонен вам верить.Тем более, что сравнение источника для HtmlHelpViewer модуля из XE и XE2 не показывает никаких изменений, которые появляются, связанные с этой проблемой.

Довольно сложно обойти эту проблему, так как код, который необходимо изменить,похоронен глубоко внутри блока HtmlHelpViewer.Мне пришлось прибегнуть к исправлению вызова API HtmlHelp.Например:

unit HtmlHelpFixer;

interface

implementation

uses
  Windows;

function HtmlHelp(hWndCaller: HWND; pszFile: PWideChar; uCommand: UINT; dwData: DWORD): HWND;
begin
  if uCommand=HH_CLOSE_ALL then begin
    //don't call HtmlHelpW because it can result in a hang due to a bug in hhctrl.ocx
    Result := 0;
  end else begin
    Result := HtmlHelpW(hWndCaller, pszFile, uCommand, dwData);
  end;
end;

procedure PatchCode(Address: Pointer; const NewCode; Size: Integer);
var
  OldProtect: DWORD;
begin
  if VirtualProtect(Address, Size, PAGE_EXECUTE_READWRITE, OldProtect) then begin
    Move(NewCode, Address^, Size);
    FlushInstructionCache(GetCurrentProcess, Address, Size);
    VirtualProtect(Address, Size, OldProtect, @OldProtect);
  end;
end;

type
  PInstruction = ^TInstruction;
  TInstruction = packed record
    Opcode: Byte;
    Offset: Integer;
  end;

procedure RedirectProcedure(OldAddress, NewAddress: Pointer);
var
  NewCode: TInstruction;
begin
  NewCode.Opcode := $E9;//jump relative
  NewCode.Offset := NativeInt(NewAddress)-NativeInt(OldAddress)-SizeOf(NewCode);
  PatchCode(OldAddress, NewCode, SizeOf(NewCode));
end;

procedure RedirectHtmlHelp;
var
  HtmlHelp: function(hWndCaller: HWND; pszFile: PWideChar; uCommand: UINT; dwData: DWORD_PTR): HWND;
begin
  HtmlHelp := Windows.HtmlHelp;
  RedirectProcedure(@HtmlHelp, @HtmlHelpFixer.HtmlHelp);
end;

initialization
  RedirectHtmlHelp;

end.

Включите этот модуль в свой список .dpr uses раньше, чем любой модуль, который что-либо делает с помощью HTML.

Версия кода, которую я использую, делаетнемного больше и предпринимает шаги, чтобы гарантировать, что все открытые окна справки закрыты, когда DLL выгружается.Это больше не происходит, потому что мы прекратили отправлять HH_CLOSE_ALL.

. Вы захотите убедиться, что все окна справки закрыты, а затем отследите дескрипторы окон, возвращенные вызовами HtmlHelp, которые вы можете теперьперехватывать.Затем при завершении работы отправьте сообщение WM_CLOSE в те окна, которое заменяет пропущенный вызов HH_CLOSE_ALL на HtmlHelp.

Однако я считаю, что приведенный выше код поможет вам преодолеть ваше непосредственное препятствие с regsvr32, который выигралПоказывать справочные окна.

Не стесняйтесь экспериментировать!По крайней мере, приведенный выше код дает вам точки входа, с помощью которых вы можете изменить поведение устройства HtmlHelpViewer.

0 голосов
/ 26 июня 2012

Embarcadero устранил эту проблему в Delphi XE2 Update 4. Но теперь контекстная справка не работает в IDE, когда вы используете BPL с модулем HtmlHelpViewer в предложении использования.

...