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

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

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 11.12.2009, 17:10   #1
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию Как узнать, перекрывается ли моё окно другим окном?

Всем привет. Сабж такой: котроче окно прячется/отображается по улику в трее. Использовать только IsVindowVisible для этой цели не удобно, т.к. окно может не быть скрытым, в понимании виндоус, но зато может перекрываться другими окнами и не отображаться. В такой ситуации надо дважды щёлкнуть в трее, что-бы отобразить окно. Один раз, что-бы его скрыть, а второй раз, что-бы отобразить.
Решил использовать WindowsEnum, но только пока я в лузерах. Не знаю что делать с хенделами, которые мне передаёт виндоус. Как мне поступить?
Altera вне форума Ответить с цитированием
Старый 11.12.2009, 17:59   #2
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

...как насчет сравнить хэндл вашего окна, которым управляете из трея с getforegroundwindow ? если не совпадает и не скрыто, то выводим на передний план setforegroundwindow или setwindowpos c cоответствующим флагом, если не совпадает и скрыто, то showwindow, ну и так далее все варианты...
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 11.12.2009, 18:10   #3
Д'якон
Форумчанин
 
Регистрация: 05.12.2007
Сообщений: 236
По умолчанию

Создавай определенный класс окна и смотри что за класс. Или смотри какому процессу принадлежит окно. А если сам пишешь программу, тогда вообще непонятно зачем это все, выводи просто поверх всех окон.
Д'якон вне форума Ответить с цитированием
Старый 11.12.2009, 19:15   #4
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию

Цитата:
Сообщение от Д'якон
Создавай определенный класс окна и смотри что за класс. Или смотри какому процессу принадлежит окно. А если сам пишешь программу, тогда вообще непонятно зачем это все, выводи просто поверх всех окон.
Ты не прав по 2м причинам. Программа то моя, но во-первых не всегда нужно, что-бы окно было поверх всех окон. А во-вторых, ты что, думаешь, что WS_EX_TOPMOST окно не может перекрываться другими такими-же? Окно по-любому может быть перекрыто.

Цитата:
Сообщение от raxp
...как насчет сравнить хэндл вашего окна, которым управляете из трея с getforegroundwindow ? если не совпадает и не скрыто, то выводим на передний план setforegroundwindow или setwindowpos c cоответствующим флагом, если не совпадает и скрыто, то showwindow, ну и так далее все варианты...
Ага, я тоже возлагал на это бооольшие надежды. Проблема в том, что при щелчке в трее форма теряет фокус (он переходит на иконку в трее), а значи окно никогда не foreground. К тому-же, если окно перекрывается WS_EX_TOPMOST окнами, то getForegroundWindow может вернуть хендел моего окна, если оно активно, не смотря на то, что оно полностью перекрывается и не отображается на экране.

В общем не всё так просто как хотелось бы.

Последний раз редактировалось Altera; 11.12.2009 в 19:17.
Altera вне форума Ответить с цитированием
Старый 11.12.2009, 19:21   #5
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

От сердца отрываю Использую Unicode версию дельфи

Код:
function ZOrderIndex(wnd: DWord): Integer;
var
  w: DWord;
begin
  Result := 0;
  w := FindWindow('Progman', NIL);
  while (w <> 0) and (w <> wnd) do
  begin
    Inc(Result);
    w := GetWindow(w, GW_HWNDPREV);
  end;
end;

type
  PEnumData = ^TEnumData;
  TEnumData = record
    Handle: HWND;
    ZOrder: Integer;
    Rect: TRect;
    Intersect: Boolean;
  end;

function EnumWindowsProc(hwnd: HWND; EnumData: PEnumData): BOOL; stdcall;
var
  r: TRect;
  ClassName: array[0..255] of WChar;
begin
  if IsWindowVisible(hwnd) and not IsIconic(hwnd) and (EnumData^.Handle <> hwnd) and
    (GetWindowLong(hwnd, GWL_HWNDPARENT) = 0) and
    (GetWindowLong(hwnd, GWL_EXSTYLE) and WS_EX_TOPMOST = 0) then
  begin
    GetWindowRect(hwnd, r);

    if IntersectRect(r, EnumData^.Rect, r) then
    begin
      GetClassName(hwnd, ClassName, 255);

      if (ClassName <> 'Progman') and (ZOrderIndex(hwnd) > EnumData^.ZOrder) then
      begin
        EnumData^.Intersect := True;
        Exit(False);
      end;
    end;
  end;

  Result := True;
end;

// somewhere in your code

if IsWindowVisible(MyWindowHandle) then
begin
      // hope you understand what I meant under "My***" :)
      EnumData.rect := MyWindowRect;
      EnumData.Handle := MyWindowHandle;
      EnumData.ZOrder := ZOrderIndex(MyWindowHandle);
      EnumData.Intersect := False;
      EnumWindows(@EnumWindowsProc, Integer(@EnumData));

      if EnumData.Intersect then
        ForceForegroundWindow(MyWindowHandle)
      else
        ShowWindow(MyWindowHandle, SW_HIDE);
end else
begin
  ShowWindow(MyWindowHandle, SW_SHOW);
end;

Последний раз редактировалось BOBAH13; 11.12.2009 в 19:26.
BOBAH13 вне форума Ответить с цитированием
Старый 11.12.2009, 20:48   #6
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию

Что за ForceForegroundWindow? Нету не в справке не в MSDN
Altera вне форума Ответить с цитированием
Старый 11.12.2009, 20:54   #7
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Цитата:
Сообщение от Altera Посмотреть сообщение
Что за ForceForegroundWindow? Нету не в справке не в MSDN
Ну емае... поставьте SetForegroundWindow
BOBAH13 вне форума Ответить с цитированием
Старый 11.12.2009, 23:09   #8
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию

Цитата:
Сообщение от BOBAH13 Посмотреть сообщение
Ну емае... поставьте SetForegroundWindow
Хорошо, вроде-бы работает. Разобраться только осталось толком. А так, респектус!
Altera вне форума Ответить с цитированием
Старый 12.12.2009, 11:05   #9
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию

2BOBAH13. А зачем нужно что-бы
GetWindowLong(hwnd, GWL_HWNDPARENT) = 0? Я её закоментировал и стало лучше.
Код:
function EnumWindowsProc(hwnd: HWND; lParam: integer): boolean; stdcall;
label checkIntersect;
var
r: TRect;
ClassName: array[0..255] of WChar;
EnumData: pEnumData;
begin
   EnumData := pointer(lParam);

   if IsWindowVisible(hwnd) and not IsIconic(hwnd) and (EnumData^.Handle <> hwnd) {and
      (GetWindowLong(hwnd, GWL_HWNDPARENT) = 0)} then
   begin
      if (GetWindowLong(hwnd, GWL_EXSTYLE) and WS_EX_TOPMOST = WS_EX_TOPMOST) then
      begin
         if EnumData^.topMost then // Это я ещё одну переменную ввёл, что-бы знать, целевое окно у меня поверх всех окон или нет. 
            goto checkIntersect
         else
            exit(true);
      end
      else
         goto checkIntersect;
   end
   else
      exit(true);

   checkIntersect:
   begin
      GetWindowRect(hwnd, r);

      if IntersectRect(r, EnumData^.Rect, r) then
      begin
         GetClassName(hwnd, ClassName, 255);
         //showMessage(ClassName);

         if (ClassName <> 'Progman') and (ZOrderIndex(hwnd) > EnumData^.ZOrder) then
         begin
            EnumData^.Intersect := True;
            Exit(False);
         end;
      end;
   end;
   Result := True;
end;

з.ы. Progman что за класс?
Altera вне форума Ответить с цитированием
Старый 12.12.2009, 12:22   #10
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Цитата:
GetWindowLong(hwnd, GWL_HWNDPARENT) = 0
Смотрим только Топ окна. Ну без дочерних чтоли... уже не помню вообщем. ну эта строчка не принципиальная

Цитата:
з.ы. Progman что за класс?
Это окно - рабочий стол
BOBAH13 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Узнать открыто ли окно? Vol666 Общие вопросы Delphi 1 07.10.2009 18:28
как узнать Pid процесса которому принадлежит окно Пепел Феникса Win Api 3 13.04.2009 13:37
Как на JavaScript узнать, что пользователь закрыл окно? Laziz JavaScript, Ajax 1 22.02.2009 21:16
проверьте моё решение sverhuVniz Паскаль, Turbo Pascal, PascalABC.NET 4 25.10.2008 09:26
как поставить иконку в моё приложение? steck Паскаль, Turbo Pascal, PascalABC.NET 2 16.05.2007 18:12