gpt4 book ai didi

Delphi 指针、数组、句柄

转载 作者:行者123 更新时间:2023-12-03 19:31:39 26 4
gpt4 key购买 nike

我无法理解使用自定义记录并制作记录数组然后指向该记录的指针的指针,特别是我想要实现的是使用给定的类名为每个顶级窗口句柄制作记录,这意味着有超过 1,对于我使用的每个窗口 EnumChildWindow获取带有 in 的子窗口的句柄。我想记录其中的每一个并将其传递给带有标题的组合框,并使该记录成为该项目的对象,以便以后可以通过选择它来访问每个记录的对象。

我的问题是我对指针的处理,在第一次将任何添加到一个数组记录时,我一直被拒绝访问。

在这里休息

Param[Form1.iEnumWin].MainHwnd:= aHwnd;

这是我正在使用的完整代码,因此人们可以更好地了解我正在尝试做的事情。
implementation

{$R *.dfm}
type
TMyEnumParam = record
sTitle: String;
MainHwnd: Hwnd;
InTxtHwnd: Hwnd;
OutTxtHwnd: Hwnd;
NickListHwnd: Hwnd;
end;
PMyEnumParam = ^TMyEnumParam;

type
ATMyEnumParam = Array[0..9] of PMyEnumParam;
PATMyEnumParam = ^ATMyEnumParam;

{ Get the window Title based on Hwnd }
function GetWindowTitle(HWND: HWND): string;
begin
SetLength(Result, 255);
SetLength(Result, GetWindowText(HWND, PChar(Result), 255));
end;

{ Get the Classname based on Hwnd }
function GetWindowClass(HWND: HWND): string;
begin
SetLength(Result, 255);
SetLength(Result, GetClassName(HWND, PChar(Result), 255));
end;

{ EnumChildWidows Callback Add to our records }
Function EnumChildProc(aHwnd: Hwnd; Param: PMyEnumParam): Boolean; stdcall;
begin
if ((GetDlgCtrlID(aHwnd) = 202) and (isWindowVisible(aHwnd) = True)) then
Param.InTxtHwnd:= aHwnd;

if ((GetDlgCtrlID(aHwnd) = 203) and (isWindowVisible(aHwnd) = True)) then
Param.OutTxtHwnd:= aHwnd;

if ((GetDlgCtrlID(aHwnd) = 1789) and (isWindowVisible(aHwnd) = True)) then
Param.NickListHwnd:= aHwnd;

Result:= True;
end;

{ EnumWindow fill our array of records for each window }
function EnumWindowsProc(aHwnd: HWND; Param: PATMyEnumParam): BOOL; stdcall;
begin
Result := True;
if GetWindowClass(aHwnd) = 'DlgGroupChat Window Class' then
begin
Param[Form1.iEnumWin].MainHwnd:= aHwnd;
Param[Form1.iEnumWin].sTitle:= GetWindowTitle(aHwnd);
EnumChildWindows(aHwnd, @EnumChildProc, LParam(@Param[Form1.iEnumWin]));
Form1.cbbRooms.AddItem(Param[Form1.iEnumWin].sTitle, TObject(Param[form1.iEnumWin]));
inc(Form1.iEnumWin);
end;
end;

{ On change display room Title for each item }
procedure TForm1.cbbRoomsChange(Sender: TObject);
var
i: Integer;
aHwnd: PMyEnumParam;
begin
i := cbbRooms.ItemIndex;
if cbbRooms.ItemIndex <> -1 then
begin
aHwnd:= PMyEnumParam(cbbRooms.Items.Objects[i]);
if aHwnd.MainHwnd > 0 then
begin
ShowMessage(aHwnd.sTitle);
end;
end;

end;

{ Call EnumWindows and fill our array records }
procedure TForm1.FormCreate(Sender: TObject);
var
arInfo: PATMyEnumParam;
begin
iEnumWin:= 0;
EnumWindows(@EnumWindowsProc, LParam(@arInfo));
end;

如果有人能指出(没有双关语)我正确的方向,我将不胜感激。

最佳答案

您的代码有很多问题。这是一个非详尽的列表:

  • 您没有为您的阵列分配任何存储空间。2
  • 你通过^PATMyEnumParamEnumWindows然后将其转换为 PATMyEnumParam在回调中。
  • 您的数组是固定长度的,您不会尝试处理对数组的越界访问。

  • 但是您最大的问题是您的代码在您可以走路之前尝试运行。它具有完全的复杂性和您需要的所有功能。然而,您还无法成功调用 EnumWindows 的电话。 .

    我在这里最大的建议不是细节,而是解决问题的一般性。从编写一段简单的代码开始。明白它。然后增强它。

    因此,在这方面,这里是如何调用 EnumerateWindows :
    program EnumWindowsDemo_17620346;

    {$APPTYPE CONSOLE}

    uses
    System.SysUtils, Winapi.Windows, Generics.Collections;

    type
    TWindowInfo = record
    Handle: HWND;
    // expand with more fields in due course
    end;

    function EnumWindowProc(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
    var
    WindowList: TList<TWindowInfo>;
    WindowInfo: TWindowInfo;
    begin
    WindowList := TList<TWindowInfo>(lParam);
    WindowInfo.Handle := hwnd;
    WindowList.Add(WindowInfo);
    Result := True;
    end;

    procedure Main;
    var
    WindowList: TList<TWindowInfo>;
    WindowInfo: TWindowInfo;
    begin
    WindowList := TList<TWindowInfo>.Create;
    try
    EnumWindows(@EnumWindowProc, LPARAM(WindowList));
    for WindowInfo in WindowList do
    Writeln(WindowInfo.Handle);
    finally
    WindowList.Free;
    end;
    end;

    begin
    Main;
    Readln;
    end.

    从这里开始,您可以扩展这个概念,因为所有棘手的部分都已经处理好了。特别是指针、强制转换和内存管理。

    关于Delphi 指针、数组、句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17620346/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com