千家信息网

ComBoBox控件,如果里面有item为空,那么就报ntdll.dll的解决办法

发表于:2024-10-21 作者:千家信息网编辑
千家信息网最后更新 2024年10月21日,ComBoBox控件,如果里面有item为空,那么就报ntdll.dll的解决办法经过在网上查询,终于找到了一个解决方案,下载到了一个pas文件把这个pas文件 add to project 后,就不
千家信息网最后更新 2024年10月21日ComBoBox控件,如果里面有item为空,那么就报ntdll.dll的解决办法

ComBoBox控件,如果里面有item为空,那么就报ntdll.dll的解决办法

经过在网上查询,终于找到了一个解决方案,下载到了一个pas文件

把这个pas文件 add to project 后,就不报错了,确实不错

---------------------------------

复制下面的代码,保存到 D7ComboBoxStringsGetPatch.pas 即可

------------------------------------------

unit D7ComboBoxStringsGetPatch;

// The patch fixes TCustomComboBoxStrings.Get method for empty string item in Delphi 7.

interface

{$IF RTLVersion <> 15.0}

'This patch is intended for Delphi 7 only';

{$IFEND}

implementation

uses

Windows, SysUtils, StdCtrls;

resourcestring

RsPatchingFailed = 'TCustomComboBoxStrings.Get patching failed.';

type

TPatchResult = (prNotNeeded, prOk, prError);

function PatchCode(RoutineStartAddr: Pointer; PatchOffset: Cardinal; OriginalCode: Pointer;

OriginalCodeLen: Cardinal; PatchedCode: Pointer; PatchedCodeLen: Cardinal): TPatchResult;

const

JmpOpCode = $25FF;

type

PPackageThunk = ^TPackageThunk;

TPackageThunk = packed record

JmpInstruction: Word;

JmpAddress: PPointer;

end;

var

CodeStart: Pointer;

BytesWritten: DWORD;

begin

if FindClassHInstance(System.TObject) <> HInstance then

with PPackageThunk(RoutineStartAddr)^ do

if JmpInstruction = JmpOpCode then

RoutineStartAddr := JmpAddress^

else

begin

Result := prError;

Exit;

end;

CodeStart := Pointer(LongWord(RoutineStartAddr) + PatchOffset);

if CompareMem(CodeStart, OriginalCode, OriginalCodeLen) then

begin

if WriteProcessMemory(GetCurrentProcess, CodeStart, PatchedCode, PatchedCodeLen, BytesWritten) and

(BytesWritten = PatchedCodeLen) then

begin

FlushInstructionCache(GetCurrentProcess, CodeStart, PatchedCodeLen);

Result := prOk;

end

else

Result := prError;

end

else

Result := prNotNeeded;

end;

type

TCustomComboBoxStringsHack = class(TCustomComboBoxStrings);

function AddrOfTCustomComboBoxStringsGet: Pointer;

begin

Result := @TCustomComboBoxStringsHack.Get;

end;

procedure PatchTCustomComboBoxStringsGet;

const

OriginalCode: Cardinal = $74FFF883; // CMP EAX, -1 | JZ +$26

PatchedCode: Cardinal = $7E00F883; // CMP EAX, 0 | JLE +$26

PatchOffset = $1F;

// for DEBUG DCU by Pavel Rogulin

OriginalCodeD: Cardinal = $FFF07D83;

PatchedCodeD: Cardinal = $00F07D83;

PatchOffsetD = $2E;

var

PatchResult: TPatchResult;

begin

PatchResult := PatchCode(AddrOfTCustomComboBoxStringsGet, PatchOffset, @OriginalCode, SizeOf(OriginalCode),

@PatchedCode, SizeOf(PatchedCode));

if PatchResult = prNotNeeded then

PatchResult := PatchCode(AddrOfTCustomComboBoxStringsGet, PatchOffsetD, @OriginalCodeD, SizeOf(OriginalCodeD),

@PatchedCodeD, SizeOf(PatchedCodeD));

case PatchResult of

prError:

begin

if IsConsole then

WriteLn(ErrOutput, RsPatchingFailed)

else

MessageBox(0, PChar(RsPatchingFailed), nil, MB_OK or MB_ICONSTOP or MB_TASKMODAL);

RunError(1);

end;

end;

end;

initialization

PatchTCustomComboBoxStringsGet;

end.

本文地址:http://www.xszlo.com/article/2012-11-10/7497.html,转发请保留这个地址,谢谢

0