MSalters schreef op 25 april 2004 @ 22:23:
Functions decayen naar pointers in expressies, dus DlgProc==&DlgProc. Dat zal het probeelm niet zijn. Een cast levert ernstige problemen op, je negeert actief een verschil in calling conventies. Dat is nooit gezond. De suggestie om BOOL CALLBACK DlgProc te vervangen door BOOL __stdcall DlgProc lijkt me wel zinnig.
Dat is juist het hele probleem, die CALLBACK is gewoon een macro voor __stdcall, dus het zou moeten werken, maar dat was het dus ook niet. Vandaar ook dat ik
hier zei dat het krom was, maar ja, VC++ 6.0 he
Ik vermoedde een thiscall, maar de compiler laat dat meestal zien met een __thiscall calling convention, dus ik dacht dat het dat niet zou zijn. Nu ik naar z'n gehele code kijk zie ik idd dat het daaraan ligt
tdm: Je functie is niet static, hij is verbonden aan een object. Die kun je dus niet zomaar converteren naar een statische functie. Declareer 'm dus als static. Je zult dan helaas wel wat werk moeten doen om de juiste CWin instance bij de HWND te vinden. Opties zijn userdata in de window-long (Get-/SetWindowLong), een lookuptable (bijvoorbeeld een std::map[nohtml]<HWND, CWin *>), of zogenaamde thunks (een stukje asm code gecodeerd als memberdata die je gebruikt als windowproc, dus vervolgens de this pointer op de stack pusht en een algemene functie aanroept zodat je de CWin * ook gewoon als parameter in je windowproc hebt. Voor de gevorderden

)
.edit: euh wat Dim ook al zei dus

Dim schreef op 25 april 2004 @ 22:42:
Het probleem is dat jouw DialogProc functie een non-static member is van je CWin class. Dat kan helaas niet voor callback functies zoals event handlers, dat moeten namelijk altijd globaal benaderbare functies zijn, terwijl je een class member functie alleen kunt aanspreken als je een object (en dus een this pointer) hebt.
Probeer de methode die je hebt gebruikt voor de gewone WndProc, namelijk een globale wrapper functie die g_pcWin->MsgProc aanroept, ook voor je DlgProc, dus zo:
C++:
1
2
3
4
5
6
7
| //////////////////////////////////////////////////////////////////
// Nog zo'n koppeling van Win32 -> klasse
//////////////////////////////////////////////////////////////////
LRESULT CALLBACK DlgProcWrapper(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return g_pCWin->DlgProc(hWnd, uMsg, wParam, lParam);
} |
En dan later bij de CreateDialog de globale wrapper functie meegeven:
C++:
1
| m_hWnd = CreateDialog( m_hInstance, MAKEINTRESOURCE( IDF_MAIN ), NULL, DlgProcWrapper ); |
Twee "fouten" aan deze aanpak. Of tenminste, de eerste is echt fout, de tweede is meer dat het gewoon niet netjes is
CreateDialog returnt een hWnd, die je vervolgens kunt assignen. Echter, er worden al window messages verzonden naar je windowproc voordat CreateDialog retourneert, zoals WM_CREATE voor een window, en WM_INITDIALOG voor een dialog. Aangezien de pointer dan naar iets anders wijst naar de juiste window gaat dit fout (typisch een access violation als je voor het eerst een window aanmaakt in je app)
De tweede fout is niet echt een technische fout, maar meer ontwepfout: je kunt met een globale pointer namelijk maar 1 window tegelijk hebben, wat niet altijd iets is dat je wilt

Overigens, het is een beetje onzin om RegisterClass te gaan doen, want dat is helemaal niet nodig voor CreateDialog en dialog boxes in het algemeen.
Maar wel voor CreateWindow uiteraard. En aangezien de aanroep naar CreateWindow er ook in staat maar uitgecomment is, denk ik dat ie het registreren van de class ook simpelweg is vergeten uit te commenten
[
Voor 45% gewijzigd door
.oisyn op 25-04-2004 23:36
]