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


Автор: Sunvas 16.3.2006, 08:20
Как сделать чтобы две формы моего приложения были всегда поверх других окон? Вариант чтобы в свойствах форм выставить вместо fsnormal fsstayontop не подходит, потому что при показе нескольких форм сразу все они почемуто не отображаються поверх остальных окон. smile

Автор: Romikgy 16.3.2006, 09:42
по таймеру их поднимать на самый верх
SetWindowPos

Автор: Sunvas 17.3.2006, 08:27
А без таймера?

Автор: Yanis 17.3.2006, 08:49
Если форма с обычным стилем - "поверх всех окон", то всё равно она будет располагаться по правилам Z order (как это по русски?). Поэтому, что бы она была такая как ты хочешь, то её нужно постоянно "подталкивать наверх". Поэтому и в таймере.

Цитата(Sunvas @ 17.3.2006, 08:27 Найти цитируемый пост)
А без таймера?
Делай, кто тебе мешает?

Автор: Sunvas 18.3.2006, 08:26
Цитата(Yanis @ 17.3.2006, 08:49 Найти цитируемый пост)
Если форма с обычным стилем - "поверх всех окон", то всё равно она будет располагаться по правилам Z order

Тогда почему если видна одна форма приложения с параметром "певерх всех окон", то все работает, а если уже две (моего приложения), то они могут перекрываться другими окнами (любыми), даже теми, которые не "поверх всех окон"?

Автор: Yanis 19.3.2006, 10:05
Цитата(Sunvas @ 18.3.2006, 08:26 Найти цитируемый пост)
Тогда почему если видна одна форма приложения с параметром "певерх всех окон", то все работает, а если уже две (моего приложения), то они могут перекрываться другими окнами (любыми), даже теми, которые не "поверх всех окон"?

Такая ситуация может быть лишь в том случае, если ты устанавливаешь fsStayOnTop не у главной формы.

Автор: Sunvas 20.3.2006, 08:27
Так как мне сделать "поверх всего" не только главную форму? smile

Автор: Демо 20.3.2006, 13:04
Устанавливаем главной форме:
Код

  FormStyle:=fsNormal;


Интервал таймера - 10мс.

Код

procedure RestoreApp;
var
  hWnd, hCurWnd, dwThreadID, dwCurThreadID: THandle;
  OldTimeOut: Cardinal;
  AResult: Boolean;
begin
    hWnd := Application.Handle;
    SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @OldTimeOut, 0);
    SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(0), 0);
    SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
    hCurWnd := GetForegroundWindow;
    AResult := False;
    while not AResult do
    begin
      dwThreadID := GetCurrentThreadId;
      dwCurThreadID := GetWindowThreadProcessId(hCurWnd);
      AttachThreadInput(dwThreadID, dwCurThreadID, True);
      AResult := SetForegroundWindow(hWnd);
      AttachThreadInput(dwThreadID, dwCurThreadID, False);
    end;
    SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
    SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(OldTimeOut), 0);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  w: THandle;
  i: Integer;
begin
  w := GetForegroundWindow;
  for i := 0 to Screen.FormCount-1 do
  begin
    if w=Screen.Forms[i].Handle then Exit;
  end;
  RestoreApp;
end;


Автор: Sunvas 21.3.2006, 08:23
Мда.. Демо, вот запустил твой код и что? Форма попросту всегда атктивна и "забивает" активность других приложений. Мне же нужно чтобы формы попросту были "поверх остальных окон".
Но все-равно спасибо за пример!

Автор: Демо 21.3.2006, 09:40
Цитата(Sunvas @ 21.3.2006, 08:23 Найти цитируемый пост)
Форма попросту всегда атктивна и "забивает" активность других приложений.


В таком случае нпонятно выражение "Всегда поверх других".

Автор: Sunvas 23.3.2006, 08:17
Цитата(Демо @ 21.3.2006, 09:40 Найти цитируемый пост)
В таком случае нпонятно выражение "Всегда поверх других".

Мда.. Возьмем к примеру пануль задач - она активна не всегда, но отображается поверх любого активного окна. Или старый добрый Винамп, когда в нем жмем Ctrl-A, то он перестает перекрываться другими окнами...
Вот этот эффект мне нужен, но только не одной главной формы, а для всех форм моего приложения.

Автор: Rouse_ 24.3.2006, 00:28
WM_WINDOWPOSCHANGING хочешь ты использовать в качестве нотификации ;)

Автор: Sunvas 24.3.2006, 08:19
Цитата(Rouse_ @ 24.3.2006, 00:28 Найти цитируемый пост)
WM_WINDOWPOSCHANGING хочешь ты использовать в качестве нотификации ;)

Это вопрос или предложение? smile

Автор: Ciber SLasH 24.3.2006, 08:59
А ShowWindowPos, что не помогает?
Код

  SetWindowPos(Handle, HWND_TOPMOST,
               (GetSystemMetrics(SM_CXSCREEN) - Width) div 2,   // координата X
               (GetSystemMetrics(SM_CYSCREEN) - Height) div 2,  // координата Y
               Width,   // ширина окна
               Height,  // высота окна
               SWP_SHOWWINDOW)


Автор: Winprogrammer 24.3.2006, 11:31
Поиграй со свойством FormStyle в паспорте свойств обьекта. smile
Добавлено @ 11:42
Код

procedure Form1.timer1timer(...);
var
       wnd_Handle:HWND;

begin 
 wnd_Handle:=GetActiveWindow;
 SwitchToTheseWindow(wnd_Handle);
end;

Автор: Winprogrammer 24.3.2006, 12:02
Предыдущий пример не работает. Попробуй так.

Код

var
      wnd_Handle:HWND;

procedure Form1.Create(...);
begin
 wnd_Handle:=GetActiveWindow;
end;

procedure Form1.timer1timer(...);
begin 
 BringWindowToTop(wnd_Handle);
end;

Надеусь будет работать.

Автор: Sunvas 25.3.2006, 08:29
Цитата(Ciber SLasH @ 24.3.2006, 08:59 Найти цитируемый пост)
  SetWindowPos(Handle, HWND_TOPMOST,
              (GetSystemMetrics(SM_CXSCREEN) - Width) div 2,  // координата X
              (GetSystemMetrics(SM_CYSCREEN) - Height) div 2,  // координата Y
              Width,  // ширина окна
              Height,  // высота окна
              SWP_SHOWWINDOW)

Повторяю для тех, кто не понял: для одной формы это работает, но вот уже для двух и более форм моего приложения - НЕТ!


Цитата(Winprogrammer @ 24.3.2006, 12:02 Найти цитируемый пост)
Надеусь будет работать.

Надежда умирает последней... Не работает..

Автор: Sunvas 6.4.2006, 07:12
Вопрос снят. smile

Автор: Демо 29.4.2006, 22:37
Вот решение:

Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Idle(Sender: TObject; var Done: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form1.Hide;
  FOrm2.Show;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnIdle := Idle;
end;

procedure TForm1.Idle(Sender: TObject; var Done: Boolean);
begin
  if Form2.Showing then SetWindowPos(FOrm2.Handle,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE    or SWP_NOSIZE);
end;

end.

 

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