В одном проекте для платформы .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);
}