Window in Klassen Kapseln



  • Hallo

    Ich packe grad die WinAPI Funktionen für ein Grundfenster in eine Klasse, und wollt Fragen, ob etwas dagegen spricht, und ob es schonmal jemand gemacht hat.
    Denn ich hab Probleme die WndProc einzubinden.

    Ich hab die WinMain so gestaltet (bei Borland abgeguggt 🕶 )
    main.cpp:

    #include "globals.h"
    
    // Entrypoint
    int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, 
    				    LPSTR lpszCmdLine, int CmdShow )
    {
             WPARAM exitcode = 0;
             WinApp application( hInstance );
    	try
    	{
    		// Initialize
    		application.init();
    		// Run
    		exitcode = application.run();
    	}
    	catch (...)
    	{
    		// TODO: exitcode = ( Exception ID )
                      // Show Message( Exception Text )
    
    	}
             // Finalize
    	application.clear();
    	return exitcode;
    }
    

    die Globalen defines und includes..
    globals.h

    #pragma once
    
    #define STRICT
    #define WIN32_LEAN_AND_MEAN
    
    #include <windows.h>
    #include <tchar.h>
    

    und meine Fensterklasse
    winapp.h

    #include "globals.h"
    
    class WinApp
    {
    public:
    	 WinApp( HINSTANCE hInst );
    	~WinApp();
        LRESULT CALLBACK  WndProc( HWND hWnd_, UINT msg_, WPARAM wParam_, LPARAM lParam_ );
    	void		init();
    	WPARAM		run();
    	void		clear();
    	HINSTANCE    	hinstance;
    	HWND		hwnd;
    	MSG		msg;
    	WNDCLASSEX	window;
    	LPCTSTR		classname;
    };
    

    winapp.cpp

    WinApp::WinApp( HINSTANCE hInst )
    {
    	hinstance = hInst;
    	hwnd = 0;
    	ZeroMemory( &msg, sizeof(msg) );
    	ZeroMemory( &window, sizeof(window) );
    	classname = _T("classname does not matter");
    }
    
    WinApp::~WinApp(void)
    {
    	clear();
    }
    
    LRESULT CALLBACK WinApp::WndProc( HWND hWnd_, UINT msg_, WPARAM wParam_, LPARAM lParam_ )
    {
        switch( msg_ ) {
             case WM_DESTROY: {
    		PostQuitMessage( 0 );
    		return 0;
    		}
    	default:
    		return DefWindowProc( hWnd_, msg_, wParam_, lParam_ );
    	}
    }
    
    void WinApp::init()
    {
    	window.cbSize		= sizeof( WNDCLASSEX );
    	window.style		= CS_CLASSDC;
    	window.lpfnWndProc	= WndProc;  // <---HIER!!!
    //	window.cbClsExtra	= 0;
    //	window.cbWndExtra	= 0;
    	window.hInstance	= hinstance;
    //	window.hIcon		= 0;
    //	window.hCursor		= 0;
    	window.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
    //	window.lpszMenuName	= 0;
    	window.lpszClassName= classname;
    //	window.hIconSm		= 0;
    	if( !RegisterClassEx( &window ) )
    		// TODO Throw
    		return;
    	hwnd = CreateWindowEx( 0, classname, _T(""), 
    							WS_POPUPWINDOW | WS_VISIBLE,
    							10, 10, 400, 400,
    							GetDesktopWindow(), 0, hinstance, 0 );
    	if( !hwnd )
    		// TODO Throw
    		return;
    	ShowWindow( hwnd, SW_SHOWDEFAULT );
    	UpdateWindow( hwnd );
    	return;
    }
    
    WPARAM WinApp::run()
    {
    	while( msg.message != WM_QUIT ) {
    		if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) {
    			TranslateMessage( &msg );
    			DispatchMessage( &msg );
    		}
    		else {
    			// TODO Application Goes Here
    		}
    	}
    	return msg.wParam;
    }
    
    void WinApp::clear()
    {
    	if( GetClassInfoEx( hinstance, classname, &window ) )
    		UnregisterClass( classname, hinstance );
    }
    

    Das ergibt folgende Fehler:

    ...error C3867: 'WinApp::WndProc': function call missing argument list; use '&WinApp::WndProc' to create a pointer to member
    ...error C2440: '=' : cannot convert from 'LRESULT (__stdcall WinApp::* )(HWND,UINT,WPARAM,LPARAM)' to 'WNDPROC'
    There is no context in which this conversion is possible

    Hab nun allso ein & vor WndProc gesetzt, dann kam dies:

    ...error C2276: '&' : illegal operation on bound member function expression

    Kann die WndProc demzufolge keine Memberfunktion sein?
    Ich probiers nun schon den zweiten Abend in Folge, 😞 und wär um jede Hilfe froh

    Danke im voraus..



  • this pointer -> etc etc

    wenn du näheres wissen willst winapi faq lesen

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-148410.html



  • danke für die links, die forensuche ergab irgendwie nichts.

    also wenn ichs static mach gehts.
    und da es das hauptfenster ist, brauch ich nur eins.
    sollt ich dann ein singleton draus machen?



  • Hmm ich find Vertexwahns umsetzung nicht sooo schlecht. d.h. : http://turing.fh-landshut.de/~jamann/IMB/IMB.html



  • hmm auf der Seite find ich nichts, was hier helfen könnte 😞



  • (D)Evil schrieb:

    Hmm ich find Vertexwahns umsetzung nicht sooo schlecht. d.h. : http://turing.fh-landshut.de/~jamann/IMB/IMB.html

    ist für seine zwecke vollkommen überzogen und bei dem ganzen overhead da krieg ich kopfschmerzen da wird für eine winow message das ganze durch 10 funktionen durchgereicht die ganzen jmps machen das auch ned gerade schneller...



  • Lol... du sollst dir einfach nur mal angucken wie Vertex es gemacht hat... also die kapselung... mehr nciht... daran kannst du dein konzept evt. anpassen.. manman man



  • this pointer -> etc etc

    wenn du näheres wissen willst winapi faq lesen

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-148410.html

    this pointer -> etc etc

    wenn du näheres wissen willst winapi faq lesen

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-148410.html

    this pointer -> etc etc

    wenn du näheres wissen willst winapi faq lesen

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-148410.html



  • Warum verwendest Du nicht MFC oder sonstige "Frameworks". Die haben genau das gemacht was Du auch machen willst...



  • Weil ich ein armer Student und Hobbyprogrammierer bin und nur die Express Editition habe.
    Ausserdem brauch ich den ganzen Overhead nicht, sondern einfach eine simple Anwendung mit weissem Fenster ohne Titelleiste, Menu, Buttons, etc pp



  • Windows-User schrieb:

    Windows-User schrieb:

    danke für die links, die forensuche ergab irgendwie nichts.

    also wenn ichs static mach gehts. //<--- OK! Erledigt!
    und da es das hauptfenster ist, brauch ich nur eins.
    sollt ich dann ein singleton draus machen? ??? ??? ???

    @fae: fast so hilfsbereit wie tggc 👎

    hm komm ja vergleich mich nicht mit irgendeinem dummen forum troll...meine antwort war doch hilfreich...bot 1 gute lösunghsmöglichkeit zum direkten copy & paste an und einen link z ueiner 4 seitigen diskussion mit mehreren anderen lösungsmöglichkeiten an....aber wenn dir noch was unklar ist kannst du ja gerne fragen 🙂



  • Ok sorry, war unfair dich mit dem grössenwahnsinnigen spiele progger zu vergleichen

    Also, wenn ich nur ein Grundfenster hab..brauch ich dann die Methode mit den this Zeigern?
    Oder kann ich ein Singleton machen?
    Oder wie mach ichs am "besten", nicht im Sinn von elegannt. Es soll ja nicht auf die Performance drücken..
    Sonst mach ich einfach eine lokale Proc ohne Scope, so wie ich das Problem am Anfang umging.



  • ok danke
    ich habs jetzt abgetippt, und sogar geschnallt, mit dem this, pointer GetWindowLongPtr etc.
    Funzt auch!

    Aber ich bin sicher, TGGC hat in seinen brillianten Codes eine elegantere Lösung!



  • Back2Topic: PLEAZZZE HELP MEEE!!!!¨¨¨

    Ok ich hab gedacht es geht, aber falsch gedacht.
    folgendes geht ned:

    LRESULT CALLBACK mainwin::WndProc( HWND hWnd_, UINT msg_, 
    								  WPARAM wParam_, LPARAM lParam_ )
    {
    	mainwin* this_ = (mainwin*) GetWindowLongPtr( hWnd_, GWL_USERDATA );
    	switch( msg_ ) {
    		case WM_CREATE: {
    			this_ = (mainwin*) ( (LPCREATESTRUCT)lParam_)->lpCreateParams;
    			SetWindowLongPtr( hWnd_, GWL_USERDATA, (LONG)this_ );
    			break;
    		}
    		case WM_PAINT: {
    			PAINTSTRUCT	ps;
    			HDC			hDC;
                               LPCWSTR text = "blabla";
    			if( hDC = BeginPaint( this_->hwnd, &ps ) ) {   ///<---Hier
    				//TextOut( hDC, 0, 0, text, sizeof(text) );	
    				EndPaint( this_->hwnd, &ps );
    			}
    

    es kompiliert zwar einwandfrei, aber steigt aus mit

    Unhandled exception at 0x00411914 in WinApp.exe: 0xC0000005: Access violation reading location 0x0000003c.

    und zwar beim ersten EInsatz von this_
    [emotionen]Je m'enerve! Püree!![/emotionen]
    Vorhin gings, was mach ich falsch???
    *zwerveifel*



  • Windows-User schrieb:

    Weil ich ein armer Student und Hobbyprogrammierer bin und nur die Express Editition habe.

    Das ist ja kein Grund...
    1. Mit der Express-Version kann man WTL und sonstige Frameworks verwenden (wxWidgeds)
    2. Als Student bekommst Du von Deiner Uni/FH ein vollständiges VS Academic kostenlos gestellt (musst nur fragen)



  • Hast Du es mal durchdebuggt? Kommst Du durch WM_CREATE durch? Was soll den das viele casten?
    Warum willst Du das Rad neu erfinden?



  • Ja, die WM_CREATE wird aufgerufen. Die Variblen sind aber alle unused=??? Auch hWnd_ . 😞 😕

    Hab das casten abgetippt von da: http://www.c-plusplus.net/forum/viewtopic-var-t-is-148410-and-start-is-0-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-.html Mein VS motzt auch deswegen.

    Wieso Rad neu erfinden? Ich will doch nur mein eintes einzigstes Fenster auslagern, damit ich es wiederverwenden kann, und die WinMain aufgeräumter aussieht. Und jetzt ist es auch eine Frage des Ehrgeizes, dass ich das schaffen möcht.



  • Hast Du das Beispiel dort verstanden??? Wie sieht DEIN CreateWindow(Ex) aus??? In Deinem ersten Beispiel hast Du da was komplett falsch gemacht (this fehlt)...
    Aber wie gesagt, wenn Du das (simple) Beispiel nicht verstanden hast, dann solltest Du dich da mal zuerst reindenken, bevor Du was eigenes machst...



  • Huch

    ich hab inzwischen folgendes in der MSDN rausgefunden

    bei GetWindowLongPtr:

    Remarks

    Reserve extra window memory by specifying a nonzero value in the cbWndExtra member of the WNDCLASSEX structure used with the RegisterClassEx function.

    also bei cbWndExtra sollte man bytes reservieren, geht aber auch ohne (?)

    bei CreateWindowEx:

    lpParam
    [in] Pointer to a value to be passed to the window through the CREATESTRUCT structure passed in the lParam member of the WM_CREATE message sent to the created window by this function before it returns. May be NULL if no additional data is needed.

    also das this im Beispiel hab ich nun zugefügt. jetzt geht es!

    Ich habs jetzt geschnallt.
    Ich hab mich doch auch gewundert, woher der Pointer im lParam des WM_CREATE kommen sollte. *kling* der Groschen ist nun gefallen.
    Wenn ich nun noch die Casts wegkriege, bin ich glücklich.
    Danke vielmals, du hast mir sehr geholfen.



  • Windows-User schrieb:

    Wenn ich nun noch die Casts wegkriege, bin ich glücklich.

    DIe bekommst Du nicht weg... sollten aber auch alle korrekt sein...


Anmelden zum Antworten