CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Balonik z traya

Balonik z traya

dział ogólny

Re: Balonik z traya

Nowy postprzez Cyfrowy Baron » czwartek, 22 lipca 2010, 19:53

Mogę potwierdzić, że takowy problem występuje. Pomyślałem, że to może przez funkcję AllocateHWnd(WMTrayNotify) pobiera uchwyt i go przetrzymuje, wiec dodałem w zdarzeniu OnCLose głównego formularza aplikacji zwalanie tegoż uchwytu:

Kod: Zaznacz cały
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
 Shell_NotifyIconW(NIM_DELETE, &Ficon);

 DeallocateHWnd(Ficon.hWnd);
}
 


Niestety to nie rozwiązuje problemu. Przeszukałem plik pomocy, ale na razie nic tam nie znalazłem.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Balonik z traya

Nowy postprzez polymorphism » piątek, 23 lipca 2010, 10:38

mckri napisał(a):
KOD cpp:     UKRYJ  
void __fastcall TForm1::WndProc(Messages::TMessage &Message)
{
           if(Message.Msg==WM_QUERYENDSESSION)
           {
                  Close();
           }
          TWinControl::WndProc(Message);
}

WM_QUERYENDSESSION służy do potwierdzania, że aplikacja jest gotowa do zamknięcia sesji. Tu raczej nie powinieneś zamykać aplikacji, tylko zwrócić TRUE. Według dokumentacji domyślna procedura obsługi zwraca TRUE w odpowiedzi na ten komunikat, więc chyba nie trzeba robić specjalnej obsługi tego komunikatu, choć oczywiście nie można wykluczyć, że VCL zwraca coś innego.

Wszelkie kwestie związane z zamykaniem aplikacji daj do WM_ENDSESSION.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Balonik z traya

Nowy postprzez Cyfrowy Baron » piątek, 23 lipca 2010, 13:31

Znalazłem przyczynę błędu. Zabrakło TForm::Dispatch(&Msg); na końcu funkcji WMTrayNotify(TMessage &Msg):

KOD cpp:     UKRYJ  
void __fastcall TForm1::WMTrayNotify(TMessage &Msg)
{
    switch(Msg.LParam)
    {
        case WM_RBUTTONUP:

            POINT WinPoint;
            GetCursorPos(&WinPoint);
            SetForegroundWindow(Handle);
            PopupMenu1->Popup(WinPoint.x,WinPoint.y);
            PostMessage(Handle, WM_NULL, 0,0);
            break;
        case WM_LBUTTONDBLCLK:
            ShowWindow(Application->Handle, SW_SHOW);
            Visible = true;
            break;
        case NIN_BALLOONHIDE:
             ShowMessage("Kliknąłeś w balonik");
             break;
   }
   TForm::Dispatch(&Msg); // <-- TEGO ZABRAKŁO
}
 


Poza tym dobrze byłoby przenieść funkcje usuwające ikonę i zwalniające uchwyt do zdarzenie OnDestroy formularza głównego aplikacji:

Kod: Zaznacz cały

void __fastcall TForm1
::FormDestroy(TObject *Sender)
{
 DeallocateHWnd(Ficon.hWnd);
 Shell_NotifyIconW(NIM_DELETE, &Ficon);
}
 
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Balonik z traya

Nowy postprzez mckri » środa, 28 lipca 2010, 10:19

Na szybko sprawdziłem i u mnie zastosowanie TForm::Dispatch(&Msg); powoduje zawieszenie procesu programu, zarówno na Vista jak i WinXP. Proces wiesza się na WinXP głównie w momencie zakończenia sesji użytkownika.
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows VistaInternet Explorer 8

Re: Balonik z traya

Nowy postprzez Cyfrowy Baron » środa, 28 lipca 2010, 11:17

To niemożliwe, gdyż TForm::Dispatch(&Msg) jest prawidłowym zakończeniem funkcji obsługującej komunikaty i zawsze powinno być stosowane, nie tylko w tym konkretnym przypadku. To, że wcześniej tego nie podałem wynikało z przeoczenia. Musiałeś popełnić gdzieś błąd, gdyż u mnie ten kod działa bezbłędnie w Windows XP. Przeprowadziłem test również w systemie Windows 7 i nie było żadnych błędów.

Masz prawdopodobnie błąd w kodzie, ale spowodowany czymś innym. Przeprowadź test programu z kodem podanym na forum bez modyfikacji.

Tak mi przyszło do głowy czy przypadkiem nie stworzyłeś dwóch funkcji do przechwytywania komunikatów, czyli tej WMTrayNotify do obsługi balonika i tej Twojej WndProc. Jeżeli tak, to nie dziw się, że program się wiesza. Poza tym, jeżeli stosujesz TWinControl::WndProc(Message) to nie możesz stosować TForm::Dispatch(&Msg) , dla mojego przykładu prawidłowy jest Dispatch.




Proces wiesza się na WinXP głównie w momencie zakończenia sesji użytkownika.


Co rozumiesz przez sesję użytkownika? Zamknięcie programu, czy zamknięcie systemu, a może jeszcze coś innego.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Balonik z traya

Nowy postprzez mckri » czwartek, 29 lipca 2010, 22:30

Jeżeli tak, to nie dziw się, że program się wiesza. Poza tym, jeżeli stosujesz TWinControl::WndProc(Message) to nie możesz stosować TForm::Dispatch(&Msg) , dla mojego przykładu prawidłowy jest Dispatch.


Stosuje bez przeszkód te dwa zdarzenia i nie zauważyłem aby się "gryzły". Zawieszenie programu powodowało w moim przypadku zastosowanie kodu:

Kod: Zaznacz cały
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
DeallocateHWnd(Ficon.hWnd);
}

Dziękuję za pomoc.
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows VistaInternet Explorer 8

Re: Balonik z traya

Nowy postprzez Cyfrowy Baron » czwartek, 29 lipca 2010, 22:56

Stosuje bez przeszkód te dwa zdarzenia i nie zauważyłem aby się "gryzły".

Nie całkiem o to mi chodziło, ale skoro już działa, to nie będę tego tematu dalej rozwijał. Dodam tylko, że funkcja DeallocateHWnd sama w sobie błędu wywoływać nie może o ile jest prawidłowo stosowana, a to oznacza, że wciąż masz potencjalne błędy w kodzie, które mogą się ujawnić w dalszej pracy na programem.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Balonik z traya

Nowy postprzez mckri » poniedziałek, 21 marca 2011, 11:15

Trochę odgrzewam kotlet.
Z tego co wiem, baloniki systemowe dla zasobnika systemowego (tray) sa kolejkowane przez OS. Chciałym sie dowiedzieć, czy w jakiś sposób można zlikwidować powiadomienia balonikowe z innych programów, tak aby w danej chwili pokazac balonik z traya własnego programu?
Będę wdzięczny za przykładowy kod :)
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows VistaOpera

Re: Balonik z traya

Nowy postprzez Cyfrowy Baron » poniedziałek, 21 marca 2011, 16:02

mckri napisał(a):Z tego co wiem, baloniki systemowe dla zasobnika systemowego (tray) sa kolejkowane przez OS.


Wszystkie komunikaty w systemie są kolejkowane, więc komunikat o wyświetleniu balonika również. Nie zauważyłem jednak by w jakiś specjalny sposób kolejkowane były same baloniki, gdyż to program decyduje czy balonik ma się wyświetlić czy też nie. By wyłączyć powiadomienia z innych programów musiałbyś sterować takim programem poprzez wysyłanie do niego komunikatów, np. o tym, że balonik został już wyświetlony, lub nakazujący jego ukrycie.
Możesz więc pokombinować z funkcją SendMessage - ► patrz serwis: Cyfrowy Baron dział: teoria -> sterowanie obcym programem z poziomu własnego poprzez wysyłanie komunikatów. To wymagałoby jednak wysyłania komunikatu do wszystkich okien otwartych aktualnie w systemie. Komunikat który należałoby wysłać to być może: NIN_BALLOONHIDE lub NIS_HIDDEN, wątpię jednak by to zadziałało, wszak programy nie wysyłają komunikatów o wyświetleniu balonika non stop, lecz tylko gdy zachodzi taka potrzeba, a to oznacza, że trzeba by zamontować w systemie hak, który przechwytywałby wszelkie komunikaty systemowe, filtrował je wyłapując tylko te o baloniku, a potem wysyłał komunikaty do programów, które chcą ten balonik wyświetlić.

Strasznie to skomplikowane. To już lepiej wyłączyć w systemie pokazywanie baloników, a we własnym programie zaimplementować coś co będzie ten balonik udawało, czyli będzie tak samo wyglądało i tak samo się zachowywało.
Możesz wykorzystać komponent TBalloonHint z palety Additional:

KOD cpp:     UKRYJ  
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 BalloonHint1->Style = bhsStandard;
 BalloonHint1->Description = "Przykładowy tekst w BalloobHint";

 TPoint bhP = TPoint(Screen->Width - 100, Screen->Height - 30);

 BalloonHint1->ShowHint(bhP);
}
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Poprzednia strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 1 gość