В одном проекте для платформы .NET мне понадобилось принудительно отобразить рамки фокуса (они бывают у контролов Button, RadioBox, CheckBox). При разработке приложений, которые в большинстве своем управляются с клавиатуры иногда бывает просто необходимо за кратчайшее время знать, на каком контроле находится текущий фокус. У кнопок, например, фокус может отображаться в двух состояниях:
На самом деле, Windows настроена так, чтобы автоматом включать режим отображения рамок по клавише TAB. Но у меня возникла проблема. Переходы надо было осуществлять по кнопке Enter и в форме, на которой куча контролов, было легко заблудиться без рамок фокуса.
Как оказалось, без использования 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);
}
Комментариев нет:
Отправить комментарий