TImage i OnKeyPress

dział ogólny

TImage i OnKeyPress

Nowy postprzez baca » poniedziaÅ‚ek, 1 grudnia 2008, 22:55

Mam taki problem stworzyłem sobie klasę która dziedziczy po klasie TImage. Chciałbym aby ta klasa obsługiwała zdarzenie naciśnięcia klawisza (OnKeyPress), ale klasa TImage nie ma tego zdarzenia. Czy mogę więc jakoś dodać te zdarzenie do mojej klasy.
Avatar użytkownika
baca
 
    NieznanyNieznana

Re: TImage i OnKeyPress

Nowy postprzez Cyfrowy Baron » Å›roda, 3 grudnia 2008, 11:05

Utworzenie zdarzenia rozpoznawanego przez system Windows, czyli takiego, które zawiera interfejs API, ogranicza się do zadeklarowania tegoż zdarzenia i zajmuje raptem dwie linijki kodu. Zdarzenie OnKeyPress znajduje się w API systemu Windows, więc można je łatwo zadeklarować. Robimy to w pliku nagłówkowym *.H

kod skrócony ograniczający się do deklaracji zdarzenia
Kod: Zaznacz cały
class PACKAGE TImage : public TMyImage
{
    private:
                TKeyPressEvent FOnKeyPress;

    protected:

    public:

    __published:
                  __property TKeyPressEvent OnKeyPress = {read = FOnKeyPress, write = FOnKeyPress};
         




Niektóre obiekty nie bez powodu nie obsługują pewnych zdarzeń, a klasa TImage nie obsługuje zdarzenia OnKeyPress, gdyż nie można go bezpośrednio wywołać w tym obiekcie, ponieważ nie da się ustawić fokusa na obiekt Image, czyli mówiąc prościej obiekt Image nigdy nie będzie obiektem aktywnym na formularzu. Jeżeli na formularzu będzie znajdował się tylko obiekt Image to focus i tak będzie ustawiony na formularz, nie na obiekt Image. Ma to związek z faktem iż obiekt Image nie posiada własnej kontrolki, a jedynie powierzchnię do odrysowywania, nie może jednak istnieć bez powierzchni, czyli zawsze musi być na czymś umieszczony na innej powierzchni np. Form, Panel itp., czyli można umieścić obiekt Image na obiekcie Panel, ale w żadne sposób nie można umieścić dowolnego obiektu na obiekcie Image, gdyż Image nie posiada własnej kontrolki, a jest tylko powierzchnią do odrysowywania, rysując (umieszczając grafikę) na Image rysujemy na powierzchni na której Image się znajduje, czyli Image ułatwia zarządzanie powierzchnią na której odbywa się rysowanie. W zasadzie klasa TImage to taka bardziej rozbudowana klasa TCanvas.

Problem tkwi głównie w dziedziczeniu, czyli w tym po jakich klasach dziedziczy klasa TImage:

  • System::TObject
  • Classes::TPersistent
  • Classes::TComponent
  • Controls::TControl
  • Controls::TGraphicControl

dla przykładu dziedziczenie klasy TPanel:

  • System::TObject
  • Classes::TPersistent
  • Classes::TComponent
  • Controls::TControl
  • Controls::TWinControl
  • Controls::TCustomControl
  • Extctrls::TCustomPanel

Jak widać klasa TPanel dziedziczy pośrednio po klasie TWinControl, więc może przejmować kontrolę nad oknem programu, a co za tym idzie reagować na zdarzenie OnKeyPress.



Można obejść to ograniczenie, ale trzeba posłużyć się dodatkowo zdarzeniem OnKeyPress innego obiektu najlepiej formularza, czyli deklarujesz w swojej nowej klasie zdarzenie OnKeyPress, tak jak to opisałem wyżej. Gdy umieścisz już swój komponent na formularzu tworzysz w nim zdarzenie OnKeyPress i umieszczasz dowolny kod który ma być wykonywany przez to zdarzenie, np.:

Kod: Zaznacz cały
void __fastcall TForm1::MyImage1KeyPress(TObject *Sender, char &Key)
{
   ShowMessage(String(Key));   
}
//---------------------------------------------------------------------------


To jednak nie wystarczy, mimo iż obiekt posiada zdarzenie OnKeyPress, to nie będzie na nie reagował, gdyż nie przejmie fokusa, żeby go zmusić do reakcji, trzeba stworzyć zdarzenie OnKeyPress dla formularza i umieścić w tym zdarzeniu odwołanie do zdarzenia OnKeyPress własnego obiektu:

Kod: Zaznacz cały
void __fastcall TForm1::FormKeyPress(TObject *Sender, char &Key)
{
  MyImage1KeyPress(Sender, Key);
}
//---------------------------------------------------------------------------


Teraz obiekt będzie reagował na zdarzenie OnKeyPress, ale tylko wtedy gdy focus będzie ustawiony na formularz. Jeżeli chcesz, żeby zawsze reagował na wciśniecie dowolnego przycisku, to musisz ustawić właściwość KeyPrewiew formularza na którym znajduje się ów obiekt na true.

Podaję to tylko jako ciekawostkę, gdyż z kodu widać, że trak naprawdę to obiekt reaguje na zdarzenie OnKeyPress formularza, a nie na własne i w zasadzie nie potrzeba tworzyć w tymże obiekcie tegoż zdarzenia, gdyż pełni ono zaledwie rolę zwykłej funkcji, aczkolwiek takie rozwiązanie jest dużym ułatwieniem, gdyż stworzenie w obiekcie zwykłej funkcji wymagałoby stworzenia całej procedury, wszystko zależy od tego co chce się uzyskać.

Na Twoim miejscu nie traciłbym już czasu na próbę zmuszenia Image do reakcji na zdarzenie OnKeyPress, gdyż to się nie uda, gdyby klasa TImage mogła obsługiwać to zdarzenie, to już by ono tam było.
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: TImage i OnKeyPress

Nowy postprzez baca » Å›roda, 3 grudnia 2008, 18:20

Dzięki za tak wyczerpująca odpowiedź. I jest tak jak mówisz dla moich potrzeb wystarczy ustawić na formatce KeyPrewiew=true.
Avatar użytkownika
baca
 
    NieznanyNieznana

Re: TImage i OnKeyPress

Nowy postprzez banita » czwartek, 8 stycznia 2009, 18:32

czy jest gdzies spis nazw tych obiektow reprezentujacych dane zdarzenia? jakie naglowki nalerzy dolaczyc aby z nich kozystac?
Avatar użytkownika
banita
Kreacjusz
Kreacjusz
 
Posty: 283
Dołączył(a): poniedziałek, 28 lipca 2008, 20:07
PodziÄ™kowaÅ‚ : 1
OtrzymaÅ‚ podziÄ™kowaÅ„: 18
System operacyjny: Windows 7 Professional
Kompilator: C++Builder 2010 Update 5,
Delphi 2010 Update 5,
NetBeans 6.9(MinGw + Qt),
Visual Studio 2008 + Qt
Gadu Gadu: 0
    NieznanyNieznana


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