Mauskoordinaten komfortabel abfragen ?



  • Sind das schon vorgegebene Funktionen? Wenn ja, welche Bibliothek?
    Oder beschreibt das einfach nur die Vorgehensweise?

    MfG
    Hundefutter



  • Das sind WinAPI-Funktion...
    PtInRect sollte eigentlich das sein, was Du suchst...



  • siehe Jochens Post...

    Wichtig/hilfreich ist vllt noch die Funktion ScreenToClient(...), der die Koordinaten auf Client-Koordinaten auf dein Fenster umrechnet.



  • Alles klar, danke für die Antworten.
    Lese mir dann mal nen paar Sachen zu den Funktionen durch und versuche die dann mal einzubauen. Vielen Dank!

    MfG
    Hundefutter



  • Habe mir jetzt mal die Funktion PtInRect() angeguckt.
    Jetzt müsste ich ja für jede Karte ein Rechteck anlegen und dann trotzdem noch mit if überprüfen, ob die Mauskoordinate in dem Rechteck liegt, oder?
    Das würde das ganze zwar etwas vereinfachen, aber um die riesige if-Verzweigung komme ich ich trotzdem nicht herum....

    Naja, wenigstens eine kleine Verbesserung 😉

    MfG
    Hundefutter



  • Ich nehme mal an, dass die Memorykarten regelmässig über den Bildschirm verteilt sind.
    Dann könntest du mit folgender Formel die Spalte und die Zeile der Karte herausbekommen, sofern die Karten direkt aneinander liegen.

    int zeile = PosY / kartenHoehe;    
    int spatle = PosX / kartenBreite;
    

    Dann müsstest du nur noch die Koordinaten (zeile, spalte) in die "Kartennummer" umrechnen.



  • Hundefutter schrieb:

    Jetzt müsste ich ja für jede Karte ein Rechteck anlegen und dann trotzdem noch mit if überprüfen, ob die Mauskoordinate in dem Rechteck liegt, oder?

    Nein.

    Hundefutter schrieb:

    Das würde das ganze zwar etwas vereinfachen, aber um die riesige if-Verzweigung komme ich ich trotzdem nicht herum....

    Doch:

    RECT rect;
    rect.top = 10;
    rect.bottom = 20;
    rect.left = 10;
    rect.right = 20;
    
    POINT pt;
    pt.x = 15;
    pt.y = 15;
    
    if( PtInRect( &rect, pt ) ) {
    
        ; // mach sonstwas.
    }
    

    Greetz, Swordfish



  • Nun habe ich 36 rechtecke. Kann ich jetzt mit ner for-schleife arbeiten und dann mit jedem durchlauf die Rechteck-Koordinaten verschieben?
    Also:

    RECT rect;
    rect.top = 10;
    rect.bottom = 20;
    rect.left = 10;
    rect.right = 20;
    
    POINT pt;
    pt.x = PosX; //Mauskoordinate X
    pt.y = PosY; //Mauskoordinate Y
    
    for(int i=0;i<36;i++)
    {
    
    if( PtInRect( &rect, pt ) ) 
    {
    
        ; // mach sonstwas.
    } //if
    
    //Rechteck verschieben
    rect.top += 80;
    // [...]
    
    } //for
    

    Probiere es jetzt so mal aus, wenn das falsch ist, ober es besser anders zu machen ist, bitte sagen.
    Danke für die Hilfen!

    MfG
    Hundefutter

    --------------
    EDIT:

    Alles klar, funktioniert so gut mit der For-Schleife!
    Vielen Dank! 🙂



  • und was bringt hier die for-Schleife?

    Greetz, Swordfish



  • Swordfish schrieb:

    und was bringt hier die for-Schleife?

    Greetz, Swordfish

    Also ich habe mir das so gedacht:
    Mit dem folgenden Quellcode durchlaufe ich die erste Reihe, also die ersten 6 Karten.

    //in der Callback-Funktion:
    case WM_LBUTTONDOWN:
    
    			//Mauskoordinaten in einem Punkt speichern
    			POINT pt;
    
    			pt.x = LOWORD( lParam );
    			pt.y = HIWORD( lParam );
    
    			//Ein Recheck definieren, welches dann immer verschoben wird
    			RECT rect;
    
    			rect.left	= 250;
    			rect.top	= 150;
    			rect.right	= 300;
    			rect.bottom = 200;
    
    			//Mit Hilfe einer For-Schleife Abfragen und das Rechteck verschieben
    			for(i=0;i<6;i++)
    			{
    				if(PtInRect( &rect, pt ))
    				{
    					Direct3D.change_Card(i);
    				};
    
    				//Rechteck verschieben
    				rect.left	+= 80;
    				rect.right	+= 80;
    
    			};
    
    			break;
    

    Dafür brauche ich dann doch die For-Schleife, oder nicht?

    MfG
    Hundefutter



  • Achso, ja, passt schon.

    Greetz, Swordfish



  • Ok.
    So ist das ganze natürlich schon viel kürzer und komfortabler.

    Wenn das jetzt noch zu steigern ist, bitte melden.

    Nochmals vielen Dank für die Hilfen.

    MfG
    Hundefutter



  • for (unsigned int i = 0; i < 6; ++i) 
    { 
        if (PtInRect(&rect, pt)) 
            Direct3D.change_Card(i); 
    
        //Rechteck verschieben 
        rect.left     += 80; 
        rect.right    += 80; 
    }
    

    😃 Ist nicht wirklich kürzer... aber nen Bissel 😃 ..



  • @(D)Evil: Witzkeks 😉 👍

    Greetz, Swordfish



  • Ich weiß ja nicht ob es beabsichtigt ist aber bei

    case WM_LBUTTONDOWN:
    

    wird die WM andauernd gesendet und schluckt somit Zeit ...

    Mit

    case WM_LBUTTONUP:
    

    geschieht alles wenn du die Taste loslässt...also nur einmal

    MfG Kuldren



  • Wenn die Karten immer an festen Positionen sind, warum definierst du dir nicht deine 36 Rechtecke in einem globalen Array?

    RECT CardRect[36];
    

    Dann kannst du in der Behandlungroutine schreiben

    case WM_LBUTTONUP:
    
                //Mauskoordinaten in einem Punkt speichern
                POINT pt;
    
                pt.x = LOWORD( lParam );
                pt.y = HIWORD( lParam );
    
                for(i=0;i<36;++i)
                {
                    if( PtInRect( &rect[i], pt ) )
                        Direct3D.change_Card(i);
                }
    
                break;
    

    Was noch effizienter wäre: Alle Rechtecke in einer Region zusammenfassen. Dann kannst du erstmal abfragen, ob sich der Cursor in der Region befindet mit PtInRgn() (oder so ähnlich) und dann erst in die for-Schleife gehen.



  • Habe es jetzt folgendermaßen aufgebaut:

    case WM_LBUTTONUP:
    
    			//Mausklick-Zähler um 1 erhöhen
    			click_zaehler++;
    
    			//Mauskoordinaten in einem Punkt speichern
    			POINT pt;
    
    			pt.x = LOWORD( lParam );
    			pt.y = HIWORD( lParam );
    
    			//Ein Recheck definieren, welches dann immer verschoben wird
    			RECT rect;
    
    			rect.left	= 250;
    			rect.top	= 150;
    			rect.right	= 300;
    			rect.bottom = 200;
    
    			//Mit Hilfe einer For-Schleife Abfragen und das Rechteck verschieben
    			for(i=0;i<36;i++)
    			{
    				if(PtInRect( &rect, pt ))
    				{
    					Direct3D.change_Card(i);
    				}
    
    					//Rechteck verschieben
    					rect.left	+= 80;
    					rect.right	+= 80;
    
    					if(i == 5) //Wechsel in Zeile 2
    					{
    						rect.left	= 250;
    						rect.top	= 230;
    						rect.right	= 300;
    						rect.bottom = 280;
    					}
    					else if (i == 11) //Wechsel in Zeile 3
    					{
    						rect.left	= 250;
    						rect.top	= 310;
    						rect.right	= 300;
    						rect.bottom = 360;
    					}
    					else if (i == 17) //Wechsel in Zeile 4
    					{
    						rect.left	= 250;
    						rect.top	= 390;
    						rect.right	= 300;
    						rect.bottom = 440;
    					}
    					else if (i == 23) //Wechsel in Zeile 5
    					{
    						rect.left	= 250;
    						rect.top	= 470;
    						rect.right	= 300;
    						rect.bottom = 520;
    					}
    					else if (i == 29) //Wechsel in Zeile 6
    					{
    						rect.left	= 250;
    						rect.top	= 550;
    						rect.right	= 300;
    						rect.bottom = 600;
    					}; //if
    			}; //for
    break;
    

    Könnte das mit dem Rechteck-Array noch machen. Würde sich das noch sehr positiv auf die Performance des Programms auswirken?
    Wenn ja, dann baue ich das gerne ncoh ein.

    MfG
    Hundefutter



  • Hundefutter schrieb:

    Könnte das mit dem Rechteck-Array noch machen. Würde sich das noch sehr positiv auf die Performance des Programms auswirken?

    Naja, nicht wirklich merkbar. Aber trotzdem würde ich das so machen. Erstens wird der Code so besser lesbar und zweitens: wer weiß, wozu du die Rechtcke noch brauchst... Dann musst du wieder das Geschiebe da machen.



  • Alles klar, dann bau ich das noch um, vielen Dank für die Nützlichen Tipps.



  • Habe gerade noch nen paar Probleme beim Initialisieren der Rechtecke.
    Habe ein Array deklariert, in welches ich die Rechtecke packe:

    RECT Rechtecke[36];
    

    Jetzt möchte ich dem ersten Feld im Array die Koordinaten des ersten Rechtecks zuordnen, nur gibt mir der Compiler immer wieder Fehlermeldungen aus.
    Habe es mal so probiert:

    Rechtecke[0] = {250,150,300,200};
    

    Nur das kann ja eigentlich so nicht funktionieren, weil das ja so nur beim erstellen des Arrays verwendet wird, wenn ich das Array sofort beim Erstellen mit Werten füllen will.

    Stehe gerade irgendwie aufm schlauch, ist wahrscheinlich ganz simpel, habe aber vorher noch nicht mit Rechtecken gearbeitet.

    Normal ist es ja so:

    //entweder so
    int array[3] = {1,2,3};
    
    //oder so
    int array[3];
    
    array[1] = 1;
    array[2] = 2;
    array[3] = 3;
    

    Nur wie läuft es jetzt mit Rechtecken?
    Hoffe nochmal auf eure Hilfe 🙄

    MfG
    Hundefutter


Anmelden zum Antworten