Как стать автором
Обновить

Программа для работы с окнами как в Windows 7 — при помощи hotkeys: Win + [Up|Down|Left|Right]

Время на прочтение4 мин
Количество просмотров1.2K
Редко пользуешься тем, что пишешь сам. Но вот тот самый редкий случай.
В Windows 7 мне очень понравилась возможность позиционирования окон при помощи сочетаний клавиш:
Win + Left — окно крепиться к левому краю
Win + Right — окно крепиться к правому краю
Win + Up — окно максимизируется
Win + Bottom — окно в нормальном состоянии.
Причем крепление окон к правому краю и левому, по-моему, уж очень удобная штука, ведь сколько раз приходилось самому располагать два окна на экране, с возможностью сравнения или перепечатывания…

Windows 7 не хочу использовать в качестве основной ОСь — потому что бета (или CR, главное что не Release), а возможность описанную выше использовать хочу. И вот — не поленился, и написал программку на C#, которая реализует данный функционал в Vista (скорее всего работает и более ранних версиях — просто не проверял). И как оказалось — задача не такая уж и сложная. Пришлось проимпортировать множество WinApi функций, а сама реализация разделилась на две: а) функционал, который перехватывает нажатия необходимых сочетаний клавиш б) позиционирование окон.

Первую задачу решил при помощи статьи Low-Level Keyboard Hook in C #, все что осталось сделать мне — найти возможность узнать когда была нажата клавиша LWin:
private static IntPtr HookCallback(
  int nCode, IntPtr wParam, IntPtr lParam)
{
  if (nCode >= 0 && wParam == (IntPtr)WAKeysHook.WmKeyDown)
  {
    if ((int)WAKeysHook.GetAsyncKeyState((IntPtr)Keys.LWin) != 0) // Left Win Key
    {
      Keys key = (Keys) Marshal.ReadInt32(lParam);
      if (key == Keys.Left || key == Keys.Right || key == Keys.Up || key == Keys.Down) // Arrows keys
        SetWindowLocation(key);
    }
  }
  return WAKeysHook.CallNextHookEx(WaKeysHook.HookId, nCode, wParam, lParam);
}


* This source code was highlighted with Source Code Highlighter.
Вторая часть задачи: найти активное окно и установить ему грамотный размер (само собой нужно учитывать, что менять размеры можно только окнам с такой возможностью (WS_SIZEBOX), а так же что некоторые окна имеют максимально разрешенные размеры своего окна, как у cmd.exe):
private static void SetWindowLocation(Keys k)
{
  //Active Window
  IntPtr window = WAWindows.GetForegroundWindow();
  // Check SIZEBOX Style (Window can sizable)
  if (((int)WAWindows.GetWindowLongPtr(window, WAWindows.GwlStyle) & WAWindows.WsSizebox)
    == WAWindows.WsSizebox)
  {
    // Show window in normal state (if always maximized)
    WAWindows.ShowWindow(window, (int)WAWindows.WindowShowStyle.ShowNormal);
    
    //Need Maximazed
    if (k != Keys.Down)
    {
      WAWindows.ShowWindow(window, (int)WAWindows.WindowShowStyle.ShowMaximized);

      // Place Window on left or right
      if (k != Keys.Up)
      {
        WAWindows.Rect rect, rectDesktop;
        if (WAWindows.GetWindowRect(window, out rect) && WAWindows.GetWindowRect(WAWindows.GetDesktopWindow(), out rectDesktop))
        {
          WAWindows.SetWindowPos(window, WAWindows.HwndTop, (k == Keys.Left) ? Math.Min(rect.Left, 0) : rectDesktop.Right / 2, rect.Top, Math.Min(rect.Width, rectDesktop.Right / 2 - Math.Min(rect.Left, 0)),
                 Math.Min(rect.Height, rectDesktop.Bottom), WAWindows.SwpShowwindow);
        }
      }
    }
  }
}


* This source code was highlighted with Source Code Highlighter.
И последнее, в своей программе я ввел возможность установки — необходимо ли отображать значек в трее или нет, который помогает в закрытии программы, для этого нужно установить значение в соответствующей секции app.config.
<applicationSettings>
  <VistaKeysExtender.Properties.Settings>
    <setting name="ShowNotifyIcon" serializeAs="String">
      <value>False</value>
    </setting>
  </VistaKeysExtender.Properties.Settings>
</applicationSettings>


* This source code was highlighted with Source Code Highlighter.
Мне просто сам значок не нужен, программа крутиться всегда в фоне, а место в трее итак переполнено. Функциональные клавиши я описал вверху статьи. Вопросы и предложения готов выслушать и ответить на них. Надеюсь, что кому то будет так же полезна данная программа как и мне.
UPD: Программа получила продолжение по этому адрессу http://outcoldman.habrahabr.ru/blog/57792/
Теги:
Хабы:
+9
Комментарии24

Публикации

Изменить настройки темы

Истории

Ближайшие события

PG Bootcamp 2024
Дата16 апреля
Время09:30 – 21:00
Место
МинскОнлайн
EvaConf 2024
Дата16 апреля
Время11:00 – 16:00
Место
МоскваОнлайн
Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн