StayOnTop w obrębie aplikacji

0

Cześć, mam aplikację i dwa typy okien(nazwijmy je oknami informacyjnymi), które informują o postępie operacji. Jedno okno wyświetla po prostu komunikat bez paska postępu i w tym momencie wykonuje się długotrwała procedura SQL(w głównym wątku, bo i tak czekać muszę na rezultat). Drugie okno pokazuje pasek postępu - używane w pętlach.

Teraz chcę zrobić tak, że jeśli aplikacja zostanie przesłonięta przez inną, to okno informacyjne zostanie schowane. Jeśli aplikacja zostanie przywrócona, to okno informacyjne pojawi się na wierzchu. Czyli chcę uzyskać efekt okna stayOnTop, ale tylko w obrebie aplikacji, a nie całego systemu. Próbowałem z fsStayOnTop, próbowałem z SetWindowPos i różnymi ustawieniami, ale nie udało mi się osiągnąć wymaganego celu. Okno było albo zawsze na wierzchu, albo na chwilę się ukrywało i po chwili przywracało na wierzch, lub nawet po chwili cała aplikacja była przywracana na wierzch :| Czy da się to zrobić bez przenoszenia wykonywania procedur składowanych do innego wątku? Może ktoś zna sposób, jakieś konkretne ustawienia SetWindowPos, czy coś. To co znalazłem w necie i helpie nie pomogło mi w żaden sposób.

0

W Application.OnActivate, przejrzyj wszystkie formatki aplikacji przez Screen znajdz to swoje okno wg nazwy klasy i przesuń na wierzch.
Z tym że to trochę bez sensu. Prościej odpalić tą formatkę w trybie ShowModal a z niej dopiero wywołać ten SQL.

0

Co rozumiesz przez okno "informacyjne zostanie schowane" - minimalizację czy ukrycie go? Bo może wystarczy Tobie, skoro chcesz warunkowe StayOnTop - coś w tym stylu, jak kod poniżej. W Timerze z małym Intervalem lub wątku z niewielkim Sleepem. Chociaż wiem, że jesteś doświadczonym użytkownikiem na forum, więc pewnie taki sposób próbowałeś, więc może Tobie on nie odpowiada, ale nic innego nie wymyślę, może ktoś inny będzie miał lepszy pomysł. Jeszcze można ewentualnie obsłużyć komunikat WM_SYSCOMMAND dla WParam = SC_RESTORE, z godnie z opisem na http://msdn.microsoft.com/en-us/library/ms646360(v=vs.85).aspx tylko nie wiem czy to tez Tobie będzie pasowało i czy zadziała jak chcesz.

  if GetforegroundWindow = Self.Handle then
  begin
    Self.FormStyle := fsStayOnTop;
  end
  else
  begin
    Self.FormStyle := fsNormal;
    Application.Minimize;
  end;
end;

EDIT: _13th_Dragon mnie ubiegł, możesz i spróbowac Jego rozwiązania.

0

Pomysł z wywołaniem sql z tego okna jest dla mnie bez sensu, bo to dość spory system i dość sporo zapytań. Poza tym okno ma pełnić rolę tylko i wyłącznie progressForm.

Pomysł z przechwyceniem komunkatu jest lepszy, ale i tak połowiczny, bo komunikatu nie dostanę, gdy odbędzie się długotrwała operacja SQL. Aplikacja będzie wtedy zablokowana, zgadza się?

0

ProgresForm może dostać jako parametr wskaźnik na metodę z podstawowej formy którą ma odpalić po starcie, samo SQL będzie w tej metodzie i wszystko od razu ma sens.

Jeżeli główny wątek całkiem zablokowany i nie są wykonywane żadne Application.ProcessMessages to nie dziwię się że nie działa twoja metoda, ani też moja nie zadziała ani ta od olesio też nie zadziała bo nie dochodzą komunikaty. Jedynie co zadziała ale kiepsko to ta moja pierwsza z ShowModal.

Takie długie zapytania powinieneś wykonywać w osobnym wątku.

0
_13th_Dragon napisał(a)

Takie długie zapytania powinieneś wykonywać w osobnym wątku.

Teoretycznie tak, ale i tak muszę czekać na wynik ich wykonywania. I moim zdaniem zabawa z jakimiś pętlami, których jedyna instrukcja to Application.ProcessMessages jest trochę bez sensu. Ale to moje zdanie i jeśli masz inne i jest ono lepsze, to możesz mnie przekonać :D

Z problemem jakoś udało mi się poradzić.
Otóż okno, gdy już nie jest potrzebne, do tej pory chowałem, teraz je zwalniam i niluje. Dzięki temu po stworzeniu, będzie na wierzchu. Dzięki temu mozna utworzyć je ze stylem fsNormal. A, żeby mieć pewność, że zawsze będzie na wierzchu wtedy, gdy musi, wyposażyłem procedurę je wywołującą w dodatkowy parametr: TopMost. Jeśli jest true, wywołuję procedurę SetWindowPos z odpowiednimi parametrami. W momencie, gdy jest pętla.

0

Twoje rozwiązanie doprowadza do tego że użytkownik nie może zrezygnować np po 5 min oczekiwania.
Np przypomniał że nie te opcje wybrał.
Z innym wątkiem nie ma problemu, naciska przycisk przerwij i po sprawie.

0

Generalnie brak możliwości przerwania nie stanowi w tej aplikacji większego problemu. Ale w odległej przyszłości być może dodam ten wątek.

1 użytkowników online, w tym zalogowanych: 0, gości: 1