Привет всем, не пинайте сильно за вопрос, так как я еще пока учусь программировать на Delphi.
Короче мне надо перечислить все окна в системе, title которых не равно пустой строке.
Использовал два способа — EnumWindows и GetWindow, однако эти 2 способа дают разные результаты.
Окна, которые не перечисляются в первом способе, перечисляются во втором и наоборот.
Может чего делаю не так, подскажите пожалуйста.
Способ 1: EnumWindows и EnumChieldWindows с callback- oм
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
lst :TStringList;
implementation
{$R *.dfm}
//Просто добавить строку в список
procedure AddToList (s :string);
begin
lst.Add(s);
end;
//Перечислить дочерние окна
function EnumChildProc(wdc :hwnd; Param :LongInt) :boolean; stdcall;
var
buf :array[0..250] of char;
s :string;
begin
GetWindowText(wdc, buf, sizeof(buf));
s := StrPas(buf);
if (s <> '') then
AddToList(s);
EnumChildProc := true;
end;
//Перечислить основные окна
function EnumProc (Wd: HWnd; Param: LongInt): Boolean; stdcall;
var
buf :array[0..250] of char;
s :string;
begin
GetWindowText(wd, buf, sizeof(buf));
s := StrPas(buf);
if (s <> '') and (GetWindowLong(Wd, GWL_HWNDPARENT) = 0) then
begin
AddToList(s);
end else
begin
EnumChildWindows(wd, @EnumChildProc, 0);
end;
EnumProc := true;
end;
var
Wnd : hWnd;
buff: array [0..127] OF Char;
s :string;
begin
lst.Clear;
Wnd := GetWindow(Application.Handle, gw_HWndFirst);
while Wnd <> 0 do
begin
GetWindowText(Wnd, buff, sizeof(buff));
s := StrPas(buff);
if s <> '' then
begin
lst.add(s);
end;
Wnd := GetWindow(Wnd, gw_hWndNext);
end;
end;
Код честно говоря не смотрел, ты бы его хотя бы в [pascal][pascal] обернул
Результаты сильно разнятся? Дело в том, что на результаты GetWindow сильно полагаться не стоит. Пока идет перечисление, окна могут удаляться и создаваться заново. Более того, старые хендлы (фактически это просто число), могут задействоваться для новых окон. С другой стороны, EnumWindows делает снапшот текущих окон и такой проблемы там не существует:
EnumWindows
...
This function is more reliable than calling the GetWindow function in a loop. An application that calls GetWindow to perform this task risks being caught in an infinite loop or referencing a handle to a window that has been destroyed.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re: Перечисление окон Windows
От:
Аноним
Дата:
07.08.06 13:41
Оценка:
DB>Использовал два способа — EnumWindows и GetWindow, однако эти 2 способа дают разные результаты.
Спроси в форуме по виндам, Delphi тут практически не при чём.
DB>function EnumChildProc(wdc :hwnd; Param :LongInt) :boolean; stdcall; DB>var DB> buf :array[0..250] of char; DB> s :string;
DB>begin DB> GetWindowText(wdc, buf, sizeof(buf)); DB> s := StrPas(buf); DB> if (s <> '') then DB> AddToList(s); DB> EnumChildProc := true;
устаревший способ. Лучше используй Result.
DB>end;
А отсюда ты вызываешь EnumChildWindows ? У детей тоже свои дети могут быть.
Здравствуйте, Аноним, Вы писали:
DB>>Использовал два способа — EnumWindows и GetWindow, однако эти 2 способа дают разные результаты.
А>Спроси в форуме по виндам, Delphi тут практически не при чём.
DB>>function EnumChildProc(wdc :hwnd; Param :LongInt) :boolean; stdcall; DB>>var DB>> buf :array[0..250] of char; DB>> s :string;
DB>>begin DB>> GetWindowText(wdc, buf, sizeof(buf)); DB>> s := StrPas(buf); DB>> if (s <> '') then DB>> AddToList(s); DB>> EnumChildProc := true;
А>устаревший способ. Лучше используй Result.
DB>>end;
А>А отсюда ты вызываешь EnumChildWindows ? У детей тоже свои дети могут быть.
DB>> Wnd := GetWindow(Application.Handle, gw_HWndFirst);
А>А если GetWindows(GetDesktopWindow(), GW_CHILD) ?
DB>> Wnd := GetWindow(Wnd, gw_hWndNext);
А>А гдe ты детей перебираешь ?
Так вот в том то и вопрос, как мне прально написать цикл, чтоб перебрать всех детей, всех детей детей и всех родителей, короче всех всех окон windows. А то у меня список явно получается не полный после перечисления.