WinMain überladen



  • Ok, ich programmiere seit ein paar Jahren C++, möchte mich jetzt aber mehr der Windows Programmierung widmen... ich habe zwar schon ein paar kleinigkeiten in C gemacht aber ich bin nicht in der lage folgendes beispiel welches ich fast 1:1 aus dem petzold abgeschrieben habe zum laufen zu bringen:

    #include <windows.h>
    
    LRESULT CALLBACK WndProc(HWND hwnd, unsigned int msg, WPARAM wPar, LPARAM lPar);
    
    int WINAPI WinMain(HINSTANCE inst, HINSTANCE prevInst, LPCTSTR cmdline, int show)
    {
    	static TCHAR progName[] = TEXT("Test");
    
    	WNDCLASS _wc;
    	_wc.style			= CS_HREDRAW | CS_VREDRAW;
    	_wc.lpfnWndProc		= WndProc;
    	_wc.cbClsExtra		= 0;
    	_wc.cbWndExtra		= 0;
    	_wc.hbrBackground	= reinterpret_cast<HBRUSH> (GetStockObject(WHITE_BRUSH));
    	_wc.hCursor			= LoadCursor(0, IDC_ARROW);
    	_wc.hIcon			= LoadIcon(0, IDI_APPLICATION);
    	_wc.hInstance		= inst;
    	_wc.lpszClassName	= progName;
    
    	if (!RegisterClass (&_wc))
    	{
    		MessageBox(NULL, TEXT("Fehler: RegisterClass()"), TEXT("Fehlermeldung"), MB_ICONERROR);
    		return 0;
    	}
    
    	HWND hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, progName, TEXT("Testprogramm"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
    		NULL, NULL, inst, NULL);
    	ShowWindow(hwnd, show);
    	UpdateWindow(hwnd);
    
    	MSG msg;
    	while(GetMessage(&msg, NULL, NULL, NULL))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    	return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, unsigned int msg, WPARAM wPar, LPARAM lPar)
    {
    	switch(msg)
    	{
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	default:
    		break;
    	}
    	return DefWindowProc(hwnd, msg, wPar, lPar);
    }
    

    Das ganze meldet nur einen Fehler:

    d:\in Arbeit\Win32\Lib\Basic\basic.cpp(6): error C2731: 'WinMain' : function cannot be overloaded

    Ich habe keine Ahnung woran das liegt... eventuell Compilerswitch oder direkt ein Fehler in dem was ich abgeschrieben hab?? wobei ich letzeres eher bezweifel.
    ich arbeite mit VC7.0 unter WindowsXP

    Vielen Dank im Voraus für Hilfe

    lg DGATmaster



  • ok, mittlerweile läst sich das ganz kompilieren,
    das problem war das LPCTSTR in der Parameterliste von WinMain mit LPSTR funktioniert es...
    dafür erhalte ich jetzt eine Exception bei RegisterClass(&_wc);
    echt schlimm... mit VC6 hat dieses beispiel nie probleme gemacht...





  • DGATmaster schrieb:

    dafür erhalte ich jetzt eine Exception bei RegisterClass(&_wc);

    und wie sieht die aus?



  • Es tritt folgende Fehlermeldung beim Aufruf von RegisterClass auf:

    Unhandled exception at 0x77d269e1 in Basis.exe: 0xC0000005: Access violation reading location 0xcccccccc.

    kA was das soll... spielt da eventuell die .Net CLR mit oder warum ist das so?



  • du hast bei der initialisierung von _wc

    _wc.lpszMenuName = NULL;
    

    vergessen.



  • miller_m schrieb:

    dritter param
    LPSTR == char*
    LPCTSTR == const char*

    Fast

    LPSTR == char*
    LPCTSTR == const TCHAR*
    


  • groovemaster schrieb:

    miller_m schrieb:

    dritter param
    LPSTR == char*
    LPCTSTR == const char*

    Fast

    LPSTR == char*
    LPCTSTR == const TCHAR*
    

    hätte ich mal nachgeschaut 🙂



  • ok, danke erstmal für die vielen rückmeldungen...
    soweit ich weiß ist:

    LPSTR TCHAR*
    LPCTSTR const TCHAR*
    und TCHAR entweder char oder wchar
    

    dieses problem hat sich zum glück bereits gelöst...
    leider tritt trotz _wc.lpszMenuName = NULL; bzw _wc.lpszMenuName = 0; die bereits erwähnte Exception auf...
    habe die komplette _wc memberinitialisierung auskommentiert und schrittweise die zeilen mit HINSTANCE und WNDPROC wieder hinzugefügt... logischerweise treten wenn diese fehlen entsprechende Fehler auf...

    im Moment siehts so aus:

    _wc.cbSize			= sizeof(WNDCLASSEX);
    	_wc.style			= CS_HREDRAW | CS_VREDRAW;
    	_wc.lpfnWndProc		= WndProc;
    	_wc.cbClsExtra		= 0;
    	_wc.cbWndExtra		= 0;
    	_wc.hbrBackground	= (HBRUSH) (GetStockObject(WHITE_BRUSH));
    	_wc.hCursor			= LoadCursor(0, IDC_ARROW);
    	_wc.hIcon			= LoadIcon(0, IDI_APPLICATION);
    	_wc.lpszMenuName	= 0;
    	_wc.hInstance		= inst;
    	_wc.lpszClassName	= progName;
    
    	try
    	{
    		if (!RegisterClassEx (&_wc))
    		{
    			throw 0;
    			MessageBox(NULL, "Fehler: RegisterClass()", "Fehlermeldung", MB_ICONERROR);
    			return 0;
    		}
    	}
    	catch(...)
    	{
    		char temp[128];
    		FormatMessage( 
    			FORMAT_MESSAGE_FROM_SYSTEM | 
    			FORMAT_MESSAGE_IGNORE_INSERTS,
    			NULL,
    			GetLastError(),
    			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    			temp,
    			128,
    			NULL );
    		MessageBox(0, temp, "Fehler!",MB_ICONERROR);
    	}
    

    der rest ist gleichgeblieben und ich bekomme den fehler falscher Parameter...



  • DGATmaster schrieb:

    soweit ich weiß ist:

    LPSTR TCHAR*
    LPCTSTR const TCHAR*
    und TCHAR entweder char oder wchar
    

    Nicht ganz, LPSTR ist schon char*. LPTSTR ist TCHAR*.

    DGATmaster schrieb:

    im Moment siehts so aus:

    _wc.cbSize			= sizeof(WNDCLASSEX);
    	_wc.style			= CS_HREDRAW | CS_VREDRAW;
    	_wc.lpfnWndProc		= WndProc;
    	_wc.cbClsExtra		= 0;
    	_wc.cbWndExtra		= 0;
    	_wc.hbrBackground	= (HBRUSH) (GetStockObject(WHITE_BRUSH));
    	_wc.hCursor			= LoadCursor(0, IDC_ARROW);
    	_wc.hIcon			= LoadIcon(0, IDI_APPLICATION);
    	_wc.lpszMenuName	= 0;
    	_wc.hInstance		= inst;
    	_wc.lpszClassName	= progName;
    

    _wc ist aber schon noch vom Typ WNDCLASS? Dann solltest du auch sizeof WNDCLASS schreiben. Oder noch besser sizeof _wc. (und lass den Unterstrich bei _wc weg)
    Es heisst übrigens &WndProc. Dass dein Compiler das ohne Adress Operator akzeptiert, ist eine dumme MS Angewohnheit.

    DGATmaster schrieb:

    try
    	{
    		if (!RegisterClassEx (&_wc))
    		{
    			throw 0;
    			MessageBox(NULL, "Fehler: RegisterClass()", "Fehlermeldung", MB_ICONERROR);
    			return 0;
    		}
    	}
    

    Was du hier machst, ist eigentlich Bödsinn. Alles was nach throw kommt, wird nie ausgeführt.



  • ok das was nach throw kommt is bei mir im editor schon auskommentiert...
    und _wc is vom Type WNDCLASSEX, das habe ich auch noch verändert aber vergessen zu sagen
    den Unterstrich hab ich deswegen da ich das nachher in ein oder zwei Klassen verpacken werde und alle Klasseninternen Variablen mit _ beginne...
    sofern es funktionieren würde...



  • Wenn du WNDCLASSEX nimmst, was ist dann mit _wc.hIconSm?



  • thx an groovemaster...
    das wars dann wohl...
    aber warum hat es vorher mit WNDCLASS nicht funktioniert???
    naja... egal... es funktioniert...



  • DGATmaster schrieb:

    aber warum hat es vorher mit WNDCLASS nicht funktioniert???

    So genau kann man deine Änderungen leider nicht nachvollziehen. Aber bei deinem ersten Post fehlt die Initialisierung von _wc.cbSize und _wc.lpszMenuName.



  • ja, das wars... danke für die hilfe!


Anmelden zum Antworten