Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C#/.NET] Windows Form slepen: waarom werkt mijn code goed?

Pagina: 1
Acties:
  • 111 views sinds 30-01-2008
  • Reageer

  • Maniakje
  • Registratie: Februari 2001
  • Laatst online: 01-11 10:36
Wellicht een beetje een vreemde topictitel, maar ik heb een kleine vraag waarop ik mij al een tijdje blindstaar.

Ik heb een shaped form, dus in een andere vorm dan de traditionele rechthoek. Omdat dit form geen titelbalk heeft is het niet te verplaatsen door de titelbalk te slepen. Daarom wil ik het kunnen verplaatsen door op de achtergrond te klikken en slepen.

Ik heb hiervoor de volgende eenvoudige code:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public partial class Form1 : Form
{
    private Boolean bezigMetSlepen = false;
    private Point klikCoords;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        //Sla coordinaten op waar geklikt is
        klikCoords = new Point(e.X, e.Y);
            
        //Geef aan dat we gaan slepen
        bezigMetSlepen = true;
    }

    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
        //Muisknop losgelaten, dus stop met slepen
        bezigMetSlepen = false;
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        //Zijn we aan het slepen? Zo ja, dan moet het form verplaatst worden
        if (bezigMetSlepen)
        {
            //Bereken de afstand van de huidige muispositie tot aan de positie
            //waarop geklikt was: dat is de afstand waarover gesleept is
            int dX = e.X - klikCoords.X;
            int dY = e.Y - klikCoords.Y;

            //Bereken de nieuwe locatie voor het form
            Point newloc = new Point(this.Location.X + dX, this.Location.Y + dY);
            this.Location = newloc;
        }
    }
}



Dit werkt als een trein en doet precies wat ik wil. Wat ik alleen niet snap is waarom.

Even nagaan wat er (volgens mij) gebeurt a.d.h.v. een voorbeeldje:

1. Het form bevindt zich op de coordinaten 300,300 op het scherm.
2. De user drukt de muisknop in op coordinaten 10,10 op het form (dus 310,310 op het scherm).
3. Deze coordinaten (10,10) worden opgeslagen in klikCoords en bezigMetSlepen wordt true.
4. De user sleept nu 10 pixels naar rechts. De MouseMove event doet zich voor.
5. De verplaatste afstand (dx, dy) wordt berekend (= 10,0) en het form wordt vanaf zijn huidige locatie over dezelfde afstand verplaatst. De nieuwe locatie is dus 310,300.
6. De muisknop is nog steeds ingedrukt en de user sleept nog eens 10 pixels naar rechts. De MouseMove event doet zich nogmaals voor.
7. De verplaatste afstand (dx,dy) wordt opnieuw berekend en is nu (20,0).
8. Het form wordt vanaf zijn huidige locatie verplaatst en de nieuwe locatie is dus 330,300.

Omdat in stap 8 het form vanaf zijn huidige locatie wordt verplaatst, zou ik verwachten dat het uitkomt op 330,300 (de oude 310,300 + 20,0). Gewenst is natuurlijk dat het op 320,300 uitkomt, aangezien de user pas 20 pixels gesleept heeft.

In werkelijkheid wordt in stap 8 het form gewoon keurig op locatie 320,300 geplaatst. Waarom?

Wat ik zou verwachten dat ik moet doen, is in de MouseDown event naast de klikCoords ook de locatie van het form opslaan (dus op het moment van starten met slepen), en in de MouseMove de nieuwe locatie relatief aan de startlocatie berekenen. Maar juist als ik dat doe reageert het form niet goed op het slepen.

Wat is er fout in mijn redenatie?

The sentence below is true.
The sentence above is false.


  • lvh
  • Registratie: Juli 2001
  • Laatst online: 02-11-2022

lvh

Zolang je de muis niet loslaat blijf je de coordinaten van het punt waar je het aanklikte behouden, en dan blijft je stelling toch gewoon geldig?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
^^ Wat hij zegt.
Maar daar ben je toch ook zo achter als je effe een watch (of whatever) gooit op klikcoords :? Of is debuggen tegenwoordig zo'n black magic? :)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Serpie
  • Registratie: Maart 2005
  • Laatst online: 01-07-2023
De redenatie klopt op zich wel, e.x & e.y bevatten echter geen screen coordinaten, maar de coordinaten van de muis op het venster zelf.
De verplaatste afstand (dx,dy) wordt opnieuw berekend en is nu (20,0).
Deze is dus niet waar, de muis verplaatst ten opzichte van het form geen 20 pixels, het form is zelf al verschoven inmiddels.

[ Voor 46% gewijzigd door Serpie op 30-10-2007 22:45 ]


  • ? ?
  • Registratie: Mei 2007
  • Niet online

? ?

Serpie schreef op dinsdag 30 oktober 2007 @ 22:42:
e.x & e.y bevatten echter geen screen coordinaten, maar de coordinaten van de muis in het venster zelf.
code:
1
2
3
4
5
6
7
8
[DllImport("user32.dll")]
private static extern int GetCursorPos (ref POINTAPI lpPoint);

[StructLayout(LayoutKind.Sequential)]
private struct POINTAPI{
    internal int x;
    internal int y;
}



Met GetCursorPos zou het wel moeten lukken, die geeft de coordinaten tov het ganse scherm
Apivierwer http://www.activevb.de/ru...r/index-apiviewereng.html is een handig tooltje om alle API's in C# / VB.NET formaat direct bij de hand te hebben of te doorzoeken

code:
1
System.Windows.Forms.Cursor.Position


Is normaal gezien het managed alternatief voor de API

[ Voor 51% gewijzigd door ? ? op 31-10-2007 08:30 ]


  • Maniakje
  • Registratie: Februari 2001
  • Laatst online: 01-11 10:36
Bedankt voor de reacties iedereen. :)

Serpie's opmerking verklaart helemaal wat er gebeurt.

Nu ik begrijp waarom mijn code goed werkt, ga ik het ook niet veranderen naar schermcoordinaten. De huidige oplossing vind ik wat eleganter en is volgens mij ook enigszins efficiënter omdat er geen opslag van de beginlocatie van het form nodig is.

The sentence below is true.
The sentence above is false.


  • ? ?
  • Registratie: Mei 2007
  • Niet online

? ?

Precies, omdat je telkens in form1_mousemove het formulier een heel klein beetje verschuift als je muis een heel klein beetje verschuift, geeft dat het effect dat je form je muis altijd volgt.

Misschien dat het op tragere machines niet werkt, als jij je muis vlugger uit je form kan bewegen dan de mousemove event optreedt, zal het niet werken. Maar dat zal wel niet zo vlug optreden :)
Pagina: 1