Visual C++ & Code::Blocks



  • Hi Community (ja ich habe heute nur probleme ^^)!
    Habe ein paar fragen zu Visual C++ & Code::Blocks.

    Wieso braucht man bei jedem Projekt bei Visual C++
    die datei: "stdafx.h"?

    Und wieso gibt es wenn ich ein programm programmiere das in
    Code::Blocks funktioniert, bei Visual C++ nur probleme?

    In Code::Blocks kann ich jede Menge programmieren,
    meine ganzen Programme bis jetzt eigentlich.
    Und wenn ich denn ganz gleichen Quellcode in Visual C++
    eingieb kommen die merkwürdigsten fehler beim debuggen.

    Ob mit Visual C++ 2008, 2010 usw.

    Was ist da los?



  • Warum denkst Du, dass man stdafx.h braucht?
    Warum hast Du nur Probleme?
    Welche hast Du denn?
    Was willst Du uns damit sagen?



  • Visual C++ = IDE + Compiler
    Code:Blocks = IDE (wohl aber eher ein Editor) und verwendet einen externen Compiler

    Du kannst nicht Code 1 zu 1 unter jedem Compiler kompilieren, da sich die Einstellungen und Präprozessor-Direktiven unterscheiden können. Das wäre so, wie wenn du versuchen würdest ein Auto mit Automatik wie ein Auto mit Kupplung zu fahren. Du musst dich an die Automatik anpassen und eben nicht immer die Kupplung durchdrücken, da diese ja bei diesem Auto nicht vorhanden ist. Aber, das Ziel bleibt immer das gleiche: Es bringt dich an deinen gewünschten Bestimmungsort. Es sei denn, du fährst zu schnell und beachtest die Verkehrsordnung nicht. Dann nämlich kann es sein, dass dich die grünen Männchen anhalten und bei sich Pusten lassen oder sogar schlimmer dich in eine WG mit langjährigem Aufenthalt einladen. Jedenfalls muss man sich eben immer an seine Umgebung anpassen. Und bei C/C++ heißt Umgebung = der verwendete Compiler.



  • N290 schrieb:

    Wieso braucht man bei jedem Projekt bei Visual C++
    die datei: "stdafx.h"?

    Nur bei denjenigen, bei denen man precompiled headers aktiviert hat. Das ist allerdings die Standard-Einstellung. Gemein, ich weiß.



  • Danke _matze, shadow und Jochen Kalmbach!

    Ja ich kann jetzt ohne stdafx.h kompilieren DANKE!

    Und shadow, ist schon klar. (Danke für die ausführliche erklärung ;D)
    Aber wenn ich zum Beispiel, ein Beispiel aus dem Buch nehme,
    in dem der Autor auch Visual C++ 2008 / 2010 verwendet, kann ich es
    trotzdem nicht kompilieren, ohne Zeiger fehler und sonstigen krams zu bekommen,
    den ich nichtmal verwende. Ab und zu kann ich eine Konsolen Anwendung kompilieren
    ohne Probleme. Und wie gesagt funktionieren alle anderen Programm ja bei
    gewissen anderen IDEs auch 🙂



  • N290 schrieb:

    Aber wenn ich zum Beispiel, ein Beispiel aus dem Buch nehme,
    in dem der Autor auch Visual C++ 2008 / 2010 verwendet, kann ich es
    trotzdem nicht kompilieren, ohne Zeiger fehler und sonstigen krams zu bekommen,
    den ich nichtmal verwende.

    Zeig ruhig mal ein Beispiel (inkl. Fehlermeldungen).



  • Hier:

    #include <windows.h>
    
    // Prototyp der Callback-Funktion
    LRESULT CALLBACK WindowProc (HWND hWnd, UINT message,
    							 WPARAM wParam, LPARAM lParam);
    
    // Hauptprogramm
    //
    int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,
    					LPSTR lpcmdline, int ncmdshow)
    {
    	WNDCLASSEX windowclass; // Struktur für Fenstereigenschaften
    	HWND       hWnd;        // Fenster-Handle
    	MSG        message;     // Nachricht
    
    	// Der Klassen-Name des Fensters ist frei wählbar
    	const char szClassName[] = "Erstes Fenster";
    
    	// Struktur mit gewünschten Eigenschaften füllen
    	//
    
    	// Größe der Struktur zwischenspeichern
    	windowclass.cbSize = sizeof (WNDCLASSEX);
    
    	// Fenster soll beim Verschieben neu gezeichnet werden
    	windowclass.style = CS_HREDRAW | CS_VREDRAW;
    
    	// Zeiger auf Callback-Funktion
    	windowclass.lpfnWndProc = WindowProc;
    
    	// Keine erweiterten Einstellungen
    	windowclass.cbClsExtra = 0;
    	windowclass.cbWndExtra = 0;
    
    	// Instanz speichern
    	windowclass.hInstance = hInst;
    
    	// Icons und Cursor festlegen
    	windowclass.hIcon   = LoadIcon (NULL, IDI_APPLICATION);
    	windowclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    	windowclass.hCursor = LoadCursor (NULL, IDC_ARROW);
    
    	// Hintergrundfarbe festlegen
    	windowclass.hbrBackground = (HBRUSH)COLOR_BACKGROUND+1;
    
    	// Ein Menü brauchen wir nicht
    	windowclass.lpszMenuName = NULL;
    
    	// Klassenname angeben
    	windowclass.lpszClassName = szClassName;
    
    	// Fensterklasse registrieren
    	if (!RegisterClassEx (&windowclass) )
    		return (0);
    
    	// Das Fenster erzeugen
    	hWnd = CreateWindowEx (NULL,
    						   szClassName,
    						   "Das erste Fenster!",
    						   WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    						   100, 100,
    						   300, 250,
    						   NULL,
    						   NULL,
    						   hInst,
    						   NULL);
    
    	// Prüfen, ob alles glatt ging
    	if (hWnd == NULL)
    		return (0);
    
    	// Der "Herzschlag" des Programms.
    	// Hier werden alle Nachrichten abgeholt,
    	// übersetzt und weitergeleitet.
    	while (GetMessage (&message, NULL, 0, 0) )
    	{
    		TranslateMessage (&message);
    		DispatchMessage (&message);
    
    	}
    
    	// Programm beenden
    	return (int)(message.wParam);
    
    } // WinMain
    
    // Callback-Funktion zur Nachrichtenverarbeitung
    //
    LRESULT CALLBACK WindowProc (HWND hWnd, UINT message,
    							 WPARAM wParam, LPARAM lParam)
    {
    	// Messages auswerten
    	switch (message)
    	{
    		// Fenster schließen? (Auch Alt-F4)
    		case WM_DESTROY:
    		{
    			// Nachricht zum Beenden schicken
    			PostQuitMessage (0);
    			return (0);
    
    		}
    
    		// Wurde eine Taste gedrückt?
    		case WM_KEYDOWN:
    		{
    			// Ja, also je nach Taste verzweigen
    			switch (wParam)
    			{
    				// Wurde "Escape" gedrückt?
    				case VK_ESCAPE:
    				{
    					// Ja, also Nachricht zum Beenden schicken
    					PostQuitMessage (0);
    					return (0);
    
    				}
    			}
    		} break;
    	} 
    
    	// Die Nachricht wurde nicht von uns verarbeitet, also
    	// von Windows verarbeiten lassen.
    	return (DefWindowProc (hWnd, message, wParam, lParam) );
    
    } // WindowProc
    

    Das ist jetzt ein Visual C++ beispiel aus nem buch, um sicher zu gehn
    das kein fehler drin is 😉
    (Funktioniert aber auch nicht, und gibt die gleichen fehler)

    1>------ Erstellen gestartet: Projekt: name, Konfiguration: Debug Win32 ------
    1>Kompilieren...
    1>main.cpp
    1>c:\users\computertechnik\desktop\name\name\main.cpp(50) : error C2440: '=': 'const char [15]' kann nicht in 'LPCWSTR' konvertiert werden
    1> Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat.
    1>c:\users\computertechnik\desktop\name\name\main.cpp(66) : error C2664: 'CreateWindowExW': Konvertierung des Parameters 2 von 'const char [15]' in 'LPCWSTR' nicht möglich
    1> Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat.
    1>Das Buildprotokoll wurde unter "file://c:\Users\ComputerTechnik\Desktop\name\name\Debug\BuildLog.htm" gespeichert.
    1>name - 2 Fehler, 0 Warnung(en)
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========

    Ich schwöre auf Code::Blocks und Dev c++ geht das 😉
    Aber in Visual C++ hört sich das eher nach nen schweren fehler an,
    obwohl auch der code 1:1 jetzt vom Buch genommen wurde?



  • Das geht in Visual C++ auch.
    Allerdings verwendet Visual C++ in der Standard Einstellung Unicode für die Windows API.
    Daher wirst du entweder in den Projekteinstellungen das Characterset von Unicode auf Multibyte setzen müssen oder du verwendest eben auch Unicode.

    Dann müsstest du statt char jeweils wchar_t verwenden und deine Literale müssten mit einem L beginnen.
    Kleines Beispiel:

    const wchar_t szClassName[] = L"Erstes Fenster";
    

    Als Alternative kannst du auch den Typ TCHAR sowie das Makro TEXT verwenden:

    const TCHAR szClassName[] = TEXT("Erstes Fenster");
    

    Damit ist dann die Einstellung egal, TCHAR wird jeweils entsprechend zu char oder wchar_t.
    Das Text Makro fügt eben bei Unicode automatisch das L an.

    PS: LPCWSTR ist ein const wchar_t *. Du übergibst aber char *. 😉



  • DANKE!
    Werd ich gleich mal versuchen!
    🙂

    EDIT: Kleines Problem ich finde die UNICODE einstellung nicht,
    das ich sie ändern könnte 😉
    hab visual c++ 2008

    EDIT: Geschafft!
    Funktioniert jetzt!
    Danke 🙂



  • Im Menü:
    Projekt -> ...-Eigenschaften

    Dann im Dialog:
    Kofigurationseigenschaften -> Allgemein

    Auf der Seite hast du dann die Einstellung "Zeichensatz".
    Da müsste bei dir "Unicode-Zeichensatz verwenden" drin stehen.



  • Schon gelöst danke 🙂
    Werden diese einstellungen jetzt für alle Win32 Projekte
    verwendet?
    Oder kann ich auch irgendwo ein Template machen oder so? ^^
    Damit man nicht jedes mal alles neu einstellen muss 😉



  • Die Einstellung gilt nur für das eine Projekt und auch nur für die eine aktive Konfiguration (Standardmäßg Debug)

    Du kannst im Einstellungsdialog oben in einer Combobox festlegen, dass die Einstellung für "Alle Konfigurationen" gelten soll. Das gilt dann allerdings trotzdem nur für das aktuelle Projekt.

    Wie man das für alle Projekte festlegen kann ist mir nicht bewusst,
    aber es ist möglich, ein eigenes Template zu erstellen (siehe Visual Studio - SDK),
    welches eben MultiByte als Standard verwendet.

    Theoretisch müsste es auch möglich sein, die vorhandenen Templates so anzupassen,
    allerdings wirst du dafür in den Textdateien im VC++ Ordner manuell rumbasteln müssen.



  • Ein template würde mir genügen 😉

    EDIT: Maaaann in Code Blocks gibs ne Funktion "Als Template verwenden"
    Und in VC++ kann man schon wieder ewig suchen ^^



  • shadow schrieb:

    Das wäre so, wie wenn du versuchen würdest ein Auto mit Automatik wie ein Auto mit Kupplung zu fahren.

    In einem Auto mit Automatikgetriebe gibt es die Kupplung auch ⚠


Anmelden zum Antworten