Staram się napisać prostą aplikację, której zadaniem jest obsługa schowka windows. W dużym uproszczeniu, aplikacja przechwytuje komunikat WM_CLIPBOARDUPDATE i odpowiednio reaguje, dając użytkownikowi możliwość zapisania zawartości schowka w odpowiednim miejscu i w odpowiednim formacie.
Aplikacja może pracować w normalnym oknie (być cały czas widoczna dla użytkownika) lub dzięki użyciu komponentu TTrayIcon - być schowana w obszarze powiadomień Windows.
Mam problem z napisaniem elementu informującego użytkownika o zmianie zawartości schowka. Jeśli użytkownik wciśnie przycisk Print Screen (lub skopiuje jakiś tekst) na klawiaturze aplikacja przechwyci komunikat i wywoła odpowiednią procedurę - ta ma wyświetlić komunikat w prawym dolnym rogu ekranu o nowych danych schowka.
Zdecydowałem się na implementację własnego okienka informacji (nie korzystam z wbudowanej funkcjonalności TTrayIcon - Ballon Hint oraz co za tym idzie systemowych powiadomień). Po pierwsze, systemowe okienko jest jakie jest (ubogie), po drugie zależne jest od ikonki w trayu (zmiana ikonki powoduje wywołanie kolejnego komunikatu - a ja zmieniam indeks ikonki wyświetlając stan schowka) i po trzecie - każdy komunikat sygnalizowany jest dźwiękiem!.
Mam zatem oprócz głównej formy (MainFrm) drugą formę (TrayMsgFrm), która realizuje wyświetlenie komunikatu dla użytkownika.
Przechodzimy do najważniejszego. Okienko komunikatu ma "wślizgnąć się" na ekran z prawej strony i po kilku sekundach "wyjechać" z powrotem (poza obszar roboczy ekranu) i zamknąć się. Okienko komunikatu tworzone jest przy uruchomieniu programu - zatem tylko wyświetlam je i zamykam - nie niszczę (próbowałem z dynamicznym tworzeniem okna i niszczeniem go za każdym użyciem - ale napotkałem tutaj jeszcze większe problemy).
Wszystko działa dobrze, gdy główne okno jest widoczne na ekranie.
Kolejność jest następująca. Użytkownik ma otwarty program, wciska przycisk Print Screen. Do schowka Windows kopiowana jest zawartość ekranu - program przechwytuje ten obraz i wyświetla komunikat użytkownikowi - forma komunikatu jest wyświetlana (TrayMsgFrm.Show) - następuje wywołanie zdarzenia onShow (tutaj ustawiam formę oraz wczytuję dane do wyświetlenia) formy oraz onActivate (tutaj zaś "animuje" ruch okna). Wszystko działa OK.
No i w końcu problem. Jeśli program działa w trybie ukrytego okna w obszarze powiadomień (widoczna tylko ikonka w tray) dzieją się cuda.
Otóż:
- Użytkownik wciska przycisk Print Screen
- Aplikacja przechwytuje zmianę zawartości schowka i wywołuje okno komunikatu TrayMsgFrm
- Odpalane jest zdarzenie onShow formy (pobieram dane)
- Odpalane jest zdarzenie onActivate formy (wyświetlam okno i zamykam je po ustalonym czasie)
ALE - tak się dzieje tylko za pierwszym razem! Kolejne wciśnięcie przycisku Print Screen (czy skopiowanie tekstu Ctrl+C) wywołuje okienko komunikatu (OnShow) ale NIE WYWOŁUJE zdarzenia onActivate (kluczowego dla mnie). Dlaczego?
W załączniku znajdziecie przykładową implementację.
Proszę o pomoc. Co jest nie tak. Jak to zrobić poprawnie?
Ps: Pytanie zadałem również na forum https://en.delphipraxis.net/topic/11580-ttrayicon-hidden-main-window-and-second-form/?tab=comments#comment-91819
[mam nadzieję, że angielskojęzyczne i Polskie forum pomoże mi w tym (być może błahym) problemie)
-PawelTest.zip