[changeTopic]...



  • Sorry. Unter WinAPI.net gab es mal ein gutes Codeschnipsel zu Subclassing. Leider ist die Seite nicht mehr verfügbar. 😞 Genaueres kann ich Dir heute Abend erst sagen, hab mir das mal ausgedruckt, aber z. Zt. nicht zur Hand. (Vermutlich sind andere Forianer schneller).)

    Wie der Button bzw. das gesubclasste Fenster aussieht, legst Du in CreateWindowEx fest, mit dem 2. Parameter (LPCTSTR lpClassName) (bei CreateWindow ist das der 1. Parameter). Dort einfach "Button" eingeben.

    The CreateWindow function creates an overlapped, pop-up, or child window. It specifies the window class, window title, window style, and (optionally) the initial position and size of the window. The function also specifies the window's parent or owner, if any, and the window's menu.

    HWND CreateWindow(

    LPCTSTR lpClassName, // pointer to registered class name
    LPCTSTR lpWindowName, // pointer to window name
    DWORD dwStyle, // window style
    int x, // horizontal position of window
    int y, // vertical position of window
    int nWidth, // window width
    int nHeight, // window height
    HWND hWndParent, // handle to parent or owner window
    HMENU hMenu, // handle to menu or child-window identifier
    HANDLE hInstance, // handle to application instance
    LPVOID lpParam // pointer to window-creation data
    );
    (...)
    Class Meaning
    BUTTON Designates a small rectangular child window that represents a button the user can click to turn it on or off. Button controls can be used alone or in groups, and they can either be labeled or appear without text. Button controls typically change appearance when the user clicks them.

    Außerdem gibst Du für den Parameter dwStyle BS_PUSHBUTTON ein.

    BS_PUSHBUTTON Creates a push button that posts a WM_COMMAND message to the owner window when the user selects the button.

    Dann schreibst Du eine entsprechend ButtonProc dazu, die WM_RBUTTONDOWN/UP bearbeitet.



  • Meine Ironie schrieb:

    Ließt du einen meiner Beiträge?
    Ich wundere mich wieder, denn du schreibst so als wüsste ich nicht,
    a. wie ich einen Button erzeuge (da werden 1225 automatisch erzeugt, müsste reichen)
    b. das ich in einer eigenen Klasse ButtonUP behandeln soll.
    Bist du spät Schlafen gegangen 😃

    Also nochmal:
    Ich habe gefragt wie man Subclasst, das hatte sich erledigt.
    Das mit Button UP hatte ich auch schon geschrieben,
    die verbleibende Frage ist:

    Wieso wird TextOut aus dem Hauptfenster ÜBER die ganzen Buttons(die ja Childs sind) gelegt?

    Es ist sinnfrei Minesweeper zu Spielen wenn man schon sieht wo welche Mienen/Zahlen/Freiflächen sind. 😮



  • Guck dir mal die Nachricht WM_CONTEXTMEnU oder so ähnlich an, aheb gerade kein PSDK da, um mal schnell nachschlagen zu können.



  • lippoliv schrieb:

    Wieso wird TextOut aus dem Hauptfenster ÜBER die ganzen Buttons(die ja Childs sind) gelegt?

    Es ist sinnfrei Minesweeper zu Spielen wenn man schon sieht wo welche Mienen/Zahlen/Freiflächen sind. 😮

    Vermutlich, weil Du die Buttons bei WM_CREATE erzeugst, den Text aber bei WM_PAINT, und die kommt NACH WM_CREATE. Also wird der Text NACH den Buttons geschrieben, und damit logischerweise über die Buttons.



  • Liebe leute: Die letze offene frage ist kursiv geschrieben, die anderen sind gelöst.
    Oder sollte mir _Luckies Beitrag bei dem Schriftproblem helfen?

    Eine neue Frage:

    icon = LoadImage( NULL, "./flag.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE );
    if( 0 == SendMessage( myWnd, BM_SETIMAGE, IMAGE_ICON, (WPARAM)icon ) )
    	printf( "nio\n" );
    

    HANDLE icon;
    HWND myWnd;

    Wieso bekomme ich da immer nio?

    [edit]@Elektronix: Danke für dienen Post, allerdings muss ich anmerken, bevor ich gesubbclasst habe, ging alles... Also ohne sichtbaren Text...

    LRESULT CALLBACK WndProc( HWND myWnd, UINT wndMsg, WPARAM wParam, LPARAM lParam )
    /*
    	This function will recieve all messages, wich where send by windows to this window.
    */
    {
    	bool visitMsg = false;
    	int x,
    		y,
    		aktXPos,
    		aktYPos,
    		tmpX,
    		tmpY;
    	HDC myHdc;
    	PAINTSTRUCT myPaint;
    	char zahl;
    
    	x = y = aktXPos = aktYPos = 0;
    
    	switch( wndMsg )
    	{
    		case WM_CREATE:					//on window creation
    			for( y = 0; y < Yaxe; y++ )		//create all Buttons
    			{
    				for( x = 0; x < Xaxe; x++ )
    				{
    					mines[y][x] = CreateWindow( "BUTTON", "", WS_CHILD | WS_VISIBLE | WS_DLGFRAME, aktXPos, aktYPos, buttonX, buttonY, myWnd, (HMENU)bmMine, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    					SetWindowLong( mines[y][x], GWL_WNDPROC, (LONG)myBtn );
    					aktXPos += buttonX;					//generate the position of the new button
    				}
    				aktYPos += buttonY;
    				aktXPos = 0;
    			}
    			for( y = 0; y < numberOfMines; y++ )	//generate the mine infos, so that there are some mines in the game.
    			{
    				do
    				{
    					tmpX = zufall( 0, Xaxe*10 );
    					tmpY = zufall( 0, Yaxe*10 );
    				}while( isMine( tmpX/10, tmpY/10 ) );
    				arrayOfMines[y][1] = tmpX/10;
    				arrayOfMines[y][2] = tmpY/10;
    			}
    			visitMsg = true;
    		break;
    		case WM_PAINT:
    			myHdc = BeginPaint( myWnd, &myPaint );
    			{
    				for( y = 0; y < numberOfMines; y++ )	//write down the mines
    				{
    					TextOut( myHdc, arrayOfMines[y][1]*buttonX+3, arrayOfMines[y][2]*buttonY, "X", 1 );
    				}
    
    				for( y = 0; y < Yaxe; y++ )			//create the number of mines for a field
    				{
    					for( x = 0; x < Xaxe; x++ )
    					{
    						if( !isMine( x, y ) && countMines( x, y ) > 0 )
    						{
    							itoa( countMines( x, y ), &zahl, 10 );
    
    							TextOut( myHdc, x*buttonX+4, y*buttonY, &zahl, 1 );
    						}
    					}
    				}
    			}
    			EndPaint( myWnd, &myPaint );
    			visitMsg = true;
    		break;
    		case WM_CLOSE:
    			deleteList();						//delete the list
    			PostQuitMessage( 0 );
    		break;
    	}
    	if( !visitMsg )
    		return DefWindowProc( myWnd, wndMsg, wParam, lParam );
    
    	return visitMsg;
    }
    

    ist das ausreichend?



  • du bist nett und verdienst hilfe



  • Es tut mir leid wenn ich ein wenig unfreundlich wirke, ich versuch mein bestes, aber eine sache verstehe ich nicht: wieso Postet man was, ohne wenigstens den letzten und vorletzten beitrag zu lesen?

    Kann mir noch wer helfen?



  • lippoliv schrieb:

    Liebe leute: Die letze offene frage ist kursiv geschrieben, die anderen sind gelöst.
    Oder sollte mir _Luckies Beitrag bei dem Schriftproblem helfen?

    Was für in Schriftproblem?

    Ich will nun einen Rechtsklick auf eines dieser Fenster mitbekommen, um eine spezielle Funktion auszuführen.



  • lippoliv schrieb:

    Die verbleibende Frage ist:

    Wieso wird TextOut aus dem Hauptfenster ÜBER die ganzen Buttons(die ja Childs sind) gelegt?

    Es ist sinnfrei Minesweeper zu Spielen wenn man schon sieht wo welche Mienen/Zahlen/Freiflächen sind. 😮

    ^^12:51 Uhr
    Dein Zitat stammt aus dem ersten Beitrag, der schon ein wenig veraltet ist, es haben sich neue Probleme aufgetan, und um nicht unsinnig irgendwelche Threads aufzumachen, habe ich die Fragen dierekt hier gepostet. 🙂

    MFG und danke für alle bisherigen Posts...



  • Warum prüfst du denn nicht ob der Button weg ist und schreibst nur dann den Text und nicht immer.

    schirrmie


  • Mod

    lippoliv schrieb:

    Wieso wird TextOut aus dem Hauptfenster ÜBER die ganzen Buttons(die ja Childs sind) gelegt?

    Weil Du selbst drüber malst! Was erwartest Du?
    Sollte Dir als Antwort genügen 😉

    Ansonsten solltest Du einfach mal die MSDN Doku lesen, was ein DC ist und was es bedeutet wenn Child Windows einen DC bekommen. Wann diese geclippt werden und das dies nicht der Normalfall ist. Siehe Doku zu WS_CLIPCHILDREN...

    Grundlektüre für das Anlegen von Fenstern...



  • @schrimme, siehe mein topic "ist mein button SW_HIDE", da bekam ich keine antwort und keiner verstand warum ich sowas machen wollte(war anderer zusammenhang, aber das hat mich geprägt)

    @Martin: Ich erwarte das sich die "STAY_ON_TOP" verhältnisse (oder wie auch immer die heißen) sich nicht verändern, nur weil ich etwas subclasse, oder ist das zuviel erwartet?
    Was ist clippen? Naja MSDN wirds mir bestimmt mitteilen...

    Danke



  • wie sieht denn dein subclass aus?



  • regStandardWnd( hInstance, "myButton", (WNDPROC)myBtn, (HBRUSH)COLOR_BTNFACE )<<aufruf
    [...]
    bool regStandardWnd( HINSTANCE hInst, char *name, WNDPROC procedure, HBRUSH color )<<standardfunktion
    /*
    	This function registers a standard Window
    */
    {
    	WNDCLASSEX wndMain;
    
    	wndMain.cbSize = sizeof(WNDCLASSEX);
    	wndMain.style = CS_HREDRAW | CS_VREDRAW;
    
    	wndMain.lpfnWndProc = procedure;						//if there is an incomming message
    
    	wndMain.cbClsExtra = 0;									//extra memory for the class
    	wndMain.cbWndExtra = 0;									//extra memory for the window
    
    	wndMain.hInstance = hInst;								//handle from that instance, wich the window belong to
    
    	wndMain.hIcon = LoadIcon( NULL, IDI_APPLICATION );		//Program icon (set to std)
    	wndMain.hCursor = LoadCursor( NULL, IDC_ARROW );		//the cursor, wich schould been used in this program
    
    	wndMain.hbrBackground = color;		//background of the window
    
    	wndMain.lpszMenuName = NULL;							//there is no menue
    
    	wndMain.lpszClassName = name;							//application name
    
    	wndMain.hIconSm = LoadIcon( NULL, IDI_APPLICATION );	//smal Icon( eventually the tray-icon )
    
    	return RegisterClassEx( &wndMain );						//register the class, return the 
    }
    [...]
    LRESULT CALLBACK myBtn( HWND myWnd, UINT msg, WPARAM wParam, LPARAM lParam )
    {
    	bool visit = false;
    	int x = 0,
    		y = 0;
    	HANDLE icon;
    	switch( msg )
    	{
    		case WM_LBUTTONUP:
    			[...]
    		break;
    		case WM_RBUTTONUP:
    			[...]
    		break;
    	}
    	if( !visit )
    		return DefWindowProc( myWnd, msg, wParam, lParam );
    
    	return visit;
    }
    

    Meintest du dass?
    Wenn nicht einfach genauer werden, dann poste ich alles... Ahso:

    for( y = 0; y < Yaxe; y++ )		//create all Buttons
    {
    	for( x = 0; x < Xaxe; x++ )
    	{
    		mines[y][x] = CreateWindow( "BUTTON", "", WS_CHILD | WS_VISIBLE | WS_DLGFRAME, aktXPos, aktYPos, buttonX, buttonY, myWnd, (HMENU)bmMine, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    		SetWindowLong( mines[y][x], GWL_WNDPROC, (LONG)myBtn );
    		aktXPos += buttonX;					//generate the position of the new button
    	}
    	aktYPos += buttonY;
    	aktXPos = 0;
    }
    

    HWND mines[Yaxe][Xaxe] //2D - Array of HWND
    Hoffe die Variablen sprechen für sich...



  • Hmm deine neue wndproc sieht komisch aus! Und du speicherst dir nicht die alte wndproc adresse und schreibst sie beim Beenden nicht wieder zurück!

    Hier das war das tut von win-api.de guck dir das an und probier das.

    #include <windows.h>
    static LONG_PTR PrevWndProcEdit;
    
    // Hauptnachrichtenschleife
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
       static HWND hwndEditAlt;
    
       switch (message)
       {
       case WM_CREATE:
    // Editfeld erzeugen
          hwndEditAlt = CreateWindow("EDIT","",WS_VISIBLE|WS_CHILD|WS_BORDER,20,20,100,30,
                               hwnd,0,((LPCREATESTRUCT)lParam)->hInstance,0);
    // Den ursprünglichen WND-PROC Pointer sichern und durch den eigenen ersetzen.
          PrevWndProcEdit = SetWindowLongPtr (hwndEditAlt, GWLP_WNDPROC, 
                                    (LONG_PTR) EditWndProc);
          return 0;
    
       case WM_DESTROY:
    // Den ursprünglichen Pointer wieder einsetzen
          SetWindowLongPtr (hwndEditAlt, GWLP_WNDPROC, PrevWndProcEdit);
          PostQuitMessage (0);
          return 0;
       }
    
    return DefWindowProc (hwnd, message, wParam, lParam);
    }
    
    // Die neue WND-PROC für das Editfeld
    LRESULT CALLBACK EditWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
       switch (message)
       {
          case WM_CHAR:
             MessageBox (NULL, "Taste!", "Tasteneingabe im Editfeld", NULL);
    // stünde hier ein "return 0;" würde keine Taste im Editfeld erscheinen!
             break;  
       }
    
    return CallWindowProc ((WNDPROC) PrevWndProcEdit, hwnd, message, wParam, lParam);
    }
    


  • DANKE MARTIN... JEA...

    Muss man die wieder umschreiben? Warum, das Window wird ja eh zerstört...

    PS: es klappt jetzt übrigens... Jetzt noch dedr SET_IMAGE SenMessage fehler weg und man kann spielen.. Ich meld mich bestimmt wieder 😞



  • lippoliv schrieb:

    Muss man die wieder umschreiben? Warum, das Window wird ja eh zerstört...

    Jaja schon klar und ein free/delete brauch man in einem Programm ja auch nicht, das Programm wird ja eh irgendwann wieder geschlossen, ne 🙄



  • Achso und wegen dem hier

    Eine neue Frage:

    icon = LoadImage( NULL, "./flag.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE );
    if( 0 == SendMessage( myWnd, BM_SETIMAGE, IMAGE_ICON, (WPARAM)icon ) )
        printf( "nio\n" );
    

    Warum prüfst du erst bei SendMesage und nicht schon bei LoadImage, falls es an LoadImage liegt dann guck dir GetLastError an!

    schirrmie



  • free/delete(wofür auch immer delete ist): Im grunde schon, allerdings kann das wohl irgendwie fehler verursachen, und es dauert eine weile bis windows den Speciehr wieder frei gibt. Das Fenster ist doch im Grunde wie eine Variable, das System macht nach Programmende ncihts mehr damit oder wie?(Ich suche eine erklärung, nicht lediglich "Jaja shcon klar*ironie*"...)

    LoadImage kann (wie bei mir aktuell) gut gehen, und SendMessage Fehlschlagen...

    An mich: Wieso vergesse ich immer GetLastError... 😡

    Danke dir, ich werde da mal nachschauen...

    €dit: "0"(successfull) ist die ausgabe von GetLastError, ein Icon wird nicht angezeigt:

    flag = LoadImage( NULL, "flag.ico", IMAGE_ICON, buttonX, buttonY, LR_DEFAULTCOLOR | LR_LOADFROMFILE );
    [...]
    case WM_RBUTTONUP:
    	if( !isEnd )
    	{
    		icon = (HANDLE)SendMessage( myWnd, BM_GETIMAGE, IMAGE_ICON, (WPARAM)NULL );
    		if( icon != flag)
    		{
    			if( NULL == (HANDLE)SendMessage( myWnd, BM_SETIMAGE, IMAGE_ICON, (WPARAM)flag ) )
    				printf( "%d; fialure ", GetLastError() );
    			printf( "disable\n" );
    		}
    		else
    		{
    			printf( "enable\n" );
    			SendMessage( myWnd, BM_SETIMAGE, IMAGE_ICON, (WPARAM)NULL );
    		}
    		visit = true;
    	}
    break;
    

    if( clickedButtonIsMine ) -> isEnd = true;
    HANDLE icon;
    glob. HANDLE flag;


  • Mod

    lippoliv schrieb:

    @Martin: Ich erwarte das sich die "STAY_ON_TOP" verhältnisse (oder wie auch immer die heißen) sich nicht verändern, nur weil ich etwas subclasse, oder ist das zuviel erwartet?

    Stay on top gilt nicht für CHild Windows. (Wieder etwas was man durch Lesen erfahren kan!)


Anmelden zum Antworten