2010-12-28 7 views
5

Mam narzędzie do przechwytywania ekranu, na którym mogę opasać obszar na pulpicie. Zrobiłem to dość łatwo, mam formę, która ma taki sam rozmiar jak ekran, na którym narysowałem zrzut ekranu pulpitu przekształconego w skalę szarości. Kiedy użytkownik przytrzyma lewy przycisk myszy, może wybrać obszar na formularzu. Prostokąt, który rysuje użytkownik, jest wypełniony przez TransparentColor. Gdy użytkownicy podniesią jego mysz, przezroczysty prostokąt pozostanie na swoim miejscu, a rzeczywisty pulpit będzie widoczny. Tutaj przychodzi mój problem: Na moim dev PC mogę faktycznie przechodzić przez ten przezroczysty prostokąt i nawigować itd., Podczas gdy na moim drugim komputerze formularz reaguje na kliknięcia myszką na rzeczywistym przezroczystym prostokącie.Przejście do pulpitu w przejrzystym formularzu

Używam .NET 4.0 w języku C#, wszelkie pomysły, w jaki sposób mogę sprawić, aby rzeczywiście kliknął na pulpicie we wszystkich przypadkach?

Dziękuję i bardzo doceniane :)

Odpowiedz

7

udało mi się znaleźć odpowiednie rozwiązanie tego problemu po patrząc głęboko w to. Okazuje się, że przy prawidłowych wywołaniach interfejsu Win32 API możliwe jest ustawienie "Niewidzialnego" dla kliknięć myszy. Można to osiągnąć przez:

[DllImport("user32.dll", SetLastError = true)] 
static extern int GetWindowLong(IntPtr hWnd, int nIndex); 

[DllImport("user32.dll")] 
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); 

[DllImport("user32.dll")] 
static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags); 

public void SetFormTransparent(IntPtr Handle) { 
    oldWindowLong = GetWindowLong(Handle, GWL_EXSTYLE); 
    SetWindowLong(Handle, GWL_EXSTYLE, Convert.ToInt32(oldWindowLong | WS_EX_LAYERED | WS_EX_TRANSPARENT)); 
} 

public void SetFormNormal(IntPtr Handle) { 
    SetWindowLong(Handle, GWL_EXSTYLE, Convert.ToInt32(oldWindowLong | WS_EX_LAYERED)); 
} 

Ale istnieje podstęp do wszystkiego. Musisz uważać, aby wszystkie kliknięcia wykonane na forum spadały przez formularz i były wysyłane pod dowolne miejsce. Aby upewnić się, że po kliknięciu mojej formy, np. na przycisku i chcę, aby przycisk kliknął Zrobiłem prostą sztuczkę. Mam timer działający w tle co N milisekund i analizujący pozycję kursora. Jeśli znajduje się nad obszarem, w którym ma być, ustawi formularz na Normalny za pomocą SetFormNormal(), inaczej będzie przezroczysty.

Mam nadzieję, że ten kod nieco pomaga i ludzie będą z niego korzystać.

+0

Zamiast korzystać z licznika czasu, dlaczego nie skorzystać z zdarzeń OnMouseEnter/OnMouseDown dla każdej kontrolki w formularzu? – Jason

+6

Proszę dodać brakujące wartości stałych. –

+0

Oto kilka przydatnych linków: http://stackoverflow.com/questions/1524035/topmost-form-clicking-through-possible, http://pinvoke.net/default.aspx/Constants.GWL%20-%20GetWindowLong, http://pinvoke.net/default.aspx/Constants.Window%20styles – Xantix