Переход на рабочий стол в прозрачной форме - PullRequest
5 голосов
/ 28 декабря 2010

У меня есть утилита захвата экрана, с помощью которой я могу резиновую область на рабочем столе. Я сделал это довольно легко, у меня есть форма такого же размера, что и экран, на котором я рисую скриншот рабочего стола, преобразованного в оттенки серого. Когда пользователь удерживает левую кнопку мыши, он может выбрать область в форме. Прямоугольник, который рисует пользователь, заполнен TransparentColor. Как только пользователь поднимает свою мышь, прозрачный прямоугольник остается на месте, и фактический рабочий стол становится видимым. Вот моя проблема: На моем компьютере разработчика я могу фактически щелкнуть этот прозрачный прямоугольник и перемещаться по нему и т. Д., В то время как на моем другом ПК форма реагирует на щелчки мыши по фактическому прозрачному прямоугольнику.

Я использую .NET 4.0 в C #, какие-либо идеи о том, как я могу заставить его действительно перейти на рабочий стол во всех случаях ??

Спасибо и высоко ценим:)

1 Ответ

7 голосов
/ 14 января 2011

Мне удалось найти правильное решение этой проблемы, после того, как я очень глубоко в нее заглянул. Оказывается, при правильных вызовах Win32 API можно задать форму «Невидимый» для щелчков мышью. Это может быть достигнуто путем:

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

Но во всем есть хитрость. Вы должны быть осторожны, чтобы все клики, сделанные на форуме, попадали через форму и отправлялись на все, что ниже формы. Чтобы убедиться, что если я нажму на мою форму, например, на кнопку, и я хочу, чтобы кнопка нажала, я сделал простой трюк. У меня есть таймер в фоновом режиме, работающий каждые N миллисекунд и анализирующий положение курсора. Если он находится над областью, которую я хочу, он установит для формы значение Normal с помощью SetFormNormal (), в противном случае он будет прозрачным.

Надеюсь, этот бит кода поможет, и люди будут его использовать.

...