Oprogramowanie zdarzenia TMenuItem

dział ogólny

Oprogramowanie zdarzenia TMenuItem

Nowy postprzez poleka » niedziela, 5 lipca 2009, 17:07

Witam, mam nadzieje, że znajdą się dobre pomysły na rozwiązanie mojego problemu:
otóż dla elementów TMenuItem menu głównego, mamy w Turbo C++ (nie wiem jak w nowszych) mało zdarzeń do oprogramowania (w przeciwieństwie do VS 2008), tj. nie mamy np. OnMouseEnter. Tak, więc trzeba się zabrać za obsługę komunikatów. Korzystając z polimorfizmu, przysłaniamy metodę WndProc w klasie naszej formatki. Spr. czy Msg to WM_MENUSELECT - komunikat wysyłany po kliknięcu, podświetleniu elementu lub kliknięciu poza menu:
Kod: Zaznacz cały
protected:
  virtual void __fastcall WndProc(TMessage& MSG){
    if(MSG.Msg == WM_MENUSELECT){
      //??
    }
  TForm::WndProc(MSG); // resztÄ… komunikatów nie zawracamy sobie gÅ‚owy
  }

Tu własnie jest pytanie: Jakie pola struktury TMessage porównać z jakimi właściwościami klasy TMenuItem, aby dostać informację, który element menu jest aktualnie podświetlany?
...
później...
TMenuItem ma właściwość Command (ushort), ale Turbo jakoś dziwnie nadaje id elementom menu, kiedy element nie rozwija się w nowe menu to jest ok, ale jak istnieje podmenu to pole Command ma wartość już przypisaną do innego elementu menu (z podmenu lub nie), co uniemożliwia jego jednoznaczną identyfikację... . Nie wiem co pozostaje do zrobienia, chyba tworzyć menu czystym WinApi?
Avatar użytkownika
poleka
Bladawiec
Bladawiec
 
Posty: 12
Dołączył(a): niedziela, 13 lipca 2008, 20:52
PodziÄ™kowaÅ‚ : 0
OtrzymaÅ‚ podziÄ™kowaÅ„: 0
    NieznanyNieznana

Re: Oprogramowanie zdarzenia TMenuItem

Nowy postprzez Cyfrowy Baron » poniedziaÅ‚ek, 6 lipca 2009, 12:30

NIe wiem jak to jest z Turbo C++, gdyż nigdy nie widziałem tego środowiska na oczy, ale:

Tu właśnie jest pytanie: Jakie pola struktury TMessage porównać z jakimi właściwościami klasy TMenuItem, aby dostać informację, który element menu jest aktualnie podświetlany?


w tym przypadku potrzebne jest raczej zdarzenie OnMouseMove.

O tworzeniu własnych zdarzeń było już na tym forum i jedno mogę Tobie powiedzieć, jeżeli korzystasz z obiektu API, a TMenuItem jest elementem interfejsu API, to możesz zdefiniować tylko takie zdarzenia jakie ten interfejs przewiduje dla danego obiektu, gdyż inne mimo iż będą zdefiniowane, nie będą działać.

W twoim przypadku trzeba się rzeczywiście posłużyć mapą komunikatów lub funkcją WindowProc, ale dla sprawdzenia na którą pozycję wskazuje kursor wystarczy wszak zdarzenie OnMouseMove, czyli komunikat WM_MOUSEMOVE.
Jeżeli chodzi o komunikaty to nie jest tak, że można zawsze korzystać z komunikatów dla okien WM_, niektóre obiekty wymagają komunikatów przewidzianych specjalnie dla nich.
Co do obiektów MainMenu i PopupMenu to są to w rzeczywistości formularze z parametrem stylu WS_POPUP, więc komunikaty WM_ powinny mieć zastosowanie.

TMessage porównać z jakimi właściwościami klasy TMenuItem, aby dostać informację, który element menu jest aktualnie podświetlany?


wielkich możliwości nie masz, w zasadzie do użycia są tylko trzy zmienne .Msg, .LParam, .WParam, więc wypróbuj każdy i zobaczysz na który będzie reakcja.
LParam raczej odpada.
Nie wiem czy nie powinieneś raczej skorzystać z klasy TMessageEvent, ale tutaj nic na razie nie poradzę, gdyz nigdy z niej jeszcze nie korzystał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
    NieznanyNieznana

Re: Oprogramowanie zdarzenia TMenuItem

Nowy postprzez Witold » poniedziaÅ‚ek, 6 lipca 2009, 15:13

poleka napisał(a):kiedy element nie rozwija się w nowe menu to jest ok, ale jak istnieje podmenu to pole Command ma wartość już przypisaną do innego elementu menu (z podmenu lub nie), co uniemożliwia jego jednoznaczną identyfikację... .


Słabo się w tym orientuje , ale wydaje mi się że gdy item ma subitemy (->POPUP) , to nie ma identyfikatora, a komunikat WM_MENUSELECT odczytuje się dla niego inaczej.

Kod: Zaznacz cały
//Przykład z http://www.lanform.com.pl/cpptxt/l45.txt
BEGIN 
  POPUP "Rozkaz" 
    BEGIN 
       MENUITEM "Rozkaz 1", IDM_R1 
       MENUITEM "Rozkaz 2", IDM_R2 
       MENUITEM "Rozkaz 3", IDM_R3 
    END 
  POPUP "Kolor" 
    BEGIN 
       MENUITEM "Czarny", IDM_BLACK 
       MENUITEM "Niebieski", IDM_BLUE 
       MENUITEM "Zielony", IDM_GREEN 
  END 
  MENUITEM "Koniec", IDM_EXIT 
END 
...
#define IDM_EXIT 100 
#define IDM_BLUE 101 
#define IDM_R1   102

O tym czy item ma subitemy można wyczytac z flagi MF_POPUP wyciągniętej z komunikatu WM_MENUSELECT.
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
PodziÄ™kowaÅ‚ : 1
OtrzymaÅ‚ podziÄ™kowaÅ„: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: Oprogramowanie zdarzenia TMenuItem

Nowy postprzez poleka » poniedziaÅ‚ek, 6 lipca 2009, 16:07

Też myślałem, że submenu nie ma id, jak traktują o tym źródła, ale nie ważne. Udało się dosyć prosto to zrobić co chciałem (np. mieć możliwość zmiany pewnej grafiki, w zależności od tego jaki element menu jest podświetlony), a było to tak:
Kod: Zaznacz cały
protected:
  virtual void __fastcall WndProc(TMessage& MSG){
    if(MSG.Msg == WM_MENUSELECT){
      if(MSG.WParamLo == 2 && !(MSG.WParamHi & MF_POPUP)){
        //wykona siÄ™ jeżeli id == 2 i element ten nie rozwija siÄ™ w podmenu
      }
  }
  TForm::WndProc(MSG);
}

A tu można sobie poczytać, m. in jakie inne flagi da się sprawdzić:
klik
...
skoro nie ma komentarzy, to zamykam
Avatar użytkownika
poleka
Bladawiec
Bladawiec
 
Posty: 12
Dołączył(a): niedziela, 13 lipca 2008, 20:52
PodziÄ™kowaÅ‚ : 0
OtrzymaÅ‚ podziÄ™kowaÅ„: 0
    NieznanyNieznana


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 6 gości