Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.08.21;
Скачать: CL | DM;

Вниз

Как узнать запущено ли хоть одно полноэкранное приложение?   Найти похожие ветки 

 
rolex   (2005-07-29 19:46) [0]

Чтобы запретить в своей программе различные OSD и popup окошки, нужно узнать запущено ли хоть одно полноэкранное приложение (игры, заставка...).
Как это можно сделать?


 
Джо ©   (2005-07-29 19:49) [1]

Искать все видимые окна верхнего уровня в системе. Проверить их размер и состояние.
?


 
rolex   (2005-07-29 19:59) [2]

А как? Можно примером?


 
TUser ©   (2005-07-29 20:08) [3]

EnumWindows
GetWindowRect


 
Джо ©   (2005-07-29 20:36) [4]

Вот нашел у себя в старых исходниках. Когда-то делал класс-энумератор для своих (скромных) целей.


unit WEnum;

interface
uses Windows, SysUtils, Classes, Contnrs;

type
 TOSWindow = class
 private
   FHandle: THandle;
   FText: string;
   function GetHandleValid: Boolean;
   procedure SetWindowProperties;
   function GetVisible: Boolean;
   function GetRect: TRect;
   function GetIconic: Boolean;
   function GetMaximized: Boolean;
 public
   property Handle: THandle read FHandle;
   property HandleValid: Boolean read GetHandleValid;
   property Visible: Boolean read GetVisible;
   property Text: string read FText;
   property Rect: TRect read GetRect;
   property Iconic: Boolean read GetIconic;
   property Maximized: Boolean read GetMaximized;
   constructor Create (AHandle: THandle);
 end;

 TWindowEnumerator = class
 private
   FList: TObjectList;
   FPosition: Integer;
   function GetCurrent: TOSWindow;
   procedure AddWindow (AHandle: THandle);
 public
   procedure Reset;
   procedure Populate;
   function MoveNext: Boolean;
   property Current: TOSWindow read GetCurrent;
   constructor Create;
   destructor Destroy; override;
 end;

implementation
uses Dialogs;

function EnumWindowProc (AHandle: THandle; lParm: LPARAM): BOOL; stdcall;
var
 Enumerator: TWindowEnumerator;
begin
 TWindowEnumerator(lParm).AddWindow(AHandle);
 Result := True
end;

{ TOSWindows }

constructor TOSWindow.Create(AHandle: THandle);
begin
 FHandle := AHandle;
 SetWindowProperties;
end;

function TOSWindow.GetHandleValid: Boolean;
begin
 Result := IsWindow(FHandle);
end;

{ TWindowEnumerator }

function TWindowEnumerator.MoveNext: Boolean;
begin
 Result := FPosition < FList.Count - 1;
 if Result then
   Inc(FPosition);
end;

function TWindowEnumerator.GetCurrent: TOSWindow;
begin
 Result := TOSWindow(FList[FPosition])
end;

procedure TWindowEnumerator.Populate;
begin
 FList.Clear;
 if not EnumWindows(@EnumWindowProc,Integer(Self)) then
   RaiseLastOSError

end;

constructor TWindowEnumerator.Create;
begin
 FList := TObjectList.Create(True);
 Populate;
 FPosition := -1;
end;

destructor TWindowEnumerator.Destroy;
begin
 FList.Free;
 inherited;
end;

procedure TWindowEnumerator.AddWindow(AHandle: THandle);
begin
 FList.Add(
   TOSWindow.Create(AHandle)
 )
end;

function TOSWindow.GetIconic: Boolean;
begin
 Result := Windows.IsIconic(FHandle)
end;

function TOSWindow.GetMaximized: Boolean;
begin
 Result := Windows.IsZoomed(FHandle)
end;

function TOSWindow.GetRect: TRect;
begin
 GetWindowRect(FHandle,Result)
end;

function TOSWindow.GetVisible: Boolean;
begin
 Result := IsWindowVisible(FHandle)
end;

procedure TOSWindow.SetWindowProperties;
var
 Len: Integer;
 AText: string;
begin
 Len := GetWindowTextLength(FHandle);
 SetLength (AText,Len+1);
 GetWindowText(FHandle,PChar(AText),Len+1);
 FText := AText
end;

procedure TWindowEnumerator.Reset;
begin
 FPosition := -1
end;

end.

Например, найти все видимые и максимизированные окна верхнего уровня и вывести из заголовок, можно так:

procedure TForm6.Button1Click(Sender: TObject);
var
 WinEnum: TWindowEnumerator;
begin
 WinEnum := TWindowEnumerator.Create;
 try
   while WinEnum.MoveNext do
   begin
     if (WinEnum.Current.Visible) and (WinEnum.Current.Maximized) then
       ShowMessage(WinEnum.Current.Text)
   end;
 finally
   WinEnum.Free;
 end;
end;

Тебе нужно будет свойство Rect.
Кстати, перед каждым опросом свойства не мешало бы подстраховываться вызовом метода HandleValid - потому как окна уже может и не быть в момент вызова :-)
В, общем, экспериментируй.
П.С. Класс - черновой, писанный для себя, так что, внимательно изучи его работу перед использованием. Можешь его расширять, как тебе будет угодно.


 
rolex   (2005-07-29 21:12) [5]

Накалякал пока такой код:
...
   procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;
 public
 end;

var
 Form1: TForm1;
 FullScrExe:Boolean;

implementation

{$R *.DFM}
Function WindowToWidth(WD: HWND):integer;
Var ARect:TRect;
begin
GetWindowRect(WD, ARect);
Result:=ARect.Right-ARect.Left;
end;

Function WindowToHeight(WD: HWND):integer;
Var ARect:TRect;
begin
GetWindowRect(WD, ARect);
Result:=ARect.Bottom-ARect.Top;
end;

function EnumWindowsProc(Wnd: HWND): BOOL; stdcall;
begin
Result:=True;
if (IsWindowVisible(Wnd) or IsIconic(wnd)) and ((GetWindowLong(Wnd, GWL_HWNDPARENT) = 0) or
(GetWindowLong(Wnd, GWL_HWNDPARENT) = GetDesktopWindow)) and (GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW = 0) then
if (WindowToWidth(Wnd)>=Screen.Width) and (WindowToHeight(Wnd)>=Screen.Height) then FullScrExe:=true;
end;

function ExistFullApplication:boolean;
begin
FullScrExe:=false;
EnumWindows(@EnumWindowsProc, 0);
Result:=FullScrExe;
end;

procedure TForm1.WMHotKey(var Msg: TWMHotKey);
begin
case msg.HotKey of
1: if form1.Visible then
     begin
     FadeOut; hide;
     end else
       if ExistFullApplication=false then
         begin
         show;
         FadeIn;
         end;
2: begin if (Visible=false) and (ExistFullApplication=false) then begin show; FadeIn; end; Timer1.Enabled:=False; Timer1.Enabled:=True; TrackBar2.Position:=TrackBar2.Position-656; end;
3: begin if (Visible=false) and (ExistFullApplication=false) then begin show; FadeIn; end; Timer1.Enabled:=False; Timer1.Enabled:=True; TrackBar2.Position:=TrackBar2.Position+656; end;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Mixer:=TAudioMixer.Create(Self);
 RegisterHotKey(Form1.Handle, 1, 0, 255);
 RegisterHotKey(Form1.Handle, 2, 0, 174);
 RegisterHotKey(Form1.Handle, 3, 0, 175);
end;

...

При нажатии на клавишу (msg.hotkey=1, 2, 3...), вылазиет ошибка. А если проверять таймером, то всё нормально.
Т.е. эта функция плохо работает когда нажата клавиша на клавиатуре. Помогите.


 
rolex   (2005-07-29 21:12) [6]


> Джо ©

Спасибо. щас ваш попробую.


 
Джо ©   (2005-07-29 21:32) [7]


> [6] rolex   (29.07.05 21:12)
> Спасибо. щас ваш попробую.

Там нет ничего нового. Просто удобный костяк и оболочка для перебора окон. У тебя - процедурный подход, у меня объектно-ориентированный. Суть одна.


 
rolex   (2005-07-29 21:34) [8]

Мля с примером Джо у меня ничего не выходит. Помгите лучше мне мой доделать.


 
Джо ©   (2005-07-29 21:39) [9]


>  [8] rolex   (29.07.05 21:34)
> Мля с примером Джо у меня ничего не выходит.

Мля, ты исключительно вежливый пацан.


 
rolex   (2005-07-29 21:52) [10]

Итак, методом тыка обнаружил, что проблема в этой функции, а конкретно в выделенных строках:
function EnumWindowsProc(Wnd: HWND): BOOL; stdcall;
begin
Result:=True;
if (IsWindowVisible(Wnd) or IsIconic(wnd)) and ((GetWindowLong(Wnd, GWL_HWNDPARENT) = 0) or
(GetWindowLong(Wnd, GWL_HWNDPARENT) = GetDesktopWindow)) and (GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW = 0) then

if (WindowToWidth(Wnd)>=Screen.Width) and (WindowToHeight(Wnd)>=Screen.Height) then FullScrExe:=true;
end;

Помогите разобраться. Пожалуйста.


> Джо ©   (29.07.05 21:39) [9]
>
> >  [8] rolex   (29.07.05 21:34)
> > Мля с примером Джо у меня ничего не выходит.
>
> Мля, ты исключительно вежливый пацан.

Извини, если что.


 
Джо ©   (2005-07-29 21:56) [11]


> Result:=True;
> if (IsWindowVisible(Wnd) or IsIconic(wnd)) and ((GetWindowLong(Wnd,
> GWL_HWNDPARENT) = 0) or
> (GetWindowLong(Wnd, GWL_HWNDPARENT) = GetDesktopWindow))
> and (GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW
> = 0) then
> if (WindowToWidth(Wnd)>=Screen.Width) and (WindowToHeight(Wnd)>=Screen.Height)
> then FullScrExe:=true;
> end;

Именно для того, чтобы не возиться с таким безобразным кодом, я и сделал свою оболочку. Расширь ее как того требует твоя задача.


 
Джо ©   (2005-07-29 21:56) [12]

Сейчас накатаю пример.


 
Джо ©   (2005-07-29 22:16) [13]

Немного подправил класс TOSWindow, внеся в него необходимые свойста: FullScreen, ToolWindow.


unit Unit7;

interface
uses Windows, SysUtils, Classes, Contnrs;

type
 TOSWindow = class
 private
   FHandle: THandle;
   FRect: TRect;
   FText: string;
   function GetHandleValid: Boolean;
   procedure SetWindowProperties;
   function GetVisible: Boolean;
   function GetIconic: Boolean;
   function GetMaximized: Boolean;
   function GetFullScreen: Boolean;
   function GetToolWindow: Boolean;
 public
   property Handle: THandle read FHandle;
   property HandleValid: Boolean read GetHandleValid;
   property Visible: Boolean read GetVisible;
   property Text: string read FText;
   property Rect: TRect read FRect;
   property Iconic: Boolean read GetIconic;
   property Maximized: Boolean read GetMaximized;
   property ToolWindow: Boolean read GetToolWindow;
   property FullScreen: Boolean read GetFullScreen;
   constructor Create (AHandle: THandle);
 end;

 TWindowEnumerator = class
 private
   FList: TObjectList;
   FPosition: Integer;
   function GetCurrent: TOSWindow;
   procedure AddWindow (AHandle: THandle);
 public
   procedure Reset;
   procedure Populate;
   function MoveNext: Boolean;
   property Current: TOSWindow read GetCurrent;
   constructor Create;
   destructor Destroy; override;
 end;

implementation
uses Dialogs, Types;

function EnumWindowProc (AHandle: THandle; lParm: LPARAM): BOOL; stdcall;
var
 Enumerator: TWindowEnumerator;
begin
 TWindowEnumerator(lParm).AddWindow(AHandle);
 Result := True
end;

{ TOSWindows }

constructor TOSWindow.Create(AHandle: THandle);
begin
 FHandle := AHandle;
 SetWindowProperties;
end;

function TOSWindow.GetFullScreen: Boolean;
begin
 Result :=
   Visible and
   (FRect.Left = 0) and
   (FRect.Top = 0) and
   (FRect.Right = GetSystemMetrics(SM_CXSCREEN)) and
   (FRect.Bottom = GetSystemMetrics(SM_CYSCREEN));
end;

function TOSWindow.GetHandleValid: Boolean;
begin
 Result := IsWindow(FHandle);
end;

{ TWindowEnumerator }

function TWindowEnumerator.MoveNext: Boolean;
begin
 Result := FPosition < FList.Count - 1;
 if Result then
   Inc(FPosition);
end;

function TWindowEnumerator.GetCurrent: TOSWindow;
begin
 Result := TOSWindow(FList[FPosition])
end;

procedure TWindowEnumerator.Populate;
begin
 FList.Clear;
 if not EnumWindows(@EnumWindowProc,Integer(Self)) then
   RaiseLastOSError

end;

constructor TWindowEnumerator.Create;
begin
 FList := TObjectList.Create(True);
 Populate;
 FPosition := -1;
end;

destructor TWindowEnumerator.Destroy;
begin
 FList.Free;
 inherited;
end;

procedure TWindowEnumerator.AddWindow(AHandle: THandle);
begin
 FList.Add(
   TOSWindow.Create(AHandle)
 )
end;

function TOSWindow.GetIconic: Boolean;
begin
 Result := Windows.IsIconic(FHandle)
end;

function TOSWindow.GetMaximized: Boolean;
begin
 Result := Windows.IsZoomed(FHandle)
end;

function TOSWindow.GetToolWindow: Boolean;
begin
 Result :=
   (GetWindowLong(FHandle, GWL_EXSTYLE) and WS_EX_TOOLWINDOW) = WS_EX_TOOLWINDOW;
end;

function TOSWindow.GetVisible: Boolean;
begin
 Result := IsWindowVisible(FHandle)
end;

procedure TOSWindow.SetWindowProperties;
var
 Len: Integer;
 AText: string;
begin
 Len := GetWindowTextLength(FHandle);
 SetLength (AText,Len+1);
 GetWindowText(FHandle,PChar(AText),Len+1);
 FText := AText;

 GetWindowRect(FHandle,FRect);
end;

procedure TWindowEnumerator.Reset;
begin
 FPosition := -1
end;

end.

---
Теперь проверка выглядит так:
---

procedure TForm6.Button1Click(Sender: TObject);
var
 WinEnum: TWindowEnumerator;
begin
 Memo1.Clear;
 WinEnum := TWindowEnumerator.Create;
 try
   while WinEnum.MoveNext do
   begin
     if WinEnum.Current.FullScreen and not WinEnum.Current.ToolWindow then

       Memo1.Lines.Add(WinEnum.Current.Text) // делаешь с окном, что хочешь
   end;
 finally
   WinEnum.Free;
 end;
end;

Посмотри код добавленных свойств, точнее их акцессоров. Добавь еще несколько свойств по их образцу, чтобы уточнить, что ты имеешь в виду под "на весь экран".  Возможно, того, что есть, хватит.
П.С.
Есть проекрасный способ, чтобы не путаться во всех этих проверках. А именно, разбиение сложного условия на составляющие. Что я и пытался продемонстрировать.


 
rolex   (2005-07-30 10:54) [14]

Вот функция (всё-таки сам сделал и по своему):
Function WindowToWidth(WD: HWND):integer;
Var ARect:TRect;
begin
GetWindowRect(WD, ARect);
Result:=ARect.Right-ARect.Left;
end;

Function WindowToHeight(WD: HWND):integer;
Var ARect:TRect;
begin
GetWindowRect(WD, ARect);
Result:=ARect.Bottom-ARect.Top;
end;

function ExistFullApplication:boolean;
var
 Wnd: hWnd;
 buff: array[0..127] of Char;
 xres:boolean;
begin
 xres:=false;
 Wnd := GetWindow(Form1.Handle, gw_HWndFirst);
 while Wnd <> 0 do begin {Не показываем:}
   GetWindowText(Wnd, buff, sizeof(buff));
   if (Wnd <> Application.Handle) and {-Собственное окно}
     IsWindowVisible(Wnd) and {-Невидимые окна}
     (GetWindow(Wnd, gw_Owner) = 0) and {-Дочернии окна}
     (StrPas(buff)<>"Program Manager") and
     (GetWindowText(Wnd, buff, sizeof(buff)) <> 0) {-Окна без заголовков}
     and (WindowToWidth(Wnd)>=Screen.Width) and (WindowToHeight(Wnd)>=Screen.Height)
     then xres:=True;
   Wnd := GetWindow(Wnd, gw_hWndNext);
 end;
Result:=xres;
end;


Проверьте, правильная ли она. Вроде у меня работает.



Страницы: 1 вся ветка

Текущий архив: 2005.08.21;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.034 c
14-1122888356
ocean
2005-08-01 13:25
2005.08.21
Старый шрифт


3-1121239183
cvg
2005-07-13 11:19
2005.08.21
Почему может быть не найдено поле?


14-1122399553
БарЛог
2005-07-26 21:39
2005.08.21
Стихи


4-1119986951
Ванечка
2005-06-28 23:29
2005.08.21
Права админа


1-1122963578
СССР
2005-08-02 10:19
2005.08.21
PopupMenu1