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


Автор: dee63 7.1.2008, 00:35
Доброго времени, друзья.
У меня тут вопросец возник в связи с одной проблемой.
Значит задача такая-надо узнать входит ли слово в заголовок окна, и если входит, то убить процесс пораждающий окно.
чтение слов идет из строкового массива. я вот как делаю
Код

for i:=1 to 9 do
  begin
    wind:=findwindow(nil,0); // получаем идентификатор окна
    getwindowtext(wind,title,900);//получаем заголовок окна, окно выбирается по идентификатору, строка не более 900
    if pos(s[i],string(title))<>0 then //проверка вхождения слова из массива в строку
      if DestroyWindow(wind)=true then //слово входит-убиваем программу с идентификатором.
      showmessage('Forbidden!')

и вот в  if pos(s[i],string(title))<>0 then //проверка вхождения слова из массива в строку
возникает ошибка обращения к памяти Eacces Violation.
скажите пожалуйста что я делаю не так?
     
   

Автор: Yanis 7.1.2008, 00:57
Цитата(dee63 @  7.1.2008,  01:35 Найти цитируемый пост)
 if pos(s[i],string(title))<>0 then 

Ошибка точно возникает в этой строке? Или оладчик на этой строке останавливается при возникновении AV?

Автор: dee63 7.1.2008, 22:19
Да я сейчас вообще нифига не пойму. стоит таймер которому передаются значения времени при нажатии кнопки, а он зараза срабатывает уже приоткрытии формы.... smile 

Автор: Yanis 8.1.2008, 01:57
Enabled значит выставлено в True.
Что по поводу основного вопроса… Посмотри как это http://www.yandex.ru/yandsearch?text=%CA%E0%EA+%ED%E0%E9%F2%E8+%EE%EA%ED%EE+%EF%EE+%ED%E5%EF%EE%EB%ED%EE%EC%F3+%ED%E0%E7%E2%E0%ED%E8%FE%3F.

Автор: dee63 8.1.2008, 20:11
Yanis, на счет таймера и ссылки-спасибо. 
Я вот нарыл там функцию вот какую:
Код

function tform1.Find(s: string): hWnd;
var
  Wnd: hWnd;
  buff: array[0..127] of Char;
begin
  Find := 0; // значение функции
  //Wnd := GetWindow(Handle, gw_HWndFirst);
  for wnd:=1 to 3 {while wnd<>0 //это было}  do
  begin
    if (Wnd <> Application.Handle) and
      IsWindowVisible(Wnd) and
      (GetWindow(Wnd, gw_Owner) = 0) and
      (GetWindowText(Wnd, buff, sizeof(buff)) <> 0) then
    begin
      GetWindowText(Wnd, buff, sizeof(buff));
        if pos(s, StrPas(buff)) > 0 then
          begin
            Find := Wnd; 
            break;
          end;
    end;
    {Wnd := GetWindow(Wnd, gw_hWndNext);  //так было}   
  end;
end;


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

procedure Tform1.closeprocess;
var
wind:Hwnd;
//s:array[1..9] of string;-описан как глобальный массив для всей программы
i:integer;
begin
  for i:=1 to 9 do
  begin
    wind:=find(s[i]);   //нашли окно в кот сод строка
    if wind<>0 then
    PostMessage(FindWindow(pansichar(Wind),'Forbidden!'), WM_QUIT, 0, 0);
end;

  end;


функция Find прост не находит НИКОГДА(!) идетификатор моего окна(т.е. при использовании ее в виде "Как было"). и приложение его пораждающее, соответственно, не закрывается smile 
Может я  не правильно в чем то ее использую?

Автор: MetalFan 8.1.2008, 20:27
Цитата(dee63 @  8.1.2008,  20:11 Найти цитируемый пост)
 for wnd:=1 to 3 

что-то я не понял этого бреда...

Автор: dee63 8.1.2008, 20:31
та ну ето что б он не все что угодно просматривал а ток конрентый диапазон.
прост в исходной версии он слиииишком долго думает и потом завершается+для трассироки удобнее такие значения маленькие брать.

Автор: MetalFan 9.1.2008, 11:45
Цитата(dee63 @  8.1.2008,  20:31 Найти цитируемый пост)
та ну ето что б он не все что угодно просматривал а ток конрентый диапазон.

ну-ну...
с чего ты взял, что хэндлы окон находятся в этом диапазоне?

Автор: dee63 9.1.2008, 13:51
MetalFan, просто даже если брать просмотр по окнам т.е
Код

...
while wnd<>0 do ...
...
...
Wnd := GetWindow(Wnd, gw_hWndNext)

то функция эта все равно не находит окно ИЕ с ключевым словом в заголовке...
я не утверждаю что хэндлы именно в том диапазоне были. прост использовал эти значения при трассировке чтоб посмотреть как выполныется функция.
Щас вот еще кое чего выдумал-попробую, может исправлю.

Автор: MetalFan 9.1.2008, 17:05
возможно заголовок длиннее 128 символов...

Автор: Yanis 9.1.2008, 20:00
а возможно потому что:
Цитата
Pos searches for Substr within S and returns an integer value that is the index of the first character of Substr within S. Pos is case-sensitive. If Substr is not found, Pos returns zero.

Автор: source777 9.1.2008, 20:51
Цитата

то функция эта все равно не находит окно ИЕ с ключевым словом в заголовке...
Находит...
Код

function FindWindowByPartOfCaption(s: string): hWnd;
var
  Wnd: hWnd;
  buff: array[0..512] of Char;
begin
  Result:= 0;
  Wnd := GetWindow(FindWindow('IEFrame', nil), gw_HWndFirst);
  while wnd<>0 do
  begin
    if (Wnd <> Application.Handle) and
      IsWindowVisible(Wnd) and
      (GetWindow(Wnd, gw_Owner) = 0) and
      (GetWindowText(Wnd, buff, sizeof(buff)) <> 0) then
    begin
      GetWindowText(Wnd, buff, sizeof(buff));
        if pos(s, StrPas(buff)) > 0 then
          begin
            Result:= Wnd;
            break;
          end;
    end;
    Wnd := GetWindow(Wnd, gw_hWndNext);  
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var h: hwnd;
begin
  h:= FindWindowByPartOfCaption('Authorization Required');
  ShowWindow(h, SW_MAXIMIZE);
end;


Добавлено через 6 минут и 7 секунд
Цитата

    wind:=find(s[i]);   //нашли окно в кот сод строка
    if wind<>0 then
    PostMessage(FindWindow(pansichar(Wind),'Forbidden!'), WM_QUIT, 0, 0);
у тебя Find вообще-то хэндл возвращает, нахрена ещё FindWindow?
Код

PostMessage(Wind, WM_QUIT, 0, 0);

Автор: dee63 9.1.2008, 21:05
Yanis, вообщем  оказалось что длина строки 511 подошла больше=)
а вообще фигня какая то получается
Код

function tform1.Find(s: string): hWnd;
var
  Wnd: hWnd;
  buff: array[0..255] of Char;
begin
  Find := 0; // значение функции
  Wnd := GetWindow(Handle, gw_HWndFirst);
  while wnd<>0 do
  begin
    if (Wnd <> Application.Handle) and
      IsWindowVisible(Wnd) and
      (GetWindow(Wnd, gw_Owner) = 0) and
      (GetWindowText(Wnd, buff, sizeof(buff)) <> 0) then
    begin
      GetWindowText(Wnd, buff, sizeof(buff));
        if pos(s, StrPas(buff)) <> 0 then
          begin
            Find := Wnd; //функции даем указатель окна
            wnd:=GetWindow(wnd, gw_hwndNext);// перем след окно
          end
        else
          wnd:=GetWindow(wnd, gw_hwndNext);// перем след окно
    end;
    //Wnd := GetWindow(Wnd, gw_hWndNext);   // берем след окно
  end;
end;




обращение к ней
Код

procedure Tform1.closeprocess;
var
wind:Hwnd;
s:array[1..9] of string;
title:pchar;
i:integer;
begin
s[1]:=form1.checkbox1.caption;
s[2]:=form1.checkbox2.caption;
s[3]:=form1.checkbox3.caption;
s[4]:=form1.checkbox4.caption;
s[5]:=form1.checkbox5.caption;
s[6]:=form1.checkbox6.caption;
s[7]:=form1.checkbox7.caption;
s[8]:=form1.checkbox8.caption;
s[9]:=form1.checkbox9.caption;
  for i:=1 to 9 do
  begin
    wind:=find(s[i]);   //нашли окно в кот сод строка
    if wind<>0 then
    PostMessage(FindWindow(pansichar(Wind),'Forbidden!'), WM_QUIT, 0, 0);    
  end;

  end;



при выполнении результативность равна 0, а загрузка проца=100% smile 

что ж я не пральна организовываю?

Автор: Magik 10.1.2008, 16:36
Цитата(dee63 @ 9.1.2008,  13:51)
MetalFan, просто даже если брать просмотр по окнам т.е
Код

...
while wnd<>0 do ...
...
...
Wnd := GetWindow(Wnd, gw_hWndNext)

то функция эта все равно не находит окно ИЕ с ключевым словом в заголовке...
я не утверждаю что хэндлы именно в том диапазоне были. прост использовал эти значения при трассировке чтоб посмотреть как выполныется функция.
Щас вот еще кое чего выдумал-попробую, может исправлю.

При таком коде не все окна  просматриваются.  Только окна одного уровня. Окна следующего уровня вызываются функцией GetWindow(HWND, GW_CHILD). То есть сначала я бы нашёл окна первого уровня  через GetWindow(HWND, GW_HWNDNEXT) (пока HWND<>0), затем перешёл на следующий (через GetWindow(HWND, GW_CHILD), и далее через GetWindow(HWND, GW_HWNDNEXT) просмотрел все окна этого уровня . И так, пока GetWindow(HWND, GW_CHILD) не станет равной нулю. Но, хочу заметить то, что и среди окон одного (не первого) просматриваемого уровня могут быть дочерние.
Но это всё можно зациклить. А вообще, для идентификации окон лучше всего использовать специальный софт типа SPY. Там можно узнать все параметры нужного окна и провести навигацию до родительского.

Автор: dee63 13.1.2008, 14:44
Цитата(Magik @  10.1.2008,  16:36 Найти цитируемый пост)
 А вообще, для идентификации окон лучше всего использовать специальный софт типа SPY

а можно поподробнее на эту тему? smile 

Автор: source777 13.1.2008, 16:12
Цитата

а можно поподробнее на эту тему?  
по-подробнее, вместе с примером смотри моё сообщение выше, ты видимо его до сих пор не прочитал... Класс окна IE в моём примере, был найден при помощи WinSpy++

Автор: dee63 19.1.2008, 19:15
source777, пасиба тебе! не знаю конечно что я в своей функции не так написал, мо твоя работает на ура, даже груз проца микроскопический) smile  smile 

Автор: source777 19.1.2008, 21:26
dee63, рад помочь.
Цитата

не знаю конечно что я в своей функции не так написал, мо твоя работает на ура, даже груз проца микроскопический) 
А ты их сравни, полезно будет в учебных целях smile 

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