• 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实现在调用时直接跳过类指针来到真实的

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

  • 相关阅读:
    frame、center和bounds
    UILabel
    UIColor
    Url_Filter(Code)
    listView介绍
    C# 常用正则
    C++指针的概念
    指针所具有的四个要素:
    windows_sendEmail
    工作笔记
  • 原文地址:https://www.cnblogs.com/caibirdy1985/p/4232982.html
Copyright © 2020-2023  润新知