» Poradna » Programy

Pro programatory v C++

 |   | 

Jsem zacatecnik v C++ a mam tu jeden problem. Vytvoril jsem jednoduchyprogram pro windows pomoci OOP. Omluvte veskere blbosti, je to jen jakz takz poskladany uryvek.class trida {public: trida() {  wc.style  =CS_HREDRAW | CS_VREDRAW | CS_OWNDC;  wc.lpfnWndProc=WndProc; //vyzaduje obsluznou funkci   /*Tady je problem.  Potrebuju, aby okenni procedurou byla proc. trida::WndProc,  jenomze nevim, jak na to. Chce to ukazatel na funkci. Pokazde mi to vyhodi, ze nejde   pretypovat z __stdcall trida::* ... na __stdcall * ...  Budu vdecny za kazdou radu, jak to zprovoznit.  */   wc.cbClsExtra=0;  wc.cbWndExtra=0;  wc.hInstance=hInstance;  wc.hIcon=LoadIcon(NULL, IDI_WINLOGO);  wc.hCursor=LoadCursor(NULL, IDC_ARROW);  wc.hbrBackground=NULL;  wc.lpszMenuName=NULL;  wc.lpszClassName="Okno"; } LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { ... }int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { trida t; return 0;} 

Mohlo by vás také zajímat

Odpovědi na otázku

 |   | 

uf, tieto veci som vzdy robil bez objektu, vacsinou bez OOP. Ak uz robim OOP tak pouzijem MFC a tam uz su taketo veci urobene v MFC frameworku.On ti hlasi ze ta WndProc je u teba clen triedy, a ze sa teda smernik na nu neda automaticky pretypovat na obycajny smernik funkcie, keby si ho pretypoval manualne = dat pred to do zatvorky pretypovanie, t.j. takto:wc.lpfnWndProc=(WNDPROC)WndProc;mozno to pomoze, ale ci tam potom nebude problem s tym ze to je v objekte, tu funkciu totiz volaju priamo Windowsy ak je pre to okno nejaky message. Asi bude lepsie na zaciatok WndProc() dat mimo triedy a radsej by som ju aj nejako inac nazval, nikto nevie ci niekde v headroch alebo kde nie je symbol WndProc pouzity...

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Teraz sa zamyslam, v MFC to musi byt v triede CWnd, takze sa to musi dat aj ked ta funkcia je clen triedy(mozno sa to da aj v MFC zdrojakoch najst - su sucastou VC++), ale skus to len pretypovat ako pisem v predch. prispevku. Ak nepomoze daj vediet...

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

wc.lpfnWndProc=(WNDPROC)WndProc;nic neresi. Problem je v tom, ze promenna chce ukazatel a vraci to ukazatel na tridu. Kdyz tam dam cos psal, tak to vyhodi, ze takova funkce neexistuje.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Co vsetko sa ti v programe vola WndProc ? Skusal si iny nazov tej funkcie? Ak si v triede tak WndProc nemoze byt ukazatel na triedu, defaultne sa berie clen triedy, t.j. v tvojom pripade ta fcia, mozes skusit este this->WndProc. Alebo skopiruj sem ake chybove hlasenie presne ti to vypise.Ale vseobecne, registrovanie triedy okna (t.j. to na co sa pytas) by som do triedy nikdy nedaval, aj ked mas OOP program tak mozes robit funkcie ktore nepatria do ziadnej triedy ak je to logicky ziaduce, myslim ze v tomto pripade je...

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

BTW:wc.lpfnWndProc=(WNDPROC)WndProc- skusal si to ? Co sa stane? Manualne pretypovanie by malo fungovat aj keby si chcel pretypovavat jablko na hrusku (ale zas nie uplne vzdy).

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

jaj sorry, sak to tam pises, asi uz blbnem. Tak nic.Ale lepsie je, ak mas problem pri preklade, skopirovat sem presne ake chybove hlasenie ti to vyhodi, ono pri chybovom hlaseni prekladacov je podstatne kazde pismeno ...

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Sorry za tolko prispevkov, este nieco - mas tu funkciu deklarovanu v headri a header includnuty? = asi je jasne co chcem povedat, predpokladam ze to vies, len keby nahodou: v jazyku C, predtym ako pouzijes nejaku funkciu, musi byt jej deklaracia alebo definicia.A ak je ta WndProc uz mimo triedy tak by som radsej pisal v tom problemovom riadku ::WndProc (tym sa uistis ze sa pouzije fcia ktora je mimo akejkolvek triedy).

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Samo.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Diky MM, ze ses tomu venoval, ale uz to muzes pustit z hlavy(ja to taky udelal).

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

No, mne to zas teraz neda pokoj preco to je take tvrdohlave, uz som aj zapol VC++ kvoli tomu, je to tak ako pises (ak je WndProc clen triedy), no, divne je to, ak ale WndProc je mimo triedy tak bez problemov, pgm som copy-pastol do noveho prispevku nizsie, pokracujeme tam .

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Zkusal, ale nafakci to. Kdyz to udelam, tak mi to vyhodi, ze pry funkce daneho typu neexistuje. Vsechno pretypovat nelze.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

No, pozrel som si tie zdrojaky MFC co su k VC++, nie je v tych zdrojakoch vsetko, ale:To na co sa ty pytas je registrovanie "triedy okna" vo windowsoch, no a ty to chces robit v konstruktore, takze pri kazdom vytvoreni objektu podla tej tvojej triedy by sa to potom pokusalo registrovat "triedu okna" vo windowsoch, to by asi moc neklaplo, pre jeden objekt tej triedy by to asi slo, ale pre dalsie by to neklaplo (nemoze byt pod win viac tried okien s rovnakym nazvom).V MFC je toto registrovanie "triedy okna" mimo akejkolvek OOP triedy, t.j. je to ako samostatna staticka funkcia. Teraz ale je sranda smernik akej funkcie tam dat do toho wc.lpfnWndProc, MFC tam dava DefWindowProc (t.j. default WinAPI window proceduru ktora pre vacsinu messagov nerobi nic), no a potom ked sa vytvaraju uz objekty triedy CWnd, teda okna, tak sa pouzije vzdy len jedna uz zaregistrovana "trieda okna" (tou statickou funkciou, mimo triedy) a zmeni sa uz len smernik na funkciu toho konkretneho okna, da sa to napr. pomocou WinAPI funkcie SetWindowLong s parametrom nIndex = GWL_WNDPROC.Je viac moznosti podla toho co chces robit, inac na zaciatok odporucam toto nerobit v OOP alebo ak OOP tak pouzit nejaku objektovu kniznicu (napr. MFC v VC++) - tam sice clovek nevidi do hlbky co sa tam vlastne deje, ale aspon mozno rychlejsie budes vidiet vysledok .

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Delal sem to pro OpenGL, takze sa nebojim, ze by se vytvorilo vice oken, kdyz tak by to slo jednoduse obejit. Me slo spis o zapouzdreni vsech dat do tridy. Na tom uz nedelam, ale pro priste jsem chtel vedet, proc to nejde. Nevim, ale podle me to nicemu neodporuje. Co je tak tezkeho na ziskani ukazatele na fci. Jinak ale dikes.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Nie je to nic tazkeho, ale je trochu filozoficky rozdiel medzi OOP a neOOP, ale myslim ze problem bol v roznych typoch smernikov, co sa automaticky nepretypovava, ak to clovek naozaj chce, treba pouzit manualne pretypovanie.Ale OK, ak mas zaujem to riesit tak vid tie prispevky vyssie, ak nie, nechajme to.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Takze, neda mi to , tak som si to skusil vo VC++.Inac v tvojej povodnej otazke chyba jedna zatvorka } takze nie je jasne kde konci trieda, dalsia vec je ze ak je WndProc v triede tak by mala byt zadefinovana ako LRESULT CALLBACK trida::WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) {... }ale to je teraz jedno.Skusil som to najprv tak ze ta WndProc je mimo triedy, tak je to bez prooblemov, prikladam cely program:LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); // len deklaracia fcieclass trida {public:trida(HINSTANCE hInstance) {  WNDCLASS wc;  wc.style  =CS_HREDRAW | CS_VREDRAW | CS_OWNDC;  wc.lpfnWndProc = WndProc; //vyzaduje obsluznou funkci   wc.cbClsExtra=0;  wc.cbWndExtra=0;  wc.hInstance=hInstance;  wc.hIcon=LoadIcon(NULL, IDI_WINLOGO);  wc.hCursor=LoadCursor(NULL, IDC_ARROW);  wc.hbrBackground=NULL;  wc.lpszMenuName=NULL;  wc.lpszClassName="Okno"; }};LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){ return 0;} int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){ trida t(hInstance); return 0;}Ale ak je WndProc clen triedy tak to je problem (ako pises), on tam nepise ze to WndProc je smernik na triedu, on ma naozaj smernik na trida::WndProc a nemoze ho skonvertovat na smernik na obycajnu funkciu. Predpokladam ze tam je principialny problem, kedze triedy su vlastne nieco ako struktury smernikov a nejakym sposobom sa nesmie smernik na fciu z triedy predat funkcii ktora nerata s tym ze ta fcia je clenom nejakej triedy.OK, zabudni na tie prispevky vyssie, ak na nieco pridem dam vediet.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Zase som si to pozrel v zdrojakoch MFC ako to riesil samotny microsoft (celkom dobry zdroj informacii ), no a tam je tiez ta funkcia ktoru volaju priamo windowsy (t.j. ako u nas WndProc) mimo triedy, ak niekoho zaujima vola sa AfxWndProc, no a kedze ta funkcia ma parameter HWND hWnd, tak sa vie o ktore okno sa jedna, no a potom sa nejakym sposobom zisti smernik na objekt CWnd (povedzme premenna cwnd), ktory prislusi tomu hWnd, no a potom sa zavola normalne cez cwnd->WindowProc(...) ta funkcia z tej triedy CWnd. Neviem preco to tam robia takto uhodene, ale urcite to ma nieco do cinenia s tym ako su robene objekty a co vsetko sa musi vykonat pred volanim funkcie v nejakej triede, ak compiler najde volanie cwnd->WindowProc(...) tak to skompiluje tak aby vsetko klaplo po volani funkcie tej triedy, ale ak tu funkciu vola niekto iny (v nasom pripade samotne windowsy) tak nemoze vediet do akej triedy sa skace takze nemoze ani nastavit vsetky potrebne veci (ja neviem, mozno niektore registre apod.).Asi preto sa ani nesmie pretypovat smernik trieda::Funkcia() na smernik na obycajnu Funkcia().Ok, asi najlepsie na konkretne tieto srandicky s triedou okien a ine CALLBACKY nepouzit OOP, predpokladam ze na nic lepsie nepridem kedze aj samotny mrkvosoft to v MFC robil tak uhodene. Ale keby nahodou som na nieco nove prisiel tak dam vediet...

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Este k tomu chybovemu hlaseniu, aby to bolo  jasne:cannot convert from 'long (__stdcall trida::*)(struct HWND__ *,unsigned int,unsigned int,long)' to 'long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long)'to "long (__stdcall trida::*)(struct HWND__ *,unsigned int,unsigned int,long)" je smernik na funkciu z triedy "trida" a ta funkcia ma parametre (struct HWND__ *,unsigned int,unsigned int,long). Nie je to smernik na triedu. Vsimni si ze to "long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long)" je to iste, len tam chyba to trida::Teda ty mas smernik na funkciu trida::WndProc(...) , len ho nesmies pouzit ako smernik na obycajnu funkciu (ktora nie je clen ziadnej triedy).Ok, dost bolo, sorry za tie pokusy zo zaciatku, nechcelo sa mi zapinat VC++ 

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Pri pouziti operatoru this je uplne stejna chyba jako chybove hlaseni uplne nahore.Rikal sem si, ze bez this to prece nemuze fungovat. Protoze nemuzu dostat ukazatelna metodu tridy, ktera neni deklarovana jako static. Tak jsem ji deklaroval jakostatic(ve zdrojaku i headru):opengl.cpp(3) : error C2724: 'Proc' : 'static' should not be used on member functions defined at file scopeTohle ale fakt nevim. Ja sem sa ucil OOP v Jave a tam je to prece jenom trochu jiny,takze nevim esli v C++ jde deklarovat metodu jako static.Ty tridy okna sem mel ochranene, ze se nejprve testovalo, esli trida existuje a azpak se registrovalo. Ta ukazka kodu byla jen "slatanina". I tela vsech funkci byla ve zdrojakua ne v headru.Este neco. Ja vim, ze by se to v poho udelalo bez OOP, ale to by uz tam musely bytnejake globalni promenne a byl by v tom celkem zmatek. Proto sem zvolil OOP a jehoskvelou vlastnost - zapouzdreni dat do objektu. Program mel byt vlastne zaklad velmi primitivniho enginu v OpenGL. S OOP se mi to zdalo vice "elegantnejsi".Uz sem vyzkousel snad vsechno, ale nejede to. Nejlepsi bude, kdyz to oba pustime z hlavy.BTW: Nejsem si zcela jisty vyznamem slova "smernik". Je to ukazatel(pointer)?

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Ano, smernik je pointer, sorry, v SR sa to pouziva ako preklad slova pointer .Co sa tyka static funkcie teraz neviem, ale podla mna to problem nevyriesi, problem je pravdepodobne na urovni stroj.kodu v principe prekladu objektov, ako som pisal v predch. prispevkoch - o tom volani funkcie objektu, s tym uz asi neurobis nic, kedze aj samotny MS to dal v MSC mimo objektu, nie vsetky nizkourovnove veci sa daju "zapuzdrit" do objektov, ono na to ani neboli robene, OOP je vyhodne pri celkovom navrhu projektu, ale tieto callbacky a ine nizkourovnove veci asi takto nejdu.Pri pouziti napr. MFC ale nemas s takymi vecami probem, uz je to tam urobene...Ja uz na to kaslem, je to ale zaujimavy problem, nestretol som sa este s tym kvoli tomu co som pisal hned na zaciatku - ak robim priamo s WinAPI - ziadne OOP, ak robim OOP tak s MFC.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Este k tomu "static" - podla MSDN:...When modifying a member function in a class declaration, the static keyword specifies that the function accesses only static members.Neviem ci by to helplo, mozno hej, mozno nie...

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

A nebude to tim ze callback muze byt pouze bud globalni funkce (ne clenska funkce nejake tridy) a nebo staticka clenska funkce? To je docela znama vec.Standa.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Uz sem to tam myslim nekde psal, ze sem to zkousel deklarovat jako static, ale nefungovalo to.(Jsem zacatecnik v C++, ze vseho co delam vychazim z Javy)

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

Ano, je to tym, nedavno som narazil na volanie nejakych objektov shellu z obycajneho C prekladaca, funkcia ktora je clenom objektu ma prvy parameter this (C++ prekladac to robi automaticky), ale kedze callback je volany priamo z Windowsov tak tam ziadne this nie je, teda nie je mozne pouzit clena objektu. Otazka je so statickou fciou, v C++ je staticka fcia fcia ktora moze pouzit len staticke cleny, to by asi implikovalo ze tam nemusi byt this, ale nie som si teraz isty ako to prekladac prelozi (ale si zas obmedzeny statickymi clenskymi premennymi, takze to uz je jedno ci to das mimo objekt)...

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   | 

... BTW. neviem ci je to az tak zname, podvedome som doteraz robil callbacky mimo tried, ale nespominam si ze by som to v MSDN cital. Ale kedze robim nejaky cas profesionalne v assembleri tak je mozne ze som to len zabudol .

Souhlasím  |  Nesouhlasím  |  Odpovědět

Související témata: NULL