Можете ли вы сделать это в .NET / C #?
Да, конечно, можно, но это требует немного усилий. Я бы порекомендовал следующий подход. Создайте форму верхнего уровня, которая не имеет границы или области заголовка, а затем убедитесь, что она не рисует фон клиентской области, задав для TransparencyKey и BackColor одинаковое значение. Теперь у вас есть окно, которое ничего не рисует ...
public class DarkenArea : Form
{
public DarkenArea()
{
FormBorderStyle = FormBorderStyle.None;
SizeGripStyle = SizeGripStyle.Hide;
StartPosition = FormStartPosition.Manual;
MaximizeBox = false;
MinimizeBox = false;
ShowInTaskbar = false;
BackColor = Color.Magenta;
TransparencyKey = Color.Magenta;
Opacity = 0.5f;
}
}
Создайте и разместите это окно DarkenArea над клиентской областью вашей формы. Затем вам нужно будет показать окно, не фокусируясь на нем, и вам нужно будет вызывать платформу следующим образом, чтобы показывать ее, пока она не стала активной ...
public void ShowWithoutActivate()
{
// Show the window without activating it (i.e. do not take focus)
PlatformInvoke.ShowWindow(this.Handle, (short)SW_SHOWNOACTIVATE);
}
Вы должны сделать так, чтобы оно действительно рисовало что-то, но исключить рисование в области элемента управления, который вы хотите оставить выделенным. Поэтому переопределите обработчик OnPaint и рисуйте черным / синим или чем угодно, кроме области, в которой вы хотите остаться яркой ...
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// Do your painting here be exclude the area you want to be brighter
}
Наконец, вам нужно переопределить WndProc, чтобы предотвратить взаимодействие мыши с окном, если пользователь пытается что-то сумасшедшее, например, щелкнуть затемненную область. Как то так ...
protected override void WndProc(ref Message m)
{
if (m.Msg == (int)WM_NCHITTEST)
m.Result = (IntPtr)HTTRANSPARENT;
else
base.WndProc(ref m);
}
Этого должно быть достаточно, чтобы получить желаемый эффект. Когда вы готовы отменить эффект, вы избавляетесь от экземпляра DarkenArea и продолжаете.