В одном проекте для платформы .NET мне понадобилось принудительно отобразить рамки фокуса (они бывают у контролов Button, RadioBox, CheckBox). При разработке приложений, которые в большинстве своем управляются с клавиатуры иногда бывает просто необходимо за кратчайшее время знать, на каком контроле находится текущий фокус. У кнопок, например, фокус может отображаться в двух состояниях:
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtNw7ThARy9HjjMcl60VvWzTIMYw5BSwfEgSDq3XIXhZxAVsgLaqOHBzjEvxfqQ3UsOMch3m2JBUsajuFb9-IlQNMnEIJGGucJeP8nMZmEAl0mLFqN1QeoJUkqIYdkEDdAncw5PSCvWLY/s320/button_without_cues.png)
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrD2oFqWn8W2U3vJmmr0nYLbp7VDSK1EK7Jvu3u8bes7PPsw7XcYNKQfA4tiSykQqRF7m0l-KdhQviK1aP1-feBtU1YZVq2pCSYQzak7yNCL-sRXcRvOa31VCvr4mGTY6rqM6Mp7kpfuk/s320/button_with_cues.png)
Как оказалось, без использования Windows API обойтись было нельзя. Поэтому после некоторого поиска в гугле, я натолкнулся на описание сообщения WM_UPDATEUISTATE, которое, как раз и отвечает за состояние контролов в окне. После родился следующий код:
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
public static IntPtr MakeLong(short lowPart, short highPart)
{
return (IntPtr)(((ushort)lowPart) | (uint)(highPart << 16));
}
public static void ShowFocusCues(IntPtr Handle)
{
const uint WM_UPDATEUISTATE = 0x0128;
//short UIS_SET = 1;
short UIS_CLEAR = 2;
//short UIS_INITIALIZE = 3;
short UISF_HIDEFOCUS = 0x1;
//short UISF_HIDEACCEL = 0x2;
//short UISF_ACTIVE = 0x4;
Common.SendMessage(Handle, WM_UPDATEUISTATE, MakeLong(UIS_CLEAR, UISF_HIDEFOCUS), (IntPtr)0);
}
Используя функцию ShowFocusCues(this.Handle) с параметром, указывающим на хендл активного окна, мы можем сменить режим отображения контролов на тот, что и требуется. То есть, принудительно отобразить рамки фокуса. Хендл окна описан в классе Form.
Также, если понадобится принудительно спрятать рамки фокуса, то можно использовать немного иную реализацию отправки сообщения WM_UPDATEUISTATE:
public static void HideFocusCues(IntPtr Handle)
{
const uint WM_UPDATEUISTATE = 0x0128;
short UIS_SET = 1;
//short UIS_CLEAR = 2;
//short UIS_INITIALIZE = 3;
short UISF_HIDEFOCUS = 0x1;
//short UISF_HIDEACCEL = 0x2;
//short UISF_ACTIVE = 0x4;
SendMessage(Handle, WM_UPDATEUISTATE, MakeLong(UIS_SET, UISF_HIDEFOCUS), (IntPtr)0);
}
Комментариев нет:
Отправить комментарий