Dmi*_*try 1 delphi delphi-xe delphi-xe2
当在Delphi XE或Delphi XE2 Update 3的DLL源代码中使用单元HtmlHelpViewer时,regsvr32.exe的DLL注册会冻结.只需将该单元添加到接口使用列表即可.主要项目(使用DLL)也在退出时冻结.
如何解决这个问题?
谢谢您的帮助!
在建议的修复中重现问题和问题的步骤:
1).请创建以下DLL:
library Test;
uses
ComServ,
HtmlHelpFixer,
HtmlHelpViewer;
exports
DllGetClassObject,
DllCanUnloadNow,
DllRegisterServer,
DllUnregisterServer;
begin
end.
Run Code Online (Sandbox Code Playgroud)
2).还创建链接到此DLL的以下BPL(-LUTestBpl例如,通过dcc32参数):
package TestBpl;
requires
Vcl;
end.
Run Code Online (Sandbox Code Playgroud)
3).然后执行:regsvr32.exe /s Test.dll.OS Windows 7 32位.
更新
根据Altaveron提交的QC报告的最新评论,这个问题将在下一次Delphi更新中得到解决,更新4.事实上,Altaveron现在确认更新4确实解决了这个问题.
这是MS HTML帮助控件hhctrl.ocx的已知问题.我所知道的最好的描述是在HelpWare FAR HTML FAQ中.有许多描述了这个问题QC报告:48983,67463,78998,89616.
根据最新的质量控制报告,这在XE2中得到了修复,但是你报告了其他情况,我倾向于相信你.特别是作为HtmlHelpViewerXE和XE2单位来源的比较,没有发现与此问题相关的变化.
由于需要修改的代码深埋在HtmlHelpViewer单元内,因此很难解决这个问题.我不得不求助于修补HtmlHelpAPI调用.像这样:
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.
Run Code Online (Sandbox Code Playgroud)
在uses任何使用HTML帮助的单位之前,请先在.dpr 列表中包含此单元.
我使用的代码版本稍微多一些,并采取措施确保在DLL卸载时关闭所有打开的帮助窗口.这不再发生,因为我们已停止发送HH_CLOSE_ALL.
您需要确保关闭所有帮助窗口,然后跟踪HtmlHelp调用返回的窗口句柄,您现在可以拦截它们.然后在关机时向WM_CLOSE那些替换丢失的HH_CLOSE_ALL呼叫的窗口发送一条消息HtmlHelp.
但是,我相信上面的代码可以帮助您解决使用regsvr32的直接障碍,它不会显示帮助窗口.
随意做一些实验!至少,上面的代码为您提供了可以修改HtmlHelpViewer单元行为的入口点.
| 归档时间: |
|
| 查看次数: |
1769 次 |
| 最近记录: |