Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Проблема в водимых параметрах функции


Автор: -Сергей- 2.10.2012, 08:26
Всем привет!
Ребят или лето на дворе или и вправду лыжи не едут....
Короче дело в чем: 
Написал я ф-ю, кот-я ищет в окне родителе контрол по его классу и надписи на нем, и если находит, то возвращает его хэндл:
Код

function GetCtrlHandle(aParent: HWND; aClassName: String; aText: String): HWND;
  function EnumProc(aHwnd: HWND; RetValue: PDWORD): BOOL; stdcall;
    var aBuffClass: String[255];
    var aBuffText: String[255];
    begin
      SetLength(aBuffclass, GetClassName(aHwnd, @aBuffClass[1], 254));
      SetLength(aBufftext, SendMessage(aHwnd, WM_GETTEXT, 254, LPARAM(@aBuffText[1])));
      Result := Not ( (aClassName = aBuffClass) and (aText = aBuffText) );
      If Not Result Then
        RetValue^ := aHwnd;
    end;
begin
   EnumChildWindows(aParent, @EnumProc, DWORD(@Result));
end;

Например будем искать на "чужой" форме кнопку TButton с текстом Обновить.
Код

  Memo1.Lines.Add(IntToStr(GetCtrlHandle(FindWindow('TfrmMain', nil), 'TButton', 'Обновить')));

И процедура выдает Accecc Violation .....
Но если вот это сравнение изменить
Код

Result := Not ( (aClassName = aBuffClass) and (aText = aBuffText) );

и вместо вводимых параметров функции заменить глобальными переменными, то все работает.
например изменить функцию вот так:
Код

var
  gClassName: String; 
  gText: String;

.......

function GetCtrlHandle(aParent: HWND; aClassName: String; aText: String): HWND;
  function EnumProc(aHwnd: HWND; RetValue: PDWORD): BOOL; stdcall;
    var aBuffClass: String[255];
    var aBuffText: String[255];
    begin
      SetLength(aBuffclass, GetClassName(aHwnd, @aBuffClass[1], 254));
      SetLength(aBufftext, SendMessage(aHwnd, WM_GETTEXT, 254, LPARAM(@aBuffText[1])));
      Result := Not ( (gClassName = aBuffClass) and (gText = aBuffText) );
      If Not Result Then
        RetValue^ := aHwnd;
    end;
begin
   gClassName := aClassName;
   gText := aText;
   EnumChildWindows(aParent, @EnumProc, DWORD(@Result));
end;

тогда все работает.
Подскажите в чем причина понять не могу.

Автор: Illusion Dolphin 2.10.2012, 08:52
У вас неправильно передаются параметры:
Код

type
  TWinEnumParameters = class
    aClassName: string;
    aText: string
  end;

function EnumChildProc(aHwnd: hWnd; iParam: LongInt): Boolean; stdcall;
var
  aBuffClass: String[255];
  aBuffText: String[255];
  Params: TWinEnumParameters;
begin
  Params := TWinEnumParameters(iParam);
  SetLength(aBuffclass, GetClassName(aHwnd, @aBuffClass[1], 254));
  SetLength(aBufftext, SendMessage(aHwnd, WM_GETTEXT, 254, LPARAM(@aBuffText[1])));

  Result := not ( (Params.aClassName = aBuffClass) and (Params.aText = aBuffText) );
end;

function GetCtrlHandle(aParent: HWND; aClassName: String; aText: String): HWND;
var
  Params: TWinEnumParameters;
begin
  Params := TWinEnumParameters.Create;
  try
    EnumChildWindows(aParent, @EnumChildProc, DWORD(Params));
  finally
    Params.Free;
  end;
end;



MSDN:
Код

BOOL CALLBACK EnumChildProc(
  _In_  HWND hwnd,
  _In_  LPARAM lParam
);

Автор: -Сергей- 2.10.2012, 09:25
А где теперь результат от GetCtrlHandle?

Автор: Illusion Dolphin 2.10.2012, 09:56
Цитата

А где теперь результат от GetCtrlHandle? 

Ой - забыл что-то про него. Что-то вроде этого.
Код

type
  TWinEnumParameters = class
    aClassName: string;
    aText: string;
    Result: HWND;
  end;

function EnumChildProc(aHwnd: hWnd; iParam: LongInt): Boolean; stdcall;
var
  aBuffClass: string[255];
  aBuffText: string[255];
  Params: TWinEnumParameters;
begin
  Params := TWinEnumParameters(iParam);
  SetLength(aBuffclass, GetClassName(aHwnd, @aBuffClass[1], 254));
  SetLength(aBufftext, SendMessage(aHwnd, WM_GETTEXT, 254, LPARAM(@aBuffText[1])));

  Result := not ((Params.aClassName = aBuffClass) and (Params.aText = aBuffText));
  if not Result then
    Params.Result := aHwnd;
end;

function GetCtrlHandle(aParent: HWND; aClassName: String; aText: String): HWND;
var
  Params: TWinEnumParameters;
begin
  Params := TWinEnumParameters.Create;
  try
    Params.aClassName := aClassName;
    Params.aText := aText;
    EnumChildWindows(aParent, @EnumChildProc, DWORD(Params));
    Result := Params.Result;
  finally
    Params.Free;
  end;
end;

Автор: -Сергей- 2.10.2012, 10:03
smile ну я так и сделал. Правда костыль какой-то. Но имхо по-другому никак...

Автор: bems 4.10.2012, 15:30
и коллбек-функция не может быть вложенной

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)