Oppure

Loading
05/03/10 21:03
Exor
salve forum :)

ho questa classe:

	class MainDlg {
		public:
			MainDlg();
			MainDlg(HINSTANCE hInstance, LPTSTR lpTemplate, HWND hParent);	// costruttore
			void OnInitDlg(HWND hDlg);	// on dialog init
			INT_PTR CALLBACK MainDlgProc(HWND, UINT, WPARAM, LPARAM);
		private:
			HWND hDlg;
	};


nel costruttore MainDlg(HINSTANCE hInstance, LPTSTR lpTemplate, HWND hParent); io cerco di inizializzare una dialog:
MainDlg::MainDlg(HINSTANCE hInstance, LPTSTR lpTemplate, HWND hParent)
{
// HWND nRes; var d'appoggio

	nRes = DialogBox(hInstance, lpTemplate, hParent, &MainDlg::MainDlgProc);
	if (nRes)
		hDlg = (HWND)nRes;
}


come quarto parametro della macro DialogBox dovrei dare un valore DLGPROC, che dato come funzione normale, non ci sono problemi, ma dato come membro di una classe il compiler mi da errore:

error C2664: 'DialogBoxParamA': impossibile convertire il parametro 4 da 'INT_PTR (__stdcall ExAppNS::MainDlg::* )(HWND,UINT,WPARAM,LPARAM)' a 'DLGPROC'


mi potreste aiutare a capire come mai non funziona ?

grazie :)

PS: dimenticavo di dire che neanche con un cast riesco a risolvere.
aaa
05/03/10 21:15
TheKaneB
un puntatore a funzione differisce da un puntatore a membro per una sottile, ma sostanziale, differenza.

La chiamata a membro presuppone il passaggio (implicito) del puntatore "this".

Es:
Classe miaClasse;
miaClasse.chupa();


il metodo chupa() sembrerebbe non avere alcun parametro in input, ma in realtà il compilatore inserisce (a tradimento) un parametro in questo modo:

Classe miaClasse;
Classe *puntatoreThis;
puntatoreThis = &miaClasse;
chupa(puntatoreThis);


Questo significa che la chiamata a membro non può avvenire se non esiste un "this" da passare come primo parametro. Infatti in C++, se vuoi chiamare un puntatore a metodo, devi prima associarlo ad una istanza di classe del tipo corretto.
Nel caso specifico della tua domanda, credo non ci sia nulla da fare. La libreria si aspetta un puntatore a funzione "classico", perchè internamente non effettua nessuna associazione classe/funzione, quindi non avrebbe nessun "this" da passargli, e la chiamata non potrebbe avere luogo.

Rassegnati ad usare un normale puntatore a funzione in questo caso :)

Ciao!
aaa
05/03/10 21:34
nessuno
A seconda dell'utilizzo che ne farai, potresti risolvere dichiarandola static

static INT_PTR CALLBACK MainDlgProc(HWND, uint, WPARAM, LPARAM);
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
06/03/10 9:45
Dax89
Questo è un problema tipico, conosco molte persone che usano le WinAPI e il C++ per fare un programma visuale utilizzando le classi, tutti si scontrano con questo problema, per "aggirarlo" c'è un piccolo trick:

Nella tua classe MainDlg oltre alla window procedure statica ne aggiungi un'altra non statica, il trick è semplice, fai in modo che la window procedure statica richiami quella non statica, salvando il "this" per recuperarlo in seguito e chiamando la funzione "wndProc" non statica.

Cambia la chiamata da DialogBox a CreateDialog, questa funzione (a differenza di DialogBox) ti restituisce l'handle della finestra che hai appena creato, il motivo si vedrà poco più sotto.

Quindi:

MainDlg::MainDlg(HINSTANCE hInstance, LPTSTR lpTemplate, HWND hParent) 
{
   /*
    * La variabile hWnd la puoi mettere come membro privato della classe
    * così è accessibile ad ogni funzione.
    */

   HWND hWnd = CreateDialog(hInstance, lpTemplate, hParent, &MainDlg::msgRouter); 
   
   // Salvi l'istanza della classe.
   SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG)this);
}

/*
 * Questa è la window procedure statica che passerai alla funzione CreateDialog
 */
BOOL MainDlg::msgRouter(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  //Recuperi l'istanza della classe.
  MainDlg* pDlg = (MainDlg*)GetWindowLongPtr(hWnd, GWL_USERDATA);

  if(pDlg)
  {
    /*
     * Chiamata alla Window Procedure non Statica
     */
    return pDlg->wndProc(hWnd, msg, wParam, lParam);
  }

  return FALSE;
}

/*
 * Questa è la window procedure NON statica (chiamata da quella statica)
 * quì gestisci gli eventi.
 */
BOOL MainDlg::wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    /*
     * Gestisci i tuoi messaggi e accedi alle informazioni non statiche
     * della classe.
     */
}


Spero sia chiaro quello che ho scritto :rofl:
:k:
Ultima modifica effettuata da Dax89 06/03/10 10:12
aaa
06/03/10 11:14
Exor
.
.
.
Spero sia chiaro quello che ho scritto :rofl:
:k:


:) grazie mille

stavo pensando ad un trick del genere auhuauh ma non c'ero arrivato ancora

grazie mille per l'info
aaa