WinApi - OOP



  • Ich hatte mir gedacht damit opengl Anwendungen zu machen und für die GUI awesowmium zu benutzen.

    Edit: Wo in den SFML dateien ist denn die WinMain funktion

    Edit 2: Habs gefunden.



  • So ein neuer Versuch:

    main.cpp:

    #include "stdafx.h"
    
    int WINAPI WinMain(HWND Handle, HINSTANCE Instance, HINSTANCE PrevInstance, LPCSTR CmdLine, int CmdShow) 
    {
    
    	Window window(Handle, Instance, "Test");
    
    }
    

    Window.h:

    #pragma once
    #pragma once
    
    #include "stdafx.h"
    
    class Window
    {
    public:
    	Window();
    	Window(HWND Handle, HINSTANCE hInstance, std::string title);
    	~Window();
    private:
    	HWND Handle;
    	HINSTANCE hInstance;
    
    	void RegisterWindowClass();
    	static LRESULT CALLBACK WndProc(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam);
    };
    

    Window.cpp:

    #include "Window.h"
    
    // static members
    const char* className = "MyClass";
    
    Window::Window(HWND Handle, HINSTANCE Instance, std::string title) : Handle(Handle), Instance(Instance)
    {
    
    	RegisterWindowClass();
    
    	Handle = CreateWindow(className, title.c_str(), WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, NULL, NULL, Instance, NULL);
    
    	ShowWindow(Handle, SW_NORMAL);
    	UpdateWindow(Handle);
    
    }
    
    Window::~Window(void)
    {
    }
    
    void Window::RegisterWindowClass() 
    {
    	WNDCLASSEX wcex;
    
    	wcex.cbSize = sizeof(WNDCLASSEX);
    	wcex.style = CS_HREDRAW | CS_VREDRAW;
    	wcex.lpfnWndProc = WndProc;
    	wcex.cbClsExtra = 0;
    	wcex.cbWndExtra = 0;
    	wcex.hInstance = Instance;
    	wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    	wcex.lpszMenuName = NULL;
    	wcex.lpszClassName = className;
    	wcex.hIconSm = NULL;
    
    	RegisterClassEx(&wcex);
    }
    
    LRESULT CALLBACK Window::WndProc(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam)
    {
    
    	if(Message == WM_CREATE) 
    	{
    		long This = reinterpret_cast<long>(reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams);
    		SetWindowLongPtr(Handle, GWLP_USERDATA, This);
    	}
    
    	Window* window = reinterpret_cast<Window*>(GetWindowLongPtr(Handle, GWLP_USERDATA));
    
    	return DefWindowProc(Handle, Message, wParam, lParam);
    
    }
    

    Jetzt bekomm ich aber immer diese fehlermeldung:

    Fehler	1	error C2731: 'WinMain': Überladen der Funktion nicht möglich
    

    PS: ich weiß das da noch einiges fehlt vor allem was message handling angeht aber ich will das jetzt erst mal so ans laufen kriegen 😉



  • Das liegt daran, dass die Parameterliste deiner WinMain Mist ist...



  • Oh stimmt habs grad gesehen o.o sorry.



  • Btw: Ich kann nur sehr empfehlen, die englische Version von Visual Studio zu benutzen, allein schon weil google dir für deutsche Compilerfehler wesentlich weniger ausspucken wird...



  • Ich hab grad vs 2012 getestet und das war auf deutsch. die 2010er version hab ich auf englisch und mal sehen obs die 2012 auch in englisch gibt.

    Kann mir jemand nen Tipp geben wie ich das Message Handling machen könnte ?



  • Woran genau scheitert's?



  • Also da ist einmal der Code in der wndproc, den hab ich aus der sfml Klasse "geklaut". Den versteh ich nicht so ganz. Und dann würde ich das Event handlingalso Tastatur Eingaben und so gerne in einer eigenen Klasse machen.



  • Th69 schrieb:

    Deinen Ansatz gibt es schon und nennt sich MFC.

    btw: Application developers should not write frameworks and toolkits

    Es ist einfach "Write games not game engines" weitergefasst.

    Guck dir mal RAII an. Insbesondere Konstruktoren und Destruktoren. Eine Methode Init() weist so gut wie immer darauf hin, dass man das Prinzip nicht verstanden hat.

    Das ist zu pauschal und demnach falsch. Klingt mehr nach Religion, vielleicht magst du eine Sekte gruenden: Kirche des RAII. Ich habe beispielsweise gerade diese Methode mittels init fuer ein aktuelles Problem gewaehlt. Ist quasi ein einfachres placement new.

    PS: Ja, ich konnte mir das nicht verkneifen.



  • knivil schrieb:

    Guck dir mal RAII an. Insbesondere Konstruktoren und Destruktoren. Eine Methode Init() weist so gut wie immer darauf hin, dass man das Prinzip nicht verstanden hat.

    Das ist zu pauschal und demnach falsch.

    Ist es durch die Relativierung "so gut wie" gerade nicht.

    knivil schrieb:

    Ich habe beispielsweise gerade diese Methode mittels init fuer ein aktuelles Problem gewaehlt.

    Ja, kann vereinzelt vorkommen. Dennoch stimmt cooky451s Aussage, erst recht auf diesen Thread bezogen. Es ist ziemlich offensichtlich, dass RAII für darman96s Problem eine bessere Lösung wäre.

    Oder willst du unbedingt die Diskussion von letztem Mal wiederholen? Es gibt genug schlechte Buchautoren, die kein RAII vermitteln, du musst jetzt nicht noch einen persönlichen Feldzug dagegen antreten 😉



  • knivil schrieb:

    Ich habe beispielsweise gerade diese Methode mittels init fuer ein aktuelles Problem gewaehlt. Ist quasi ein einfachres placement new.

    Interessant, kannst du das näher erleutern?



  • Leute das hatten wir doch alles schon.
    1. Ich hab gar keine init function mehr.
    2. Ich weiß das ich das nich machen MUSS und das es das schon gibt aber ich will es trotzdem machen und zu dem Satz "Write games not game engines" kann ich nur sagen: wenn alle sich daran halten würden hätten wir heute nicht sehr viele engines mit denen man spiele machen könnte 😉

    3. ich hatte nach dem Message/Event Handling gefragt.

    Gruß darman96


  • Mod

    darman96 schrieb:

    2. Ich weiß das ich das nich machen MUSS und das es das schon gibt aber ich will es trotzdem machen und zu dem Satz "Write games not game engines" kann ich nur sagen: wenn alle sich daran halten würden hätten wir heute nicht sehr viele engines mit denen man spiele machen könnte 😉

    Stimmt. Dann hätten wir viele gute Engines, mit denen man Spiele machen könnte. Aber da sich leider nicht alle da dran halten, haben wie viele gute Engines, mit denen man Spiele machen könnte und Millionen von Schrottengines, mit denen man gar nichts machen kann.

    Wenn es doch bloß eine Methode gäbe, Wissen von Generation zu Generation weiter zu geben, damit nicht jeder Neuling immer wieder die gleichen Fehler wiederholt 😞 . Das wurde die Menschheit wirklich weit vorwärts bringen.



  • SeppJ schrieb:

    Wenn es doch bloß eine Methode gäbe, Wissen von Generation zu Generation weiter zu geben, damit nicht jeder Neuling immer wieder die gleichen Fehler wiederholt 😞 . Das wurde die Menschheit wirklich weit vorwärts bringen.

    http://www.ted.com/talks/aubrey_de_grey_says_we_can_avoid_aging.html 😉



  • -.- Nicht dein Ernst oder 😃

    Außerdem wer sagt denn, dass ich eine GameEngine machen möchte.


  • Mod

    darman96 schrieb:

    Außerdem wer sagt denn, dass ich eine GameEngine machen möchte.

    Niemand. Du möchtest eine Genric Abstract Application Framework Manager Class Factory schreiben. Noch viel schlimmer.



  • So bin ich halt 😃

    Können wir jetzt zum Thema zurück?

    Ich würde die Events/Messages gerne in einer eigenen Klasse abfangen, hab aber keine Ahnung wie. Könnte mir jemand ne kleine Beispielklasse geben oder so?



  • cooky451 schrieb:

    knivil schrieb:

    Ich habe beispielsweise gerade diese Methode mittels init fuer ein aktuelles Problem gewaehlt. Ist quasi ein einfachres placement new.

    Interessant, kannst du das näher erleutern?

    Immer dann, wenn du einen Objektpool hast (beispielsweise in einem statischen Array oder ein vom Benutzer beeitgestellter Speicherbereich) und den Speicher nachnutzen moechtest. Ein einfaches init_with versetzt diesen Speicher in ein gueltiges Objekt. Hinzu kommt noch, dass diese Objekte PODs sein sollen. Dafuer gibt es zwei Anwendungszenarien: a) Performance b) embedded, oder beide gleichzeitig.



  • Mir ist schon klar wie placement new funktioniert. Was mich interessiert, ist der Fall in dem eine Klasse eine init() Methode hat mit der das Objekt initialisiert wird.



  • self quote for the win.

    Ist quasi ein einfachres placement new.

    Bitte stelle deine Frage neu. Warum wird init einem placement new vorgezogen? Weils 'nen POD sein soll und er trotzdem etwas aehnliches wie einen Konstruktor haben soll. Wenn dich der Name "init" stoert, wie waere es mit "reset". Beispiel: Zustandsautomaten in einen definiert Zustand/Anfangszustand bringen. shared_ptr oder unique_ptr haben reset. Also ein placement new auf den Speicherbereich wuerde ich nicht machen.


Anmelden zum Antworten