2010-12-28 19 views
5

Tengo una utilidad de captura de pantalla en la que puedo agrupar un área en el escritorio. He hecho esto de una manera bastante fácil, tengo un formulario que es del mismo tamaño que la pantalla en la que dibujo una captura de pantalla del escritorio transformada en escala de grises. Cuando el usuario mantiene presionado el botón izquierdo del mouse, puede seleccionar un área en el formulario. El rectángulo que dibuja el usuario está lleno de TransparentColor. Una vez que los usuarios levantan el mouse, el rectángulo transparente se deja en su lugar y el escritorio real es visible. Aquí viene mi problema: En mi PC de desarrollo, realmente puedo hacer clic a través de este rectángulo transparente y navegar, etc. mientras que en mi otra PC, el formulario responde con un clic del mouse en el rectángulo transparente real.Hacer clic en el escritorio en un formulario transparente

Estoy usando .NET 4.0 en C#, ¿alguna idea sobre cómo puedo hacer que realmente haga clic en el escritorio en todos los casos?

Gracias y muy apreciado :)

Respuesta

7

he conseguido encontrar una solución adecuada para este problema después de mirar muy profundamente en esto. Resulta que con las llamadas API de Win32 adecuadas, es posible establecer un formulario "Invisible" a los clics del mouse. Esto se puede lograr por:

[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)); 
} 

Pero hay un truco para todo. Debe tener cuidado de que todos los clics realizados en el foro se incluyan en el formulario y se envíen a todo lo que esté debajo del formulario. Para garantizar que si hago clic en mi formulario, p. en un botón y quiero hacer clic en el botón, hice un truco simple. Tengo un temporizador en el fondo ejecutando cada N milisegundos y analizando la posición del Cursor. Si está por encima del área que quiero que sea, establecerá el formulario en Normal a través de SetFormNormal(), de lo contrario será transparente.

Espero que este código ayude y la gente lo use.

+0

En lugar de utilizar un temporizador, ¿por qué no aprovechar los eventos OnMouseEnter/OnMouseDown para cada control en su formulario? – Jason

+6

Agregue los valores faltantes para las constantes. –

+0

Aquí hay algunos enlaces útiles: 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

Cuestiones relacionadas