zoukankan      html  css  js  c++  java
  • Delphi 设置Windows API的回调函数为类的方法

    参考 SysUtils中TLanguages里面的技巧

    { This stores the languages that the system supports }

    TLanguages = class

    private

    FSysLangs: array of TLangRec;

    function LocalesCallback(LocaleID: PChar): Integer; stdcall;

    function GetExt(Index: Integer): string;

    function GetID(Index: Integer): string;

    function GetLCID(Index: Integer): LCID;

    function GetName(Index: Integer): string;

    function GetNameFromLocaleID(ID: LCID): string;

    function GetNameFromLCID(const ID: string): string;

    function GetCount: integer;

    public

    constructor Create;

    function IndexOf(ID: LCID): Integer;

    property Count: Integer read GetCount;

    property Name[Index: Integer]: string read GetName;

    property NameFromLocaleID[ID: LCID]: string read GetNameFromLocaleID;

    property NameFromLCID[const ID: string]: string read GetNameFromLCID;

    property ID[Index: Integer]: string read GetID;

    property LocaleID[Index: Integer]: LCID read GetLCID;

    property Ext[Index: Integer]: string read GetExt;

    end platform;

    { Called for each supported locale. }

    function TLanguages.LocalesCallback(LocaleID: PChar): Integer; stdcall;

    var

    AID: LCID;

    ShortLangName: string;

    GetLocaleDataProc: function (ID: LCID; Flag: DWORD): string;

    begin

    if Win32Platform = VER_PLATFORM_WIN32_NT then

    GetLocaleDataProc := @GetLocaleDataW

    else

    GetLocaleDataProc := @GetLocaleDataA;

    AID := StrToInt('$' + Copy(LocaleID, 5, 4));

    ShortLangName := GetLocaleDataProc(AID, LOCALE_SABBREVLANGNAME);

    if ShortLangName <> '' then

    begin

    SetLength(FSysLangs, Length(FSysLangs) + 1);

    with FSysLangs[High(FSysLangs)] do

    begin

    FName := GetLocaleDataProc(AID, LOCALE_SLANGUAGE);

    FLCID := AID;

    FExt := ShortLangName;

    end;

    end;

    Result := 1;

    end;

    constructor TLanguages.Create;

    type

    TCallbackThunk = packed record

    POPEDX: Byte;

    MOVEAX: Byte;

    SelfPtr: Pointer;

    PUSHEAX: Byte;

    PUSHEDX: Byte;

    JMP: Byte;

    JmpOffset: Integer;

    end;

    var

    Callback: TCallbackThunk;

    begin

    inherited Create;

    Callback.POPEDX := $5A;

    Callback.MOVEAX := $B8;

    Callback.SelfPtr := Self;

    Callback.PUSHEAX := $50;

    Callback.PUSHEDX := $52;

    Callback.JMP := $E9;

    Callback.JmpOffset := Integer(@TLanguages.LocalesCallback) - Integer(@Callback.JMP) - 5;

    EnumSystemLocales(TFNLocaleEnumProc(@Callback), LCID_SUPPORTED);

    end;

    function TLanguages.GetCount: Integer;

    begin

    Result := High(FSysLangs) + 1;

    end;

    function TLanguages.GetExt(Index: Integer): string;

    begin

    Result := FSysLangs[Index].FExt;

    end;

    function TLanguages.GetID(Index: Integer): string;

    begin

    Result := HexDisplayPrefix + IntToHex(FSysLangs[Index].FLCID, 8);

    end;

    function TLanguages.GetLCID(Index: Integer): LCID;

    begin

    Result := FSysLangs[Index].FLCID;

    end;

    function TLanguages.GetName(Index: Integer): string;

    begin

    Result := FSysLangs[Index].FName;

    end;

    function TLanguages.GetNameFromLocaleID(ID: LCID): string;

    var

    Index: Integer;

    begin

    Index := IndexOf(ID);

    if Index <> - 1 then Result := Name[Index];

    if Result = '' then Result := sUnknown;

    end;

    function TLanguages.GetNameFromLCID(const ID: string): string;

    begin

    Result := NameFromLocaleID[StrToIntDef(ID, 0)];

    end;

    function TLanguages.IndexOf(ID: LCID): Integer;

    begin

    for Result := Low(FSysLangs) to High(FSysLangs) do

    if FSysLangs[Result].FLCID = ID then Exit;

    Result := -1;

    end;

    //==================================

    将类的方法巧妙的变成windowsAPI的回调函数,

    由于类的方法调用时隐含类指针,隐藏在调用时,这里通过一个TCallbackThunk实现在调用时直接跳过类指针来到真实的

    方法地址。这种应用需要对类的方法使用过程以及汇编语言中函数调用过程熟悉才能做到。

  • 相关阅读:
    JDK代理(必须代理类要实现一个接口)
    Spring整合jdbc
    Python 之正则匹配
    Spark ML 之 LR逻辑回归实现排序
    Spark 之 读取配置连接Mysql和上传到HDFS
    Spark ML 之 推荐算法项目(上)
    Spark ML 之 推荐算法项目(下)
    Spark ML 之 ALS内存溢出的解决办法
    Spark ML 之 基于协同过滤的召回算法
    Spark ML 特征处理类之 VectorAssembler 向量装配转换器/VectorIndexer
  • 原文地址:https://www.cnblogs.com/caibirdy1985/p/4232982.html
Copyright © 2011-2022 走看看