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


Автор: gonzales 14.5.2006, 01:19
Собственно САБЖ

Поясню, 
использую функцию WindowFromPoint(Mouse.CursorPos) для нахождения хандла контрола под мышью, 
а как зная хандл получить информацию о главном окне, на котором расположен контрол (его хандл, имя процесса)

че то затупил, не могу сообразить  smile 

всем заранее спасибо 

Автор: Nickel 14.5.2006, 10:33
Код

uses psapi;

function GetAppFileName (hWnd: THandle) :string;
var dPID: dWord;
    hHandle: THandle;
begin
 GetWindowThreadProcessId(hWnd, @dPID);
 SetLength (Result, MAX_PATH);
 hHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, True, dPID);
 if GetModuleFileNameEx (hHandle, 0, PChar (Result), MAX_PATH) > 0 then SetLength (Result, StrLen (PChar (Result)));
end;

procedure TForm1.Button1Click(Sender: TObject);
var a:array[0..255] of Char;
    h:Cardinal;
begin
 h:=WindowFromPoint(Mouse.CursorPos);
 while GetParent(h)<>0 do
                h:=GetParent(h);
 GetWindowText(h,a,sizeof(a));
 showmessage('Íàçâàíèå îêíà - '+a+#10#13+
      'Õåíäë îêíà - '+inttostr(h)+#10#13+
      'Íàçâàíèå ïðîöåññà - '+GetAppFileName(h));
end;

 

Автор: gonzales 14.5.2006, 12:24
спасибо, не догадался getparent в цикл запуститьsmile

но есть еще одна засада, когда getparent в цикле то в некоторых приложения верхний уровень становится не главное окно, а Tapplication, а мне этого не надо! 
Как этого избежать??? 

Автор: Nickel 14.5.2006, 13:26
Это в каких приложениях? 

Автор: gonzales 15.5.2006, 01:25
например BSPlayer, BeholdTV (это от ТВ-Тюнера) 

Автор: Nickel 15.5.2006, 12:38
Цитата
 в некоторых приложения верхний уровень становится не главное окно, а Tapplication

А с чего ты решил? И неплохо было бы посмотреть код. 

Автор: gonzales 15.5.2006, 13:56
Цитата

А с чего ты решил?


с того, что я выхожу на верхний уровень, получаю хандл контрола, смотрю его класс - и он TAplication

а код  

Код

begin    
 h:=WindowFromPoint(Mouse.CursorPos);    
 while GetParent(h)<>0 do    
                h:=GetParent(h);    
 GetClassName(h,a,sizeof(a));
 

Автор: Nickel 16.5.2006, 16:58
Тут оказывается не всё так просто... Скачал я BSPlayer (BeholdTV решил не стоит, наверняка только со своим тюнером работает). Поковырял его - действительно написан на делфи! Посмотрел в Spy++, действительно у всех окошек плеера Parent - TApplication. Создал своё приложение из 3-ёх форм и обламался, потому что у всех окон нет parent'a , хотя owner так же как и у BSPlayer - TApplication. Вот такая вышла загагулина, однако интуиция подсказала менять все набодряд свойства форм, что дало результат. Parent зависит от BorderStyle. Например если он - bsSingle, то у окошка parent'ом будет TApplication, а если bsSizeable, то то parent'a не будет. Вот такие пироги...
Первый способ решения проблемы:
Код

while GetParent(h)<>0 do begin
                GetClassName(GetParent(h),a,sizeof(a));
                s:=a;
                if s='TApplication' then break;
                h:=GetParent(h);
                end;

Однако, только ли в делфях такой прикол? Да и в принципе при желании TApplication можно переименовать.
Способ намбер два основан на том, что хитрое окошко TApplication имеет размеры 0 на 0 пикселей ( кстати оно висит прям по середине экрана и, как оказалось, в качестве фона использует wallpaper с рабочего стола =):
Код

while GetParent(h)<>0 do begin
                GetWindowRect(GetParent(h),r);
                if (r.Left=r.Right) and (r.Top=r.Bottom) then break;
                h:=GetParent(h);
                end;
 

Автор: gonzales 17.5.2006, 11:05
Цитата

пособ намбер два основан на том, что хитрое окошко TApplication имеет размеры 0 на 0 пикселей


йоу, отличная мысльsmile 
жаль не могу пока тебе репутацию поднять

но все равно спасибо, все работает 

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