Strona główna > Przykłady > Z cyklu boso przez Śródziemie: biblioteka GDI+ oraz jak sprawdzić, czy kursor zawiera się w figurze geometrycznej.

Z cyklu boso przez Śródziemie: biblioteka GDI+ oraz jak sprawdzić, czy kursor zawiera się w figurze geometrycznej.

Dziś wykorzystam bibliotekę graficzną GDI+ i pokażę jak przetestować czy kursor zawiera się w jakiejś figurze geometrycznej. Napiszę aplikację, która będzie wyświetlała nazwę wskazanej na mapie krainy.

W tym celu biorę kostkę rosołową Knorr, odpalam Visual Sudio 2008 i tworzę nowy projekt WinForms. Do utworzonej domyślnie formy dodaję kontrolkę PictureBox, nazywam ją mapkaPictureBox i wstawiam do niej gotowy obrazek (właściwość Image w oknie Properties). Obrazkiem będzie wyszukana w  googlach mapka tolkienowskiego Śródziemia na licencji GNU.  Zmieniam właściwość SizeMode na StretchImage, co spowoduje dopasowanie obrazka do rozmiarów kontrolki. Do formy dodaję jeszcze labelki, które nazywam xyLabel i krainaLabel. Gotuję na małym ogniu przez  3min. ciągle mieszając 🙂

Następnie tworzę metodę obsługująca zdarzenie MouseMove, która ułatwi mi dalszą pracę. (W Form1.cs[Design] klikam obrazek, następnie w oknie Properties wybieram grupę Events i podwójnie klikam na MouseMove – zostanie wygenerowany szkic metody w Form1.cs, oraz potrzebny kod w pliku Form1.Designer.cs . Środek metody wypełniamy sami.)

//ta metoda ma pomóc w określeniu współrzędnych punktów,
//które będą wierzchołkami wielkąta ograniczającego Gondor
private void mapkaPictureBox_MouseMove(object sender, MouseEventArgs e)
{
  xyLabel.Text = String.Format("Współrzędne: x={0}, y={1}", e.X, e.Y);
}

Od tej pory w labelce xyLabel będę widział aktualne położenie myszki na obrazku.

Następnie przystępuje do napisania metody, która obsłuży zdarzenie MouseDown dla mapkaPictureBox. Wygląda ona następująco:

private void mapkaPictureBox_MouseDown(object sender, MouseEventArgs e)
{
//tworzymy obiekt klasy Graphics, który będzie potrzebyny do narysowania ramek
Graphics g = mapkaPictureBox.CreateGraphics();

//tworzymy prosokąt ograniczający Mordor
Rectangle rMordor = new Rectangle(530, 270, 190, 100);

//tworzymy wielkoąt, który będzie reprezentował granice Gondoru
Point p1 = new Point(340, 280);
Point p2 = new Point(310, 320);
Point p3 = new Point(390, 320);
Point p4 = new Point(400, 350);
Point p5 = new Point(445, 300);
Point [] pTab = new Point[] {p1,p2,p3,p4,p5};
GraphicsPath gpGondor = new GraphicsPath();
gpGondor.AddPolygon(pTab);

//rysujemy na mapie prostokąt reprezentujący Mordor,
//oraz wielkoąt reprezentujący Gondor
//Możemy pominąć rysowanie, aby mapka ładniej wyglądała
g.DrawRectangle(new Pen(Color.Red, 3), rMordor);
g.DrawPath(new Pen(Color.Blue,3),gpGondor);

//sprawdzamy czy kursor w czasie klkinięcia był w obrębie Mordoru lub Gondoru
if (rMordor.Contains(e.X, e.Y))
    krainaLabel.Text = "Wybrałeś Mordor";
else if (gpGondor.IsVisible(e.X, e.Y))
    krainaLabel.Text = "Wybrałeś Gondor";
else
    krainaLabel.Text = "Wybierz Mordor lub Gondor";
}

Uwaga: klasa GraphicPath znajduje się w przestrzeni nazw System.Drawing.Drawing2D, która nie jest domyślnie dołączana w projekach Windows Forms.

Kluczowe są tu linijki 26 i 28. To tutaj sprawdzam metodą Contains (należącą do klasy Rectangle), czy kursor w czasie kliknięcia jest wewnątrz prostokąta rMordor , oraz metodą IsVisible (należącą do klasy GraphicPath) , czy jest wewnątrz wielokątu gpGondor.

Gotowy program wygląda tak:

Program Śródziemie

Voilà!

Zachęcam do podzielenia się opinią na temat prezentowanego programu, a także całego wpisu. Z chęcią wyjaśnię niejasności. Głos uzasadnionej i wyrozumiałej krytyki będzie również mile widziany.

Kategorie:Przykłady Tagi: , , ,
  1. some1
    20 września 2011 o 1:10 pm

    Całkiem pomocny poradnik.
    Jednak nurtuje mnie jedna sprawa. Co jeśli zechcemy aby obsluga zdarzenia „MouseMove” odbyła się tak jakby dla naszego pulpitu.
    Chodzi mi tutaj o przekazanie do „Labela” informacji na temat tego w jakiej pozycji znajduje się kursor względem pixela(0,0) na pulpicie, nie w danej kontrolce. Jak to ugryść?

    • 20 września 2011 o 3:10 pm

      Pozycję kursora na ekranie możemy pobrać używając właściwości Cursor.Position

      lblX.Text = Cursor.Position.X.ToString(); // pozycja X zapisana do labelki

      Zapisanie pozycji jest jednorazowe, ale możemy użyć Timer’a i jego zdarzenie Tick aby uzyskać efekt podobny do sprawdzania współrzędnych w MouseMove.

      Jako ciekawostkę można potraktować starszy sposób z użyciem metody GetCursorPos z biblioteki user32.dll.

      // dodajemy przestrzeń nazw wymaganą do użycia dll
      using System.Runtime.InteropServices;

      //w klasie formy deklarujemy metodę
      [DllImport(„user32.dll”)]
      static extern bool GetCursorPos(ref Point lpPoint);

      // … i używamy metody do pobrania punktu kursora
      Point punkt = new Point(); // tworzymy obiekt Point
      GetCursorPos(ref punkt); // współrzędne zostają zapisane do punktu
      lblX.Text = „X = ” + punkt.X.ToString(); // zapisujemy współrzędną X w labelce
      lblY.Text = „Y = ” + punkt.Y.ToString(); // analogicznie Y

  2. some1
    20 września 2011 o 4:46 pm

    Dziękuję bardzo, kombinowałem z tym bo myślałem, że to trudniejsze.
    Geniusz tkwi jednak w prostocie.
    Ponadto dziękuję za dołożenie fragmentu z importowaniem bilbiotek, właśnie pisałem coś co z tego korzysta i sie zastanawiałem jak i po co.

    Pozdrawiam

    p.s
    Liczę na więcej przykładów, tak naprawdę to one zachęcają do twórczego myślenia, oraz uzupełniają wiedzę z różnych dziedzin.

    • 21 września 2011 o 8:00 am

      Ciesze się, że mogłem Ci pomóc. Też mam nadzieję, że opublikuję jeszcze sporo ciekawych artykułów. 😛

  3. some1
    22 września 2011 o 9:29 am

    Mam nawet pomysł. Męczę się już z tym drugi dzień.
    Temat po części związany z moim poprzednim pytaniem.
    Mianowicie, przeczytałbym jakiś ciekawy opis tego jak poslugiwać się „Hook’ami”.
    Bardzo ciekawe zagadnienie i uważam, że przydatne dla wielu aplikacji, które chcą pobierac info na temat interakcji użytkownika z komputerem z innego wątku niż jest w danymm momncie „ontop”.
    Jest pare artykułów na msdn, ale co polski tutek to polski.

    Da się zrobić ?
    Pozdrawiam

    • 23 września 2011 o 2:20 pm

      Niestety nie da się 🙂 Nie czuję się na tyle pewnie w temacie haków, żeby pisać o tym tutka ( narazie określam się jako początkujący programista ). TUTAJ znajdziesz ciekawy polski artykuł ( może jeszcze na niego nie wpadłeś ) o hakach, autorstwa Maćka Aniserowicza, którego blog nawiasem mówiąc gorąco polecam. Maciek też wspomina, że ciężko coś znaleźć na ten temat w polskim internecie.

  1. 14 lutego 2011 o 5:50 pm

Dodaj komentarz