Ich brauch hilfe und weis nicht weiter :/



  • Hey ich habe mich nach länger zeit mal wieder mit winapi versucht jetzt habe ich bei der CreateWindow Funktion i-wie immer einen fehler des halb hier mal der quelltext die stelle wo bei mir laut visual studio 2010 express angekreuzt wird versuche ich hier auch mal i-wie zu makieren ich hoffe ihr könnt mir helfen

    MFG Dagnih 🙂

    [cpp]#include <Windows.h>

    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

    const LPCWSTR szAppName = L"Fenster";

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    HWND hWnd; // Handel
    MSG msg; // wnd nachrichten abholen und bearbeiten
    WNDCLASS wndcl; // typ der fensterklasse

    wndcl.style = CS_HREDRAW | CS_VREDRAW; //Horizontal Vertikal Zeichnen
    wndcl.lpfnWndProc = WndProc; //Zeiger auf Adresse der Fkt die Nachrichtenbearbeitung übernimmt
    wndcl.cbClsExtra = 0 ;
    wndcl.cbWndExtra = 0;
    wndcl.hInstance = hInstance; // Übergabe des Handels auf unsere Programminstanz das nur unser Programm diese Fensterklasse Nutzen kann
    wndcl.hCursor = LoadCursor(NULL,IDC_ARROW);// CursorTyp -> Cursor Laden
    wndcl.hIcon = LoadIcon(NULL,IDI_APPLICATION);// Icon -> Icon Laden
    wndcl.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // Hintergrund -> (HBRUSH)ist ein Typecast der in c++ den Rückgabewerttyp ändern muss
    wndcl.lpszClassName = szAppName; // Fensterklassenname
    wndcl.lpszMenuName = NULL; // MenÜ -> keins

    RegisterClass(&wndcl); //registriert bzw. meldet unsere Fensterklasse beim Fenstermanager von Windows an

    hWnd = CreateWindow(szAppName, //Name der Fensterklasse
    "abc", //Text in Titelleiste
    WS_OVERLAPPEDWINDOW, //Stil des Fensters
    CW_USEDEFAULT, //X-Position auf dem Monitor
    CW_USEDEFAULT, //Y-Position auf dem Monitor
    CW_USEDEFAULT, //Fensterbreite
    CW_USEDEFAULT, //Fensterhöhe
    NULL,
    NULL,
    hInstance, //damit man das Fenster unserem Programm zuordnen kann
    NULL);

    ShowWindow(hWnd, iCmdShow); //zeigt Fenster -> 2ter prameter legt fest wie das fenster angezeigt werden soll geht z.B. auch (SW_SHOW)
    UpdateWindow(hWnd); //lässt den Anwendungsbereich, also den freien Fensterbereich, sofort nach dem Start neu zeichnen.

    return 0;
    }[/cpp]



  • achja fals ihr das net lesen könnt sagt mir bitte was nochmal des richtige war um des in so nem scrofenster anzuzeigen 😃



  • Und wie lautet denn die Fehlermeldung? Für mich sieht es atm so aus, also ob du UNICODE- und ANSI-Strings bunt durcheinandergeworfen hast (die beiden String-Parameter für Klassen-Name und Fenstername sollten schon vom selben Typ und passend zu deinen UNICODE-Einstellungen sein).

    Edit: und afair verträgt sich das Syntax-Highlighting nicht besonders gut mit Textformatierungen - da ist ein großer "hier ist der Fehler"-Kommentar besser geeignet (oder du schreibst unten drunter in welcher Zeile des Code-Ausschnitts der Fehler aufgetreten ist).



  • also ich dacht mir schon des daran in der richtung i-wie liegt

    da steht folgendes :

    Das Argument vom Typ ""const char *"" ist mit dem Parameter vom Typ ""LPCWSTR"" inkopmatibel.

    aber ich arbeite momentan mit der Winapi Tutorial seite
    http://www.win-api.de/tutorials.php?tutid=3
    und bei dem funktioniert das so blos 1 unterschied er delklariert am anfang gleich nen konstanten char aber als ich das versucht hab ging des bei mir mit dem

    wndcl.lpszClassName = szAppName;

    net 😕 omg ich blicks net so ganz xD 😮



  • oke sry aber das mit der textformatierung kapier ich garnicht mehr sry *__*



  • Was ist denn die genaue Fehlermeldung?

    #include <Windows.h>
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    const LPCWSTR szAppName = L"Fenster";
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    HWND hWnd; // Handel
    MSG msg; // wnd nachrichten abholen und bearbeiten
    WNDCLASS wndcl; // typ der fensterklasse
    
    wndcl.style = CS_HREDRAW | CS_VREDRAW; //Horizontal Vertikal Zeichnen
    wndcl.lpfnWndProc = WndProc; //Zeiger auf Adresse der Fkt die Nachrichtenbearbeitung übernimmt
    wndcl.cbClsExtra = 0 ;
    wndcl.cbWndExtra = 0;
    wndcl.hInstance = hInstance; // Übergabe des Handels auf unsere Programminstanz das nur unser Programm diese Fensterklasse Nutzen kann
    wndcl.hCursor = LoadCursor(NULL,IDC_ARROW);// CursorTyp -> Cursor Laden
    wndcl.hIcon = LoadIcon(NULL,IDI_APPLICATION);// Icon -> Icon Laden
    wndcl.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // Hintergrund -> (HBRUSH)ist ein Typecast der in c++ den Rückgabewerttyp ändern muss
    wndcl.lpszClassName = szAppName; // Fensterklassenname
    wndcl.lpszMenuName = NULL; // MenÜ -> keins
    
    RegisterClass(&wndcl); //registriert bzw. meldet unsere Fensterklasse beim Fenstermanager von Windows an
    
    hWnd = CreateWindow(szAppName, //Name der Fensterklasse
    "abc", //Text in Titelleiste
    WS_OVERLAPPEDWINDOW, //Stil des Fensters
    CW_USEDEFAULT, //X-Position auf dem Monitor
    CW_USEDEFAULT, //Y-Position auf dem Monitor
    CW_USEDEFAULT, //Fensterbreite
    CW_USEDEFAULT, //Fensterhöhe
    NULL,
    NULL,
    hInstance, //damit man das Fenster unserem Programm zuordnen kann
    NULL);
    
    ShowWindow(hWnd, iCmdShow); //zeigt Fenster -> 2ter prameter legt fest wie das fenster angezeigt werden soll geht z.B. auch (SW_SHOW)
    UpdateWindow(hWnd); //lässt den Anwendungsbereich, also den freien Fensterbereich, sofort nach dem Start neu zeichnen.
    
    return 0;
    }
    

    Der einzige Fehler den ich grade sehe, ist in CreateWindow, hier sollte es L"abc" heissen. Da ja normalerweise Unicode default ist.
    Das MSG-Struct solltest du afaik erst in der Event-Loop erzeugen und jede Loop ein neues. Das braucht man nicht aufheben.

    Hier mal eine Variante die funktioniert, 1:1 abschreiben wird aber nicht gehen, da dir Variablen von mir fehlen, aber eventuell hilfts dir weiter:
    http://code.google.com/p/nightlight2d/source/browse/NightLightDLL/NLWindowWin32.cpp#56

    Die Message-Pumpe findest du hier:
    http://code.google.com/p/nightlight2d/source/browse/NightLightDLL/NLWindowWin32.cpp#210



  • Hey so also mein fehler is in zeile 27 dort wird bei mir in visual c++ 2010 der Funktionenname rot unterstrichen und der oben schonbeschreibene fehler ausgegeben



  • Dagnih schrieb:

    Hey so also mein fehler is in zeile 27 dort wird bei mir in visual c++ 2010 der Funktionenname rot unterstrichen und der oben schonbeschreibene fehler ausgegeben

    Hab die Antwort übersehen. Aber das ist dann genau das was ich aufgeführt habe.



  • sry nochmal wenn ich frage aber wie du hast mir ja mehrere sachen vorgelegt was meinst du is jetzt falsch



  • Der einzige Fehler den ich grade sehe, ist in CreateWindow, hier sollte es L"abc" heissen. Da ja normalerweise Unicode default ist.



  • okey dan gibts nur noch einproblem ich hab das schon abgeändert aber es geht immer noch nicht 😕

    ich glauch ich meld mich morgen nochmal hier an und schreib dir dan ne pn vll können wir ja dan übe skype oder so kummunizieren dan kann ich es vieleicht besser erklären 🙂

    Aber im mom is schon etwas spät ich leg mich dan schlafen ^^



  • Naja, dir fehlt die Message-pumpe und wahrscheinlich auch die WindowProc.
    Du solltest das Tutorial vielleicht lesen statt nur zu kopieren :D.



  • So da bin ich nochmal ich hab mir jetzt nen benutzer angelegt

    bei mir hat es jetzt zwischendurch jetzt auch mal das fenster angezeigt und das Problem mit der CreateWindow Funktion ist behoben aber jetzt wird bei mir kein Error Mehr angezeigt und doch will mein pc das fenster nicht öffenen
    es kommt einfach immer der lademauszeiger und unten in meiner taskleiste wird auch das Programm angezeigt aber ich sehe es nicht

    Hier nochmal der Quelltext

    #include <Windows.h>
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    const LPCWSTR szAppName = L"Fenster";
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    	HWND		hWnd;							// Handel
    	MSG			msg;							// wnd nachrichten abholen und bearbeiten
    	WNDCLASS	wndcl;							// typ der fensterklasse
    
    	wndcl.style			= CS_HREDRAW | CS_VREDRAW; //Horizontal Vertikal Zeichnen 
    	wndcl.lpfnWndProc	= WndProc;				   //Zeiger auf Adresse der Fkt die Nachrichtenbearbeitung übernimmt
    	wndcl.cbClsExtra	= 0 ;
    	wndcl.cbWndExtra	= 0;
    	wndcl.hInstance		= hInstance;			// Übergabe des Handels auf unsere Programminstanz das nur unser Programm diese Fensterklasse Nutzen kann
    	wndcl.hCursor		= LoadCursor(NULL,IDC_ARROW);// CursorTyp -> Cursor Laden 
    	wndcl.hIcon			= LoadIcon(NULL,IDI_APPLICATION);// Icon -> Icon Laden
    	wndcl.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // Hintergrund -> (HBRUSH)ist ein Typecast der in c++ den Rückgabewerttyp ändern muss
    	wndcl.lpszClassName = szAppName;			// Fensterklassenname
    	wndcl.lpszMenuName  = NULL;					// MenÜ -> keins
    
    	RegisterClass(&wndcl);	//registriert bzw. meldet unsere Fensterklasse beim Fenstermanager von Windows an
    
    	hWnd = CreateWindow(szAppName,			   //Name der Fensterklasse
    						L"abc",				   //Text in Titelleiste
    						WS_OVERLAPPEDWINDOW,   //Stil des Fensters
    						CW_USEDEFAULT,		   //X-Position auf dem Monitor 
    						CW_USEDEFAULT,		   //Y-Position auf dem Monitor 
    						CW_USEDEFAULT,		   //Fensterbreite
    						CW_USEDEFAULT,		   //Fensterhöhe
    						NULL,
    						NULL,
    						hInstance,			   //damit man das Fenster unserem Programm zuordnen kann
    						NULL);
    
    	ShowWindow(hWnd, iCmdShow);			//zeigt Fenster -> 2ter prameter legt fest wie das fenster angezeigt werden soll geht z.B. auch (SW_SHOW)
    	UpdateWindow(hWnd);					//lässt den Anwendungsbereich, also den freien Fensterbereich, sofort nach dem Start neu zeichnen.
    
    										// Schleife -> Warten auf aktivität des benutzers wenn etwas passiert informiert und windows über eine nachricht
    	while(GetMessage(&msg,NULL,0,0))   //GetMessage -> Solange Rückgabewert != NULL -> NULL = Wenn Programm durch den Aufruf von PostQuitMessage beendet werden soll   wenn keine nachricht vorhanden wartet unsere schleife einfach
    	{									//GetMessage -> 1. Parameter Hier wird die nachricht gespeichert 
    										//				2. Parameter ??? Im zweiten Parameter können wir uns auf das Abholen von Nachrichten für nur ein Fenster beschränken. Wenn wir dies wollten, müssten wir hier den Handle des Fensters eintragen. Jedoch würde dann unser Programm nicht korrekt beenden, da zum Beispiel die Nachricht, die PostQuitMessage sendet nicht für unser Fenster bestimmt ist, da dies ja schon zerstört wurde.
    										//				3.u 4. Parameter welche art der nachrichten abgeholt wird Alle nachriten zwischen parameter 3 und 4 auser bei 0 0 da werden alle abgeholt
    	TranslateMessage(&msg);				//	Verarbeitung von Tasterturnachrichten
    	DispatchMessage(&msg);				//	verteilt die Nachrichten an die jeweilige Windows Prozdeur auch WndProc
    	}
    
    	return msg.wParam;  // wParam = die letzte nachricht die GetMessage bearbeitet hat
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam) //bearbeitet alle Nachrichtenfür unsere Fensterklasse
    {
    	switch (message)	// Welche Nachricht hat uns Windows oder ein anderes Fenster geschickt 
    	{
    	case WM_DESTROY:    //Wenn die Nachricht vom Typ WM_DESTROY is 
    		{						// Parameter von PostQuitMessage wird später als Rückgabewert der WinMain Funktion benutzt
    			PostQuitMessage(0);	// senden wir mithilfen von PostQuitMessage die Nachricht WM_QUIT -> GetMessage Funktion Beendet das Programm
    			return 0;	//Wenn wir eine nachricht bearbeitet haben beenden wir die WndProc Fkt mit dem wert 0
    		}
    
    		return DefWindowProc(hWnd, message, wParam, lParam); // alle Nachrichten werden mit einer standard Bearbeitung behandelt übergabe der WndProc Fkt in die DefWindowProc
    	}
    }
    

    Ich hoffe ihr könnt mir helfen Mfg Dagnih bzw phileman 🙄



  • Teste mal anhand der Rückgabewerte ob entweder RegisterClass() oder CreateWindow() fehlschlagen.



  • wndcl.cbSize wird nicht initialisiert, daher schlägt RegisterClass() fehl.

    Füge mal folgendes vor RegisterClass(&wndcl) hinzu:

    wndcl.cbSize = sizeof(WNDCLASS);
    


  • immer schön größe angeben schrieb:

    wndcl.cbSize wird nicht initialisiert, daher schlägt RegisterClass() fehl.

    Füge mal folgendes vor RegisterClass(&wndcl) hinzu:

    wndcl.cbSize = sizeof(WNDCLASS);
    

    WNDCLASS hat kein cbSize, das hat nur WNDCLASSEX.

    http://msdn.microsoft.com/en-us/library/ms633576(v=vs.85).aspx
    http://msdn.microsoft.com/en-us/library/ms633577(v=VS.85).aspx



  • Verdammt, das kommt davon, wenn man immer die ...Ex()-Funktion benutzt 😃

    Dachte bisher immer, dass der einzige Unterschied das hIconSm wäre 🙄
    Wieder was dazugelernt.

    !RegisterClass(&wndcl) evaluiert zu true, GetLastError gibt aber 0 zurück...komisch



  • Da ich ja wie gesagt n anfänger bin hab ichs mal so versucht

    #include <Windows.h>
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    const LPCWSTR szAppName = L"Fenster";
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    	HWND		hWnd;							// Handel
    	MSG			msg;							// wnd nachrichten abholen und bearbeiten
    	WNDCLASS	wndcl;							// typ der fensterklasse
    
    	wndcl.style			= CS_HREDRAW | CS_VREDRAW; //Horizontal Vertikal Zeichnen 
    	wndcl.lpfnWndProc	= WndProc;				   //Zeiger auf Adresse der Fkt die Nachrichtenbearbeitung übernimmt
    	wndcl.cbClsExtra	= 0 ;
    	wndcl.cbWndExtra	= 0;
    	wndcl.hInstance		= hInstance;			// Übergabe des Handels auf unsere Programminstanz das nur unser Programm diese Fensterklasse Nutzen kann
    	wndcl.hCursor		= LoadCursor(NULL,IDC_ARROW);// CursorTyp -> Cursor Laden 
    	wndcl.hIcon			= LoadIcon(NULL,IDI_APPLICATION);// Icon -> Icon Laden
    	wndcl.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // Hintergrund -> (HBRUSH)ist ein Typecast der in c++ den Rückgabewerttyp ändern muss
    	wndcl.lpszClassName = szAppName;			// Fensterklassenname
    	wndcl.lpszMenuName  = NULL;					// MenÜ -> keins
    
    	ATOM test;
    	RegisterClass(&wndcl);	//registriert bzw. meldet unsere Fensterklasse beim Fenstermanager von Windows an
    	test = RegisterClass(&wndcl);
    
    	if(test == 0)
    	{
    				MessageBox(NULL, L"Fail Registerclass",
                           L"Fail",
                           MB_ICONINFORMATION | MB_OK | MB_DEFBUTTON1);
    	}
    
    	hWnd = CreateWindow(szAppName,			   //Name der Fensterklasse
    						L"abc",				   //Text in Titelleiste
    						WS_OVERLAPPEDWINDOW,   //Stil des Fensters
    						CW_USEDEFAULT,		   //X-Position auf dem Monitor 
    						CW_USEDEFAULT,		   //Y-Position auf dem Monitor 
    						CW_USEDEFAULT,		   //Fensterbreite
    						CW_USEDEFAULT,		   //Fensterhöhe
    						NULL,
    						NULL,
    						hInstance,			   //damit man das Fenster unserem Programm zuordnen kann
    						NULL);
    
    	if(NULL == hWnd)
    	{
    		MessageBox(NULL, L"Fail CreateWindow",
                           L"Fail",
                           MB_ICONINFORMATION | MB_OK | MB_DEFBUTTON1);
    	}
    
    	ShowWindow(hWnd, iCmdShow);			//zeigt Fenster -> 2ter prameter legt fest wie das fenster angezeigt werden soll geht z.B. auch (SW_SHOW)
    	UpdateWindow(hWnd);					//lässt den Anwendungsbereich, also den freien Fensterbereich, sofort nach dem Start neu zeichnen.
    
    										// Schleife -> Warten auf aktivität des benutzers wenn etwas passiert informiert und windows über eine nachricht
    	while(GetMessage(&msg,NULL,0,0))   //GetMessage -> Solange Rückgabewert != NULL -> NULL = Wenn Programm durch den Aufruf von PostQuitMessage beendet werden soll   wenn keine nachricht vorhanden wartet unsere schleife einfach
    	{									//GetMessage -> 1. Parameter Hier wird die nachricht gespeichert 
    										//				2. Parameter ??? Im zweiten Parameter können wir uns auf das Abholen von Nachrichten für nur ein Fenster beschränken. Wenn wir dies wollten, müssten wir hier den Handle des Fensters eintragen. Jedoch würde dann unser Programm nicht korrekt beenden, da zum Beispiel die Nachricht, die PostQuitMessage sendet nicht für unser Fenster bestimmt ist, da dies ja schon zerstört wurde.
    										//				3.u 4. Parameter welche art der nachrichten abgeholt wird Alle nachriten zwischen parameter 3 und 4 auser bei 0 0 da werden alle abgeholt
    	TranslateMessage(&msg);				//	Verarbeitung von Tasterturnachrichten
    	DispatchMessage(&msg);				//	verteilt die Nachrichten an die jeweilige Windows Prozdeur auch WndProc
    	}
    
    	return msg.wParam;  // wParam = die letzte nachricht die GetMessage bearbeitet hat
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam) //bearbeitet alle Nachrichtenfür unsere Fensterklasse
    {
    	switch (message)	// Welche Nachricht hat uns Windows oder ein anderes Fenster geschickt 
    	{
    	case WM_DESTROY:    //Wenn die Nachricht vom Typ WM_DESTROY is 
    		{						// Parameter von PostQuitMessage wird später als Rückgabewert der WinMain Funktion benutzt
    			PostQuitMessage(0);	// senden wir mithilfen von PostQuitMessage die Nachricht WM_QUIT -> GetMessage Funktion Beendet das Programm
    			return 0;	//Wenn wir eine nachricht bearbeitet haben beenden wir die WndProc Fkt mit dem wert 0
    		}
    
    		return DefWindowProc(hWnd, message, wParam, lParam); // alle Nachrichten werden mit einer standard Bearbeitung behandelt übergabe der WndProc Fkt in die DefWindowProc
    	}
    }
    

    Und die RegisterClass gibt den wert null zurück der laut mdsn dort ein fehler ist

    If the function fails, the return value is zero.

    Aber was ich jetzt machen soll weis ich leider immer noch nicht 😕



  • Genau, ruf am besten einfach zwei mal hintereinander RegisterClass auf, das hilft bestimmt!



  • So hab jetzt nochmal die oben drüber weggelassen jetzt wird die RegisterClass Funktion nur noch 1 mal auf gerufen aber jetzt gibts auch keinen fehler mehr

    Funktioniert aber immer noch net *_*


Anmelden zum Antworten