unit D7ComboBoxStringsGetPatch;

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

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, - | JZ  +$

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

  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(, PChar(RsPatchingFailed), nil, MB_OK or MB_ICONSTOP or MB_TASKMODAL);

        RunError();

      end;

  end;

end;

initialization

  PatchTCustomComboBoxStringsGet;

end.

官方BUG解决地址:

http://cc.embarcadero.com/item/18872

(转)TComboBox patch for Delphi 7的更多相关文章

  1. Delphi XE2 之 FireMonkey 入门(42) - 控件基础: TComboBox、TComboEdit

    Delphi XE2 之 FireMonkey 入门(42) - 控件基础: TComboBox.TComboEdit TListBox 有两个兄弟 TComboListBox.TComboEditL ...

  2. delphi连接sql存储过程

    针对返回结果为参数的 一. 先建立自己的存储过程 ALTER PROCEDURE [dbo].[REName] ) AS BEGIN select ROW_NUMBER() over(order by ...

  3. 转:Delphi 6 实用函数

    来自: daocaoren0824, 时间: -- ::, ID: 再给你一份 程序员实用函数 {▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎} {▎ ▎} {▎ 大 ...

  4. delphi里动态创建AlphaControls实现换肤

    AlphaControls是一套Delphi下的优秀的皮肤vcl控件.几年前,一般用得比较多的是vclskin,使用很方便,可惜这套2010年已经停止维护了.后来就看到更多的人开始推崇AlphaCon ...

  5. delphi.指针.应用

    注:初稿...有点乱,可能增删改... 因为指针应用,感觉不好写,请大家指出错误,谢谢. 注意: 本文着重点讲的是指针的各类型的应用或使用,而不是说这种方法不应该+不安全+危险+不提倡使用. 其它:本 ...

  6. Delphi完成的断点续传例子 转

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  7. Delphi经验总结(1)

    先人的DELPHI基础开发技巧 ◇[DELPHI]网络邻居复制文件 uses shellapi; copyfile(pchar('newfile.txt'),pchar('//computername ...

  8. Delphi xe7 FireMonkey / Mobile (Android, iOS)生成 QR Code完整实例

    这个实例在windows.OS X.IOS和Android等平台运行正常.本文参考这个网站提供的方法:http://zarko-gajic.iz.hr/firemonkey-mobile-androi ...

  9. 2年后的Delphi XE6

    1.有幸下载到Delphi XE6,下载地址如下: http://altd.embarcadero.com/download/radstudio/xe6/delphicbuilder_xe6_win. ...

随机推荐

  1. 【LeetCode】012. Integer to Roman

    Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 t ...

  2. iOS中使用NSInvocation

    在iOS中可以使用NSInvocation进行动态调用方法. /* NSInvocation is much slower than objc_msgSend()... Do not use it i ...

  3. 系统原生文件MD5值获取

    windows: certutil -hashfile filePath MD5 certutil -hashfile filePath SHA1   Linux md5sum  filePath s ...

  4. POJ3784:Running Median

    浅谈堆:https://www.cnblogs.com/AKMer/p/10284629.html 题目传送门:http://poj.org/problem?id=3784 用一个"对顶堆& ...

  5. 【转】Pro Android学习笔记(十四):用户界面和控制(2):Text类控制

    目录(?)[-] TextView 例子1在XML中设置autoLink属性 例子2在代码中设置autoLink属性 EditText AutoCompleteTextView MultiAutoCo ...

  6. MongoDB之二基础入门(window/linux安装启动)

    mongodb中有三元素:数据库,集合,文档,其中“集合”就是对应关系数据库中的“表”,“文档”对应“行”. 一window安装与启动 一. 下载 上MongoDB官网 ,下载页面:https://w ...

  7. mysql数据库之表与表之间的关系

    表1 foreign key 表2 则表1的多条记录对应表2的一条记录,即多对一 利用foreign key的原理我们可以制作两张表的多对多,一对一关系 多对多: 表1的多条记录可以对应表2的一条记录 ...

  8. win10系统-javac不是内部或外部命令

    给笔记本装了一个ssd,上午装的系统,重新搞jdk,设置JAVA_HOME之后,cmd运行javac报 “javac不是内部或外部命令”各种懵逼,试了好几次才发现Path路径里面不能用%JAVA_HO ...

  9. web安全之XSS和CSRF

    XSS 跨站脚本攻击(cross site script),本来缩写CSS单位了和层叠样式(Cascading Style Sheet,CSS)有所区别,所以在安全领域叫做“XSS”. XSS攻击,通 ...

  10. Flask14 渲染问题、API、项目文档

    3 前端渲染和后端渲染 这两种渲染都属于动态页面 区分前后端渲染的关键点是站在浏览器的角度 3.1 后端渲染 浏览器请求服务器后获取到的是完整的HTML页面(即:后台已经组装好HTML文件啦),利用f ...