Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Transparency problem


Rekomendowane odpowiedzi

Opublikowano

Witam, dopiero zaczynam swoją przygodę z C#. Napisałem sobie prosty programik i w Visual Studio chce zrobić do niego grafikę. Mój problem polega na tym, że używam nietypowego kształtu grafiki (niektóre elementy wystają poza "główny" obszar) i chcę, aby okno było przesuwane (jest borderless) przez kliknięcie i przesunięcie w dowolnym miejscu. Wrzuciłem sobie przykładową funkcję do przesuwania borderlessów z internetu. Wszystko działa, jednak problem jest w tym, że na niewidzialnej części w obszarze okna także da się kliknąć i je przesunąć, chciałbym aby można było przesuwać tylko tam gdzie jest widoczny obrazek. Jest na to jakieś rozwiązanie? Obrazek mam wrzucony w Background image, ustawiłem Background color i dałem transparency key na ten sam kolor. Proszę o wyrozumiałość, uczę się. Oczywiście za pomoc będą plusy.
Kod, którego używam do przesuwania:
 

protected override void WndProc(ref Message m)
 {
   switch (m.Msg)
   {
       case 0x84:
           base.WndProc(ref m);
           if ((int)m.Result == 0x1)
               m.Result = (IntPtr)0x2;
           return;
   }
   base.WndProc(ref m);
 }
Opublikowano

Po pierwsze - witaj na forum!

Co do pytania:
najprościej będzie zrobić odwołanie do systemu o przesunięcie poprzez dodanie:

public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;

[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();

i oczywiście interop services

using System.Runtime.InteropServices;

a następnie w zdarzeniu onclick formy lub kontrolki dodać:

if (e.Button == MouseButtons.Left) {
    ReleaseCapture();
    SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}

jeśli zaś chodzi o transparentne obszary najprościej będzie ustawić ręcznie miejsce w które można kliknąć poprzez stworzenie sobie w nich rectangle'a i sprawdzanie kolizji przykładowo tak:

private bool checkCollision(Rectangle target) {
    Point MousePoint = PointToClient(Cursor.Position);
    Rectangle MouseRectangle = new Rectangle(MousePoint.X, MousePoint.Y, 1, 1);
    if (MouseRectangle.IntersectsWith(target))
        return true;
    else
        return false;
}

wtedy kod wyżej zmieniamy na:

if (e.Button == MouseButtons.Left) {
    if(checkCollision(obszar1) || checkCollision(obszar2)) { //i tak dalej
        ReleaseCapture();
        SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
    }
}

Jeśli masz jakieś dalsze pytania lub wątpliwości - śmiało ;)

Pozdrawiam,
 Paweł 'asrv'

PS Nie lepiej zainteresować się WPF jeśli chcesz robić takie "ładne" programy? ;)

PPS Jeśli masz bardzo nieregularny kształt musisz sprawdzać jakiego koloru jest tło i porównywać wartość z transparency key, jeśli będzie to konieczne to napisz w tym temacie - spróbuję zrobić dla Ciebie jakiś pomocniczy kod.

"Zwei Dinge sind unendlich, das Universum und die menschliche Dummheit, aber beim Universum bin ich mir nicht ganz sicher."
~A. Einstein

Opublikowano

Dziękuje za odpowiedź, bo dłuższym eksperymentowaniu i przemyśleniach postanowiłem przenieść się na WPF, daje on wielokrotnie większe możliwości niż WinForm. Myślę że temat można zamknąć.

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...