> Sicer se ne spoznam na C++:
Pri meni je ravno obratno, spoznam se na C++, vendar ne na
unixski "mambo jambo".
> class Ggg {
> void tiskaj();
> };
> kje ga lomim?
> Ko ti poklices funkcijo iz gtk-ja ne poda "hidden parameter" (aka.
> kazalec na objekt, ki klice metodo).
Genau! Ce se nekaj klice kot callback, potem mora biti to deklarirano
static. Obstaja pa nekaj itsy-bitsy problemckov s staticnimi funkcijami.
1. nimajo this pointerja in
2. lahko deklariras samo eno za vse objekte dolocenega razreda.
Nic ni narobe, dokler uporabljas le en razred. Uporabis singleton
pattern in poskrbis za nadzorovano inicializacijo.
V primeru, da potrebujes vec razredov, pa obstaja klasicen C++ workaround,
za ta problemcek. Denimo, da delas wrapper za window. Vsak window ima
callback
proceduro, ki sprejema sporocila (recimo enemu od sporocil: OnRedraw).
Definiras razred window:
class Window {
public:
void Window(HANDLE hWindow_);
protected:
virtual void OnRedraw() {}; // or =0 for required interface members
private:
static list<WindowMapEntry> wme_;
static void Callback(HANDLE hWindow_, MESSAGE Message_, WINDOWPARAMETER
wParameter_);
};
struct WindowMapEntry {
HANDLE hWindow_,
Window *thisptr_;
};
Rings a bell? Tvoj konstruktor mora za vsak skonstruirani Window
objekt spraviti dvojico (hWindow in this) v listo (pravzaprav bi
slo tudi z drugo STL strukturo, vendar se mi ne ljubi brskati po
dokumentaciji). Lista pa je staticna in dosegljiva iz vsakega
razreda.
Tvoja callback funkcija mora ob sporocilu poiskati handle v tej
listi in prevezati klic na thisptr. Ce ponazorim celotno zadevo
s psevdo kodo:
if (wme.hWindow_=hWindow_ && Message_=ON_REDRAW)
(Window *)(wme.thisptr_)->OnRedraw();
Voila.
Vsa nadaljna okna lahko kodiras kot (npr.):
class MainWindow : public Window {
public:
void MainWindow(string sTitle_, HANDLE hWindow_) : Window (hWindow) {
SetTitle(hWindow,sTitle.cstr());
}
virtual void OnRedraw() {
// your drawing code here...
}
};
nizko-nivojska koda je ze izolirana, enkapsulirana, karkoli ze
v dolocenem trenutku v zgodovini zveni bolj cool. Gre za to, da si
dvignil nivo abstrakcije do nivoja C++ in zdaj lahko pozabis na
operacijski sistem. Yuperoo.
Edini problem nastane, ker je teh sporocil lahko veliko in tako vsak objekt
za okno tovori s seboj zajetno vtbl... Problem lahko deloma resis tako,
da delas tabelo kazalcev na funkcije za vsako okno (torej mapiras handle,
sporocilo in funkcijo - 2 kljuca in 1 podatek), ko je to narejeno v MFCju
(message maps). Ampak, v bistvu to zadeve bistveno bolj zakomplicira za
koncnega (no, srednjega) uporabnika, ki mora potem te message mape zgraditi,
ponavadi z uporabo predprocesorja, kar je po mojem prepricanju urnebesno
grdo,
ne, ugly beyond recognition. Vsaka resitev ima svoj + in svoj -. Na koncu se
je za nekaj treba odlociti.
Kakor bi poeticno rekli malo bolj na jugu: "ne mozes da jebes, a da ti ne
ude.",
a ne punce?
Lp,
Tomaz