Funkcja FindComponent we własnej funkcji

dział ogólny

Funkcja FindComponent we własnej funkcji

Nowy postprzez simekone » wtorek, 21 lipca 2009, 18:53

Mianowicie mam taki problem, chcę użyć funkcji FindComponent we własnoręcznie napisanej funkcji, która jest wywoływana po kliknięciu jednego z przycisków z zadanymi parametrami. Kod który działa w OnClick, nie działa już w mojej funkcji, otrzymuje komunikat:
Kod: Zaznacz cały
[BCC32 Error] pole_gry.cpp(52): E2268 Call to undefined function 'FindComponent'

Jak zdefiniować tą funkcję, aby działała?
Avatar użytkownika
simekone
Bladawiec
Bladawiec
 
Posty: 31
Dołączył(a): środa, 25 marca 2009, 13:27
Podziękował : 1
Otrzymał podziękowań: 0
Kompilator: CodeGear C++ Builder 2009
    NieznanyNieznana

Re: Funkcja FindComponent we własnej funkcji

Nowy postprzez Cyfrowy Baron » wtorek, 21 lipca 2009, 19:38

Pokaż kompletny kod bo bez tego to możemy zgadywać w nieskończoność.
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: Funkcja FindComponent we własnej funkcji

Nowy postprzez banita » wtorek, 21 lipca 2009, 20:41

najprawdopodobniej problem polega na tym iz owa funkcaj to nie funkcja globalna a metoda klas komponentow ktore moga byc rodzicami dla innych komponentow. gdy w onclick wywolujesz FIndComponent to tak naprawde wywolywane jest
this->FindComponent

pomysl logicznie. jesli wywolasz ta funkcje we wlasnej funkcji to gdzie maja byc szukane te komponenty? na ktorej formatce/panelu itd... ?
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

Re: Funkcja FindComponent we własnej funkcji

Nowy postprzez Cyfrowy Baron » wtorek, 21 lipca 2009, 21:18

najprawdopodobniej problem polega na tym iz owa funkcaj to nie funkcja globalna a metoda klas komponentow ktore


jest raczej właśnie funkcja globalną, ale nie ma za "rodzica" formularza, np:

Kod: Zaznacz cały
void Funkcja(void)
{
  FindComponent(...);
}


Można to rozwiązać na dwa sposoby. Pierwszy zostawić funkcję tak jak jest i prawidłowo adresować funkcję FindComponent:

Kod: Zaznacz cały
void Funkcja(void)
{
  Form1->FindComponent(...);
}


Drugo sposób to przypisać funkcję do formularza poprzez deklarację w sekcji private lub public pliku nagłówkowego i definicję w pliku źródłowym. To rozwiązanie jest lepsze gdyż łatwiej będize się odwoływać do komponentów na formularzu:

Kod: Zaznacz cały
//plik nagłówkowy np. Unit1.h
public:
  void Funkcja(void);
//-----------------------------------------------

//plik źródłowy np. Unit1.cpp
void TForm1::Funkcja(void)
{
  this->FindComponent(...);
}
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: Funkcja FindComponent we własnej funkcji

Nowy postprzez simekone » wtorek, 21 lipca 2009, 22:08

Funkcja wygląda tak:
Kod: Zaznacz cały
void move(TButton *mob, int x, int y){
if (mob->Caption != "") {
   TIniFile *Ini = new TIniFile("mobs.ini");
      int ruch = Ini->ReadInteger(mob->Caption, "ruch", 0);
   delete Ini;
   dynamic_cast<TButton *>(FindComponent("p" + IntToStr(x) + IntToStr(y-ruch)))->Enabled = true;
   dynamic_cast<TButton *>(FindComponent("p" + IntToStr(x) + IntToStr(y+ruch)))->Enabled = true;
   dynamic_cast<TButton *>(FindComponent("p" + IntToStr(x-ruch) + IntToStr(y)))->Enabled = true;
   dynamic_cast<TButton *>(FindComponent("p" + IntToStr(x+ruch) + IntToStr(y)))->Enabled = true;
}
}


Póki co prymitywna próba realizacji pewnego pomysłu, na nic lepszego nie wpadłem ;)
Avatar użytkownika
simekone
Bladawiec
Bladawiec
 
Posty: 31
Dołączył(a): środa, 25 marca 2009, 13:27
Podziękował : 1
Otrzymał podziękowań: 0
Kompilator: CodeGear C++ Builder 2009
    NieznanyNieznana

Re: Funkcja FindComponent we własnej funkcji

Nowy postprzez Cyfrowy Baron » środa, 22 lipca 2009, 08:32

I to jest dokładnie to o czym pisał banita. Tworzysz funkcję globalna niezależną od klasy TForm, czyli od formularza na którym chcesz wyliczać komponenty, więc funkcja nie zna funkcji FindComponent i nie może się do niej odwoływać. Patrz co napisałem w poprzednim wątku.

Zadeklaruj funkcję w klasie public pliku nagłówkowego np. Unit1.h:
Kod: Zaznacz cały
public:
        void move(TButton *mob, int x, int y);


Teraz definiuj ją w pliku źródłowym np. Unit1.cpp

Kod: Zaznacz cały
void TForm1::move(TButton *mob, int x, int y)
{
  if (!mob->Caption.IsEmpty()) // to jest równoznaczne z zapisem: if(mob->Caption != "")
  {
   String fileIni = ExtractFilePath(ParamStr(0)) + "mobs.ini";
   TIniFile *Ini = new TIniFile(fileIni); // należy zastosować ścieżkę bezwzględną
      int ruch = Ini->ReadInteger(mob->Caption, "ruch", 0);
   delete Ini;
   dynamic_cast<TButton *>(this->FindComponent("p" + IntToStr(x) + IntToStr(y-ruch)))->Enabled = true;
   dynamic_cast<TButton *>(this->FindComponent("p" + IntToStr(x) + IntToStr(y+ruch)))->Enabled = true;
   dynamic_cast<TButton *>(this->FindComponent("p" + IntToStr(x-ruch) + IntToStr(y)))->Enabled = true;
   dynamic_cast<TButton *>(this->FindComponent("p" + IntToStr(x+ruch) + IntToStr(y)))->Enabled = true;
  }
}


można też tak:

Kod: Zaznacz cały
void TForm1::move(TButton *mob, int x, int y)
{
  if (!mob->Caption.IsEmpty()) return; // return przerywa wykonywanie dalszych instrukcji i wyrzuca z funkcji

   String fileIni = ExtractFilePath(ParamStr(0)) + "mobs.ini";
   TIniFile *Ini = new TIniFile(fileIni); // należy zastosować ścieżkę bezwzględną
   int ruch = Ini->ReadInteger(mob->Caption, "ruch", 0);

   delete Ini;
   dynamic_cast<TButton *>(this->FindComponent("p" + IntToStr(x) + IntToStr(y-ruch)))->Enabled = true;
   dynamic_cast<TButton *>(this->FindComponent("p" + IntToStr(x) + IntToStr(y+ruch)))->Enabled = true;
   dynamic_cast<TButton *>(this->FindComponent("p" + IntToStr(x-ruch) + IntToStr(y)))->Enabled = true;
   dynamic_cast<TButton *>(this->FindComponent("p" + IntToStr(x+ruch) + IntToStr(y)))->Enabled = true;

}


gdzie TForm1 to nazwa klasy formularza do którego funkcja została przypisana.
Argument TButton *mob funkcji move jest niewykorzystywany w ciele funkcji więc jest zbędny.



Przy odwoływaniu się do pliku *.ini należy podawać ścieżkę bezwzględną nawet gdy ten plik znajduje się w katalogu programu, gdyż "pewne" zdarzenia mogą sprawić, że program "zgubi" względną ścieżkę do pliku, jak np. zastosowanie i użycie obiektu OpenDialog. Funkcja ExtractFilePath(ParamStr(0)) pobiera ścieżkę dostępu do katalogu programu, niezależnie od tego gdzie ten program się znajduje zawsze będzie to ścieżka do katalogu tegoż programu. Funkcja ExtractFilePath zawsze zwraca ścieżkę dostępu do pliku określonego w argumencie tej funkcji, funkcja ParamStr(0) pobiera pierwszy parametr programu którym zawsze jest pełna ścieżka dostępu wraz z nazwą programu. Tak więc funkcja ExtractFilePath ekstrahuje ścieżkę dostępu z wartości zwracanej przez funkcję ParamStr(0). Jeżeli np. program znajduje się w lokalizacji: C:\Program Files\My Program\Project1.exe to funkcja ParamStr(0) zwróci jako wynik właśnie tą ścieżkę czyli: C:\Program Files\My Program\Project1.exe funkcja ExtractFilePath wyekstrahuje z tego ścieżkę dostępu do katalogu programu czyli: C:\Program Files\My Program\, potem dodajemy do tego nazwę pliku mobs.ini i otrzymujemy pełną bezwzględną ścieżkę dostępu do tegoż pliku czyli: C:\Program Files\My Program\mobs.ini

Dlatego właśnie chciałem, żebyś przytoczył swój kod.
Zalecam przeczytanie artykułu: ► patrz serwis: Cyfrowy Baron dział: teoria -> funkcje.
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: Funkcja FindComponent we własnej funkcji

Nowy postprzez simekone » środa, 22 lipca 2009, 11:36

Działa bez zarzutu, dziekuję tez za dodatkowe porady, na pewno je wykorzystam.
Avatar użytkownika
simekone
Bladawiec
Bladawiec
 
Posty: 31
Dołączył(a): środa, 25 marca 2009, 13:27
Podziękował : 1
Otrzymał podziękowań: 0
Kompilator: CodeGear C++ Builder 2009
    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 4 gości

cron