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. [转]jQuery.extend 函数详解

    JQuery的extend扩展方法:      Jquery的扩展方法extend是我们在写插件的过程中常用的方法,该方法有一些重载原型,在此,我们一起去了解了解.      一.Jquery的扩展方 ...

  2. import module, from module import funtion区别

    import module与from module import funtion区别: import module导入模块后你需要使用module.function()来调用一个函数 from mod ...

  3. CentOS6.5中的vsftpd安装配置

    安装ftp 1.使用chkconfig 来查看是否装有vsftpd服务: 2.使用yum命令直接安装:yum -y install vsftpd 3.然后为它创建日志文件:touch /var/log ...

  4. Logstash 2.0.0 beta2 发布,开源日志管理

    Logstash 是一个应用程序日志.事件的传输.处理.管理和搜索的平台.你可以用它来统一对应用程序日志进行收集管理,提供 Web 接口用于查询和统计. Logstash 现在是 ElasticSea ...

  5. 【转】Pro Android学习笔记(二六):用户界面和控制(14):RelativeLayout

    相对布局:RelativeLayout RelativeLayout也是非常常用的布局,能够精确对控件的位置进行网格对齐,可以设置在控件与其他控件的相对位置,以及控件在容器中的位置.缺省控件的位置为最 ...

  6. python unittest之断言及示例

    python unintest单元测试框架提供了一整套内置的断言方法. 如果断言失败,则抛出一个AssertionError,并标识该测试为失败状态 如果异常,则当做错误来处理 注意:以上两种方式的区 ...

  7. 开源一个windows消息队列查看器

    windows消息简单易用,在异步消息发送场景的使用还是比较适合.为了方便查看队列中的消息和删除一些异常消息,开发了一个简单的小工具拿出来分享下. 源码地址:https://gitee.com/eab ...

  8. JavaScript基础:

    一. JavaScript概述 JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型. document.write("<h1>这是一个标 ...

  9. Appium 在 Android UI 测试中的应用

    原文地址:https://blog.coding.net/blog/Appium-Android-UI Android 测试工具与 Appium 简介 Appium 是一个 C/S 架构的,支持 An ...

  10. raspberry是个什么玩意

    今天Wilson同学取回一个书本大小的包裹,说买回来一台小电脑,只有信用卡大小! 这是第一次听说和看见raspberry Pi. 一块开发板上有四个USB.一个视频接口.一个音频接口.一个网线接口和电 ...