1. unit D7ComboBoxStringsGetPatch;
  2.  
  3. // The patch fixes TCustomComboBoxStrings.Get method for empty string item in Delphi .
  4.  
  5. interface
  6.  
  7. {$IF RTLVersion <> 15.0}
  8.  
  9. 'This patch is intended for Delphi 7 only';
  10.  
  11. {$IFEND}
  12.  
  13. implementation
  14.  
  15. uses
  16.  
  17. Windows, SysUtils, StdCtrls;
  18.  
  19. resourcestring
  20.  
  21. RsPatchingFailed = 'TCustomComboBoxStrings.Get patching failed.';
  22.  
  23. type
  24.  
  25. TPatchResult = (prNotNeeded, prOk, prError);
  26.  
  27. function PatchCode(RoutineStartAddr: Pointer; PatchOffset: Cardinal; OriginalCode: Pointer;
  28.  
  29. OriginalCodeLen: Cardinal; PatchedCode: Pointer; PatchedCodeLen: Cardinal): TPatchResult;
  30.  
  31. const
  32.  
  33. JmpOpCode = $25FF;
  34.  
  35. type
  36.  
  37. PPackageThunk = ^TPackageThunk;
  38.  
  39. TPackageThunk = packed record
  40.  
  41. JmpInstruction: Word;
  42.  
  43. JmpAddress: PPointer;
  44.  
  45. end;
  46.  
  47. var
  48.  
  49. CodeStart: Pointer;
  50.  
  51. BytesWritten: DWORD;
  52.  
  53. begin
  54.  
  55. if FindClassHInstance(System.TObject) <> HInstance then
  56.  
  57. with PPackageThunk(RoutineStartAddr)^ do
  58.  
  59. if JmpInstruction = JmpOpCode then
  60.  
  61. RoutineStartAddr := JmpAddress^
  62.  
  63. else
  64.  
  65. begin
  66.  
  67. Result := prError;
  68.  
  69. Exit;
  70.  
  71. end;
  72.  
  73. CodeStart := Pointer(LongWord(RoutineStartAddr) + PatchOffset);
  74.  
  75. if CompareMem(CodeStart, OriginalCode, OriginalCodeLen) then
  76.  
  77. begin
  78.  
  79. if WriteProcessMemory(GetCurrentProcess, CodeStart, PatchedCode, PatchedCodeLen, BytesWritten) and
  80.  
  81. (BytesWritten = PatchedCodeLen) then
  82.  
  83. begin
  84.  
  85. FlushInstructionCache(GetCurrentProcess, CodeStart, PatchedCodeLen);
  86.  
  87. Result := prOk;
  88.  
  89. end
  90.  
  91. else
  92.  
  93. Result := prError;
  94.  
  95. end
  96.  
  97. else
  98.  
  99. Result := prNotNeeded;
  100.  
  101. end;
  102.  
  103. type
  104.  
  105. TCustomComboBoxStringsHack = class(TCustomComboBoxStrings);
  106.  
  107. function AddrOfTCustomComboBoxStringsGet: Pointer;
  108.  
  109. begin
  110.  
  111. Result := @TCustomComboBoxStringsHack.Get;
  112.  
  113. end;
  114.  
  115. procedure PatchTCustomComboBoxStringsGet;
  116.  
  117. const
  118.  
  119. OriginalCode: Cardinal = $74FFF883; // CMP EAX, - | JZ +$
  120.  
  121. PatchedCode: Cardinal = $7E00F883; // CMP EAX, | JLE +$
  122.  
  123. PatchOffset = $1F;
  124.  
  125. // for DEBUG DCU by Pavel Rogulin
  126.  
  127. OriginalCodeD: Cardinal = $FFF07D83;
  128.  
  129. PatchedCodeD: Cardinal = $00F07D83;
  130.  
  131. PatchOffsetD = $2E;
  132.  
  133. var
  134.  
  135. PatchResult: TPatchResult;
  136.  
  137. begin
  138.  
  139. PatchResult := PatchCode(AddrOfTCustomComboBoxStringsGet, PatchOffset, @OriginalCode, SizeOf(OriginalCode),
  140.  
  141. @PatchedCode, SizeOf(PatchedCode));
  142.  
  143. if PatchResult = prNotNeeded then
  144.  
  145. PatchResult := PatchCode(AddrOfTCustomComboBoxStringsGet, PatchOffsetD, @OriginalCodeD, SizeOf(OriginalCodeD),
  146.  
  147. @PatchedCodeD, SizeOf(PatchedCodeD));
  148.  
  149. case PatchResult of
  150.  
  151. prError:
  152.  
  153. begin
  154.  
  155. if IsConsole then
  156.  
  157. WriteLn(ErrOutput, RsPatchingFailed)
  158.  
  159. else
  160.  
  161. MessageBox(, PChar(RsPatchingFailed), nil, MB_OK or MB_ICONSTOP or MB_TASKMODAL);
  162.  
  163. RunError();
  164.  
  165. end;
  166.  
  167. end;
  168.  
  169. end;
  170.  
  171. initialization
  172.  
  173. PatchTCustomComboBoxStringsGet;
  174.  
  175. 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. centos 6 rsync+inotify 实时同步

    主机名.ip: server 172.31.82.184 client  172.31.82.185 需求: 1.server端 ”/data/server“ 做为client端 “/data/cli ...

  2. python文件操作 seek(),tell()

    seek():移动文件读取指针到指定位置 tell():返回文件读取指针的位置 seek()的三种模式: (1)f.seek(p,0)  移动当文件第p个字节处,绝对位置 (2)f.seek(p,1) ...

  3. Poj 1458 Common Subsequence(LCS)

    一.Description A subsequence of a given sequence is the given sequence with some elements (possible n ...

  4. 【转】 Pro Android学习笔记(三五):Menu(6):XML方式 & PopUp菜单

    目录(?)[-] 利用XML创建菜单 XML的有关属性 onClick事件 Pop-up菜单 利用XML创建菜单 在代码中对每个菜单项进行设置,繁琐且修改不灵活,不能适配多国语言的要求,可以利用资源进 ...

  5. DCloud-MUI:文档 UI组件

    ylbtech-DCloud-MUI:文档 UI组件 1.返回顶部 1.accordion(折叠面板) 折叠面板从二级列表中演化而来,dom结构和二级列表类似,如下: <ul class=&qu ...

  6. C++知识点总结(三)

    1.字符串查找字符函数strchr strchr函数原型:extern char*strchr(const char *s,char c); 功能:查找字符数组s中首次出现字符c的位置 说明:返回首次 ...

  7. 进击的菜鸟问题1(设置checkbox全选)

    问题:设置页面标签属性时,常常使用jquery.attr("","");在设置checkbox属性时,会出现操作设置checkbox属性后,无法清除,导致第二次 ...

  8. 共用体的定义和应用【C++】

    定义: 使用覆盖技术,几个变量相互覆盖,从而使几个不同变量共占同一段内存的结构,成为共同体类型的结构. 共同体的定义类似结构体,不过共同体的所有成员都在同一段内存中存放,起始地址一样,并且同一时刻只能 ...

  9. 19. CTF综合靶机渗透(十二)

    靶机说明: 靶机主题来自美剧<黑客军团> 本次靶机有三个flag,难度在初级到中级,非常适合新手训练学习,不需要逆向技术,目标就是找到三个key,并且拿到主机root权限. 渗透过程: 本 ...

  10. C# Collection was modified;enumeration operation may not execute

    一.问题描述 在做 数组.列表.集合遍历时,可能我们会遇见这个问题.Collection was modified;enumeration operation may not execute ,翻译的 ...