Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.07.2015, 13:09   #1
fanlis
Пользователь
 
Регистрация: 13.05.2007
Сообщений: 60
Вопрос поиск окна Mozilla FireFox

Здравствуйте.
Задача: нужно найти открытую программу Mozilla FireFox или Google Chrome, определить расположение ее на экране и размеры окна и вывести мое окно справа от нее (привязать к правому краю) (да не важно к какому).
я ищу окно с помощью FindWindow по названию класса MozillaWindowClass для файрфокса и Chrome_WidgetWin_1 для хрома.
Далее с помощью GetWindowRect получаю координаты и размеры окна. Так вот в windows XP все находится нормально, а в windows 7 проблемы с FireFox. Иногда находит все нормально, иногда находит окно с дикими координатами типа -2137,3857 или -32000,-32000, или размерами, несоответствующими те, что я вижу на экране, иногда вообще не находит. Не знаю что работает не правильно: FindWindow или GetWindowRect. То ли окно находится какое-то не то, то ли координаты его определяются неправильно. Что можно сделать?
Код:
procedure TForm1.FormCreate(Sender: TObject);
const
  WCN1 = 'Chrome_WidgetWin_1';
  WCN2 = 'MozillaWindowClass';
var
  WH: HWND;
  WRect: TRect;
begin
//ищем гугл хром по названию класса окна
  WH:=FindWindow(PChar(WCN1),nil);
//если не нашли, ищем мозиллу по названию класса окна
  if WH=0 then
    WH:=FindWindow(PChar(WCN2),nil);

//если что-то нашли
  if WH<>0 then
  begin
    ShowWindow(WH,SW_SHOW); //покажем окно браузера, если оно свернуто
    GetWindowRect(WH,WRect); //получаем координаты и размеры окна браузера

  //может я чего не понимаю, но когда окно свернуто, координаты определяются как -32000,-32000...

    if WRect.Left>-1000 then //на всякий случай
    begin
    //если данное окно (моё) не влезет слева от браузера
      if WRect.Left<Form1.Width+10 then Form1.Left:=WRect.Right+10 //поместим его справа
      else Form1.Left:=WRect.Left-Form1.Width-10; //иначе поместим его слева
      Form1.Top:=Round((WRect.Bottom-WRect.Top-Form1.Height)/2)+WRect.Top;
    end;

  //а если браузер не найден, то окно откроется в штатном режиме
  end;
end;
fanlis вне форума Ответить с цитированием
Старый 15.07.2015, 13:20   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Я бы на твоем месте еще сюда для теста прикрутил получение текста заголовка окна найденного. Чтоб посмотреть то ли окно программа находит.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 15.07.2015, 13:49   #3
fanlis
Пользователь
 
Регистрация: 13.05.2007
Сообщений: 60
По умолчанию

в заголовке пишется название вкладки (т.е. зависит от открытых сайтов) и естественно все время разное.
fanlis вне форума Ответить с цитированием
Старый 15.07.2015, 13:56   #4
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,434
По умолчанию

В случае с мазиллой это браузер(загружаемые страницы) внутри другого браузера(функционал и вид самого браузера). Окно браузера так же XUL-документ (интерфейс описан на XML-подобном языке, функции на javascript), вот откройте эту ссылку в FireFox: chrome://browser/content/browser.xul так что хэндл ловить будите долго.

Вот сама мазила предлагает варианты: https://developer.mozilla.org/en-US/...Window_Handles

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

Последний раз редактировалось Человек_Борща; 15.07.2015 в 14:04.
Человек_Борща вне форума Ответить с цитированием
Старый 15.07.2015, 13:59   #5
ResourceSpace
Форумчанин
 
Аватар для ResourceSpace
 
Регистрация: 30.06.2015
Сообщений: 353
По умолчанию

Цитата:
ShowWindow(WH,SW_SHOW); //покажем окно браузера, если оно свернуто
Нехорошо так делать.
Цитата:
if WRect.Left>-1000 then //на всякий случай
Это тоже не нужно.

А что означает "привязать к краю"? А то что окно может быть на весь экран или его постоянно кто-то двигает это ничего?
Цитата:
Не знаю что работает не правильно: FindWindow или GetWindowRect.
//может я чего не понимаю, но когда окно свернуто, координаты определяются как -32000,-32000...
У ОгнеЛиса куча окон создаётся. Вы не то окно находите, вот и всё.
А отрицательное положение и должно быть у свёрнутых и невидимых окон.



P.S. Кстати мою версию Хрома тоже не находит.

Последний раз редактировалось ResourceSpace; 15.07.2015 в 14:40. Причина: P.S.
ResourceSpace вне форума Ответить с цитированием
Старый 15.07.2015, 14:30   #6
fanlis
Пользователь
 
Регистрация: 13.05.2007
Сообщений: 60
По умолчанию

ну вообще то, что написано в проге, это мои попытки обойти неправильное нахождение окна. Это все мелочи и будет исправлено. главное что окно не находится правильно.

Ссылку на то, что предлагает сама мозилла изучу, спасибо.
fanlis вне форума Ответить с цитированием
Старый 15.07.2015, 15:05   #7
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,645
По умолчанию

Цитата:
Сообщение от fanlis Посмотреть сообщение
в заголовке пишется название вкладки (т.е. зависит от открытых сайтов) и естественно все время разное.
Stilet дело говорит. Ищи также и по имени. Естественно не в FindWindow, а просто делай GetWindowText (или SendMessage для WM_GETTEXT), у лисы и хрома там дописываются названия браузеров.
0.jpg
Способ может и не самый верный, но шансы подростут
Для разворота окна давно в сети нашёл такой способ
Код:
function ForceForegroundWindow(hwnd: THandle): boolean;
const
SPI_GETFOREGROUNDLOCKTIMEOUT = $2000;
SPI_SETFOREGROUNDLOCKTIMEOUT = $2001;
var
ForegroundThreadID: DWORD;
ThisThreadID: DWORD;
timeout: DWORD;
begin
if IsIconic(hwnd) then
  ShowWindow(hwnd, SW_RESTORE);

if GetForegroundWindow = hwnd then
  Result := True
else
begin
  // Windows 98/2000 doesn"t want to foreground a window when some other
  // window has keyboard focus
  if ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion > 4))
    or
    ((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and
    ((Win32MajorVersion > 4) or ((Win32MajorVersion = 4) and
    (Win32MinorVersion > 0)))) then
  begin
    // Code from Karl E. Peterson, www.mvps.org/vb/sample.htm
    // Converted to Delphi by Ray Lischner
    // Published in The Delphi Magazine 55, page 16
    Result := False;
    ForegroundThreadID := GetWindowThreadProcessID(GetForegroundWindow,
      nil);
    ThisThreadID := GetWindowThreadPRocessId(hwnd, nil);
    if AttachThreadInput(ThisThreadID, ForegroundThreadID, True) then
    begin
      BringWindowToTop(hwnd); // IE 5.5 related hack
      SetForegroundWindow(hwnd);
      AttachThreadInput(ThisThreadID, ForegroundThreadID, False);
      Result := (GetForegroundWindow = hwnd);
    end;

    if not Result then
    begin
      // Code by Daniel P. Stasinski
      SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @timeout, 0);
      SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(0), SPIF_SENDCHANGE);
      BringWindowToTop(hwnd); // IE 5.5 related hack
      SetForegroundWindow(hWnd);
      SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(timeout), SPIF_SENDCHANGE);
    end;
  end
  else
  begin
    BringWindowToTop(hwnd); // IE 5.5 related hack
    SetForegroundWindow(hwnd);
  end;

  Result := (GetForegroundWindow = hwnd);
end;
end; { ForceForegroundWindow }


procedure TForm2.Button1Click(Sender: TObject);
const
  WCN1 = 'Chrome_WidgetWin_1';    name1 = 'Google Chrome';
  WCN2 = 'MozillaWindowClass';    name2 = 'Mozilla Firefox';
var
  WH: HWND;
  WRect: TRect;
  Buf: array[0..199] of Char;
begin
  WH := GetWindow(Handle, gw_HWndFirst);
  while WH <> 0 do begin
    GetWindowText(WH, Buf, sizeof(Buf));
    if pos(name2, StrPas(Buf) )>0 then begin
      ForceForegroundWindow(WH);
      GetWindowRect(WH,WRect);
      break;
    end;
    WH := GetWindow(WH, gw_hWndNext);
  end;

  if WRect.Left<Form2.Width+10 then Form2.Left:=WRect.Right+10 //поместим его справа
    else Form2.Left:=WRect.Left-Form2.Width-10; //иначе поместим его слева
    Form2.Top:=Round((WRect.Bottom-WRect.Top-Form2.Height)/2)+WRect.Top;

end;
Хром сам добавишь по аналогии
eoln вне форума Ответить с цитированием
Старый 15.07.2015, 15:19   #8
ResourceSpace
Форумчанин
 
Аватар для ResourceSpace
 
Регистрация: 30.06.2015
Сообщений: 353
По умолчанию

Опоздал чуть...
У ОгнеЛиса бывает не ' Mozilla Firefox', а просто ' Firefox'.

Код:
Unit Unit1;

Interface

Uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;

Type
      TForm1 = Class(TForm)
            Timer1: TTimer;
            Procedure FormCreate(Sender: TObject);
            Procedure Timer1Timer(Sender: TObject);
      Private { Private declarations }
            wndToSnap: HWND;
            Function FindChrome(): HWND;
            Function FindFireFox(): HWND;
            Function FindBrowsers(): HWND;
            Procedure SnapToWindow(wnd: HWND);
      Public { Public declarations }
      End;

Var Form1: TForm1;

Implementation

{$R *.dfm}

Function EnumWindowsProc_Search_FF(wnd: HWND; Var param: LPARAM): BooLean; StdCall;
Var Buffer: Array [0..255] Of Char;
Begin
Result:=True;
GetClassName(wnd, Buffer, Length(Buffer));
If Buffer<>'MozillaWindowClass' Then
      Exit;
GetWindowText(wnd, Buffer, Length(Buffer));
If Pos(' Firefox', Buffer)>0 Then
      Begin
      param:=wnd;
      Result:=False;
      End;
End;

Function EnumWindowsProc_Search_Chrome(wnd: HWND; Var param: LPARAM): BooLean; StdCall;
Var Buffer: Array [0..255] Of Char;
Begin
Result:=True;
GetClassName(wnd, Buffer, Length(Buffer));
If Buffer<>'Chrome_WidgetWin_1' Then
      Exit;
GetWindowText(wnd, Buffer, Length(Buffer));
If Pos(' Chrome', Buffer)>0 Then
      Begin
      param:=wnd;
      Result:=False;
      End;
End;

Function TForm1.FindChrome(): HWND;
Begin
Result:=0;
EnumWindows(@EnumWindowsProc_Search_Chrome, Integer(@Result));
End;

Function TForm1.FindFireFox(): HWND;
Begin
Result:=0;
EnumWindows(@EnumWindowsProc_Search_FF, Integer(@Result));
End;

Function TForm1.FindBrowsers(): HWND;
Begin
Result:=FindChrome();
If Result=0 Then
      Result:=FindFireFox();
End;

Procedure TForm1.FormCreate(Sender: TObject);
Begin
wndToSnap:=FindBrowsers();
End;

Procedure TForm1.SnapToWindow(wnd: HWND);
Var R: TRect; wndStyle: Integer;
Begin
wndStyle:=GetWindowLong(wnd, GWL_STYLE);
If (wndStyle And WS_MAXIMIZE)>0 Then
      Begin
      Left:=0;
      Top:=0;
      Exit;
      End;
If (wndStyle And WS_MINIMIZE)>0 Then
      Begin  
      Left:=Screen.WorkAreaWidth+Screen.WorkAreaLeft-Width;
      Top:=Screen.WorkAreaHeight+Screen.WorkAreaTop-Height;
      Exit;
      End;
GetWindowRect(wnd, R);
If R.Left<Width Then
      Left:=R.Right
Else
      Left:=R.Left-Width;
Top:=Round((R.Bottom-R.Top-Height)/2)+R.Top;
End;

Procedure TForm1.Timer1Timer(Sender: TObject);
Begin
If wndToSnap<>0 Then
      SnapToWindow(wndToSnap);
End;

End.
З.Ы. гм... Что именно делает ForceForegroundWindow()?

Последний раз редактировалось ResourceSpace; 15.07.2015 в 15:22.
ResourceSpace вне форума Ответить с цитированием
Старый 16.07.2015, 20:11   #9
fanlis
Пользователь
 
Регистрация: 13.05.2007
Сообщений: 60
По умолчанию

Попробовал код eoln и код ResourceSpace, оба естественно работают.
В общем я понял: смысл в том, чтобы искать еще и по названию окна.
У меня есть какая-то моя старая прога, которая находит все окна на экране и выдает названия их классов и названия самих окон, так вот она мне почему-то не выдавала в названии окна файрфокса слово FireFox, только название вкладки... Поэтому я и не стал искать по названию окна.

Присоединяюсь к вопросу: что именно делает функция ForceForegroundWindow? Выглядит она страшно

Кстати, посмотрел ссылку, по которой сама мозилла там что-то предлагает. Попробовал первый код, где они там ищут детенышей, нифига не находит.
Дальше я в коде не смог разобраться, так как толком не знаю синтаксиса Си.
fanlis вне форума Ответить с цитированием
Старый 17.07.2015, 12:26   #10
ResourceSpace
Форумчанин
 
Аватар для ResourceSpace
 
Регистрация: 30.06.2015
Сообщений: 353
По умолчанию

Ваш код из первого сообщения ищет первое окно с указанным классом из списка. Окна создаваемые браузерами по всей видимости располагаются как попало. Так что ваш код в некоторых случаях бы работал. Проблема в том что этих окон раскидано множество, а что бы определить какой из них нужен требуются дополнительные проверки.

Одна из лучших (и бесплатных) программ - Spy++ идёт вроде со студией. Могу скинуть свою сейчас наверное уже старую копию.
Окна которые были созданы ОгнеЛисом и Хромом (по одной копии, по три вкладки) меня мягко говоря удивили. Многие без Caption (ну эти-то ладно, понятно), но некоторые с такими названиями что я прифигел малость. Но с дописанным названием браузера только одно.

Тоже вникал в ссылку, но таких детей Spy++ не находил.

Цитата:
У ОгнеЛиса бывает не ' Mozilla Firefox', а просто ' Firefox'.
Дополню себя - у моей последней версии поведение: обычный режим - дописывается ' - Mozilla Firefox'; режим группировки вкладок - дописывается ' Firefox'.

Последний раз редактировалось ResourceSpace; 17.07.2015 в 12:29.
ResourceSpace вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Mozilla FireFox 4.0 Beta 8 Adblock Софт 1 02.04.2011 11:26
Mozilla Firefox 4 Bustle Софт 11 02.04.2011 10:23
Mozilla Firefox -=пароли=-!!! 8Акр8 Софт 6 09.09.2009 18:12
Mozilla Firefox zai_1gen Софт 29 13.02.2009 18:08