Do pobrania wszystkich okien w systemie służy funkcja EnumWindowsProc (wiadomo [...] ). Okna można przefiltrować tak aby otrzymać tylko te istotne.
Po pierwsze sprawdzić czy funkcja IsWindowVisible zwraca true. Tak odpada 9/10 okien. Można jeszcze zrobić GetWindowLong(whandle,GWL_EXSTYLE) i sprawdzić czy wynik tej funkcji jest różny od WS_EX_TOOLWINDOW. Parametr WS_EX_TOOLWINDOW używa się aby ukryć aplikacje z pasak zadań.
Wiec powinno działać. Potrzebuje otrzymać tylko te okna , które są wyświetlane na pasku zadań , albo te , które widać w zakładce "Aplikacje" po wciśnięciu Alt+Crtl+Del. Nie mogę wykombinować jak to zrobić. Bardzo proszę o pomoc ;)
Naprawdę nikt nie wie jak to zrobić ?
Spróbuj może tak:
function EnumWindowsProc(Wnd : HWnd;Form : TForm1) : Boolean;
var
Buffer : Array[0..99] of char;
begin
GetWindowText(Wnd,Buffer,100);
if StrLen(Buffer) <> 0 then
Form.ListBox1.Items.Add(StrPas(Buffer));
Result := True;
end;
Niestety to nie działa. Dla przykładu , gdy mam uruchomione Delhi , to w ListBox1 są dwie pozycję o tym samym tytule , różnią się tylko nazwą klasy (no i Handle też ;) ). Albo Gadu-Gadu. Gdy ktoś staję się dostępnym , to pokazuje się taki dymek , a w moim ListBox1 i tak są wpisywane to okno... I skończyły mi się pomysły :(
Jeżeli to jedyne problemy a już sprawdzasz uchwyty to zrób:
MainFormHwnd:=GetAncestor(Hwd,GA_ROOTOWNER);
a otrzymasz uchwyt głównej formy podając Hwd wyłapane. Porównaj z tym na liście i jęzeli się powtatza to nie dopisuj.
Rozwiązałem wreszcie ten problem. Jeśli ktoś to potrzebuje to prawidłowe rozwiązanie to procesy :) Trzeba zapisywać ID Procesów okien i jeśli jakieś okno ma to samo ID to nie dopisywać :
function EnumWindowsProc(wHandle: HWND): Boolean; StdCall; Export;
var
ext: integer;
begin
Result:=True;
if IsWindowVisible(wHandle) then
begin
ext:=GetWindowLong(whandle,GWL_EXSTYLE);
if (GetParent(Whandle)=0) and (ext<>ext or WS_EX_TOOLWINDOW) and(ext<>ext or WS_CHILDWINDOW) and (ext<>ext or WS_CHILD) and (IsWindow(whandle)) and (AppyID.Lines.IndexOf(inttostr(GetWindowThreadProcessId(Whandle)))=-1) then
begin
AppyID.Lines.add(inttostr(GetWindowThreadProcessId(WHandle)));
Appy.Lines.add(inttostr(wHandle));
end;
end;
end;
Gdzie Appy to TMemo ze Handle okien widocznych na pasku zadań , a AppyID to Tmemo przechowujące identyfikatory procesów...