Newsgroup: it.comp.programmare.win32
Titolo: [C++] funzioni membro in un call back (WndProcedure) si può?

Ciao.
Solitamente con SetWindowLong, impostavo una
CtrlProc(hwnd,message,wParam,lParam), separata dalla classica WndProc, per
compiere certe operazioni nella gestione di una finestra secondaria.
Dopo ho avuto la necessità di riusare più volte quel tipo di controllo ed ho
avuto la triste pensata di crearmi una classe, pensavo fosse la soluzione
migliore... invece sono cominciati i problemi.
Purtroppo, non sono riuscito a definire la CtrlProc come membro di quella
classe, perché quando passo il suo valore alla funzione SetWindowLong, lei
accetta un LONG che è in realtà l'indirizzo della LRESULT CALLBACK WNDPROC e
non un nomeclasse::miafunzione...
Ottengo infatti i seguenti errori!
[C++ Error] FPCONTROLS.H(123): E2034 Cannot convert 'long (__stdcall
fp_Control::*)(void *,unsigned int,unsigned int,long)' to 'long (__stdcall
*)(void *,unsigned int,unsigned int,long)'
[C++ Error] FPCONTROLS.H(124): E2034 Cannot convert 'long' to 'long
(__stdcall *)(void *,unsigned int,unsigned int,long)'
Ecco una sezione del codice, nel costruttore della classe, che ritorna quel
tipo d'errore...
                WNDPROC _prc;
                WNDPROC ctrlp;
                ctrlp=&fp_Control::CtrlProc;
                _prc=SetWindowLong(myHwnd,GWL_WNDPROC,(LONG)ctrlp);
la CtrlProc è la solita definizione...
class fp_Control {
...
virtual LRESULT CALLBACK CtrlProc(HWND,UINT,WPARAM,LPARAM);
...
};
Potrei mettere una CtrlProc esterna, fuori dalla classe e puntarci tutte le
istazne della classe, ma chissà che casino ci salta fuori, dopo dovrei
risalire al controllo che chiama e differenziare il codice... vorrei
evitare.
Chiedo a voi, più esperti di me, innanzitutto se si può fare e mi sono
sbagliato io, oppure se non è possibile e se vi siete già imbattuti in
questo problema, quale sarebbe il modo più brillante di superarlo?
Nota: compilo sia con il Dev-C++ che con il C++ della Borland.
Grazie a tutti!!
Paolo Ferraresi (
fp...@tin.it
)


wrote:
[cut]
Hai provato a definire con static la funzione callback ?
Es. file pinco.h
class Pinco
{
private:
	static long WINAPI PincoWndProc(HWND,UINT,WPARAM,LPARAM);
etc etc
Poi definisci nel corpo della classe la tua funzione 
file pinco.cpp
long WINAPI Pinco::PincoWndProc(HWND hwnd,UINT msg,WPARAM
wParam,LPARAM lParam)
Ciao
Stefano "HappyMan" 
--
Personal Web 
http://www.sgr.info
Email 
happyman...@libero.it
 [Togliere nospam per scrivermi]
Salsa Web 
http://happyman.n3.net
 [Foto salseri/e & I.A.B.L.A. Ring]
IABLA Sezione Lago Maggiore (NO)

 evitare.
In effetti è ciò che viene fatto in MFC; ovvero esiste una mappa (a livello
di thread) che associa l'handle hwnd di una finestra ad una classe CWnd
(quando essa esiste ovviamente). Poi la funzione globale di risposta ai
messaggi (AfxWndProc mi pare, o qualcosa di simile) recupera l'istanza CWnd
della finestra che deve gestire il messaggio e chiama la funzione membro di
risposta ai messaggi della classe giusta.
Ciao
Porlock

 viene richiesta una funzione standard
Si', la funzione membro viene dichiarata "static" ed
e', in realta', un'unica funzione valida per tutte le
istanze.
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 istanze.
ma in qusto caso la funzione membro non ha accesso this, quindi ai dati
della classe. Di fatto dichiarare una funzione membro come static equivale
a dichiararla nel modulo. E' un problema che ho avuto con TAPI e OpenGL, lo
avevo risolto creando una lista (globale) di puntatori alla mia classe,
ogni classe nel costruttore si andava ad aggiungere in lista. Ogni volta
che veniva chiamata, la funzione di callback scandiva la lista per vedere a
quale istanza era riferita, dal puntatore a tale istanza si ottenevano poi
i dati membro.
spero possa servire.
ciao
Ermando

della classe. 
Io ho risolto in questo modo:
sia Pinco la mia classe e PincoWndProc la static callback, quando creo
la finestra, in un metodo qualsiasi dove ho accesso a this scrivo
CreateWindow(..bla..bla....(HMENU)Id,hInst,this); 
Nella callback
long WINAPI Grid::PincoWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM
lParam)
{
LPCREATESTRUCT lpcs;
Pinco *p;
// Prelevo il puntatore all'oggetto a cui è associata la finestra
p=(Pinco*)GetWindowLong(hwnd,GWL_USERDATA);
if (p==0 && msg!=WM_CREATE)	// Finestra non ancora inizializzata
return(DefWindowProc(hwnd,msg,wParam,lParam));
switch (msg)
{
case WM_CREATE:
// Registro nella memoria aggiuntiva di ogni finestra il puntatore
// all'oggetto a cui è associata
lpcs=(LPCREATESTRUCT)lParam;
p=(Pinco*)lpcs->lpCreateParams;
SetWindowLong(hwnd,GWL_USERDATA,(LONG)p);
return(0);
