Практика
Глумление над "Панелью задач"

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика


Начинающих программистов данная тема очень привлекает. Мысль о том, что над Windows можно немного поглумиться, приводит новичков в неописуемый восторг. Но, несмотря на то, что это всего-навсего баловство, подобная практика полезна, потому что начинающий программист получает навыки работы с посторонними окнами. Данный пример демонстрирует некоторые приемы, которые многим могут показаться интересными.

В этом примере мы не ограничимся скрытием "Панели задач" и изменением положения кнопки. Мы доберемся до области Tray (области, в которой некоторые программы, также как и сама Windows, размещают свои иконки), и до часов в этой области. Так как это просто демонстрационная программа, сделаем несколько допущений: панель задач расположена горизонтально (вверху или внизу экрана неважно), для большей наглядности авто скрытие желательно выключить, и последнее, но не менее важное, в области Tray нежелательно наличие анимированных иконок.

Приступаем к работе, и начинаем с объявления переменных.

var
  TaskBarFrm: TTaskBarFrm;
  Tray:        TRect; // Позиция и размер области Tray
  Clock:       TRect; // Позиция и размер часов
  Wind:        TRect; // Позиция и размер панели задач
  Btn:         TRect; // Позиция и размер кнопки на панели задач
  Window:      hWnd;  // Указатель на панель задач
  WindowBtn:   hWnd;  // Указатель на кнопку на панели задач
  WindowTray:  hWnd;  // Указатель на область Tray
  TrayClock:   hWnd;  // Указатель на часы

Окно панели задач и компоненты этого окна программа будет искать при загрузке, для чего обработаем событие OnCreate.

procedure TTaskBarFrm.FormCreate(Sender: TObject);
begin
   // Указатель на панель задач
   Window := FindWindow( 'Shell_TrayWnd', nil );
   // Указатель на кнопку
   WindowBtn := FindWindowEx( Window, 0, 'Button', nil );
   // Указатель на Tray
   WindowTray := FindWindowEx( Window, 0, 'TrayNotifyWnd', nil );
   // Указатель на часы
   TrayClock := FindWindowEx( WindowTray, 0, 'TrayClockWClass', nil );
   // Размер панели задач
   GetWindowRect( Window, Wind );
   // Размер кнопки на панели задач
   GetWindowRect( WindowBtn, Btn );
   // Размер области Tray
   GetWindowRect( WindowTray, Tray );
   // Размер часов в области Tray
   GetWindowRect( TrayClock, Clock );
   // Устанавливаем начальное и конечное значение
   // для ползунка, двигающего кнопку
   MoveButton.Min := Btn.Left;
   MoveButton.Max := Wind.Right - Btn.Right;
   // Устанавливаем начальное и конечное значение
   // для ползунка, растягивающего кнопку
   ResizeButton.Min := Btn.Right - Btn.Left;
   ResizeButton.Max := ( Btn.Right - Btn.Left ) * 3;
   // Устанавливаем начальное и конечное значение
   // для ползунка, двигающего область Tray
   MoveTray.Min := 0;
   MoveTray.Max := Tray.Left;
   MoveTray.Position := MoveTray.Max;
   // Устанавливаем начальное и конечное значение
   // для ползунка, двигающего часы<
   MoveClock.Min := 0;
   MoveClock.Max := ( Tray.Right - Tray.Left ) -
                    ( Clock.Right - Clock.Left );
   MoveClock.Position := MoveClock.Max;
end;

Если ты был внимательным, то заметил, что ползунок, отвечающий за кнопку, установлен в начальное положение, а ползунки, отвечающие за область Tray и часы, установлены в конечное положение. Это связано с тем, что кнопка расположена с левой стороны панели, и свое движение начнет в правую сторону, а Tray и часы расположены с правой стороны и свое движение начнут в противоположенном направлении.

Для поиска окна и его компонентов мы использовали функции FindWindow и FindWindowEx соответственно, их описание приведено ниже. Для того чтобы узнать положение и размеры окна, мы воспользовались функцией GetWindowRect.

function FindWindow( IpClassName: PChar; IpWindowName: PChar ): HWND;
  IpClassName - класс искомого окна
  IpWindowName - заголовок искомого окна
  Функция возвращает указатель на найденное окно,
  или 0, если окно не найдено.


function FindWindowEx( Parent: HWND; Child: HWND; 
                       ClassName: PChar, WindowName: PChar ): HWND;
  Parent - указатель на родительское окно
  Child - дочернее окно, обычно здесь ставят 0
  ClassName - класс искомого окна
  WindowName - заголовок искомого окна
  Функция возвращает указатель на найденное окно,
  или 0, если окно не найдено.


function GetWindowRect( hWnd: HWND; var IpRect: TRect ): LongBool;
  hWnd - указатель на найденное окно
  IpRect - структура типа TRect
  Функция возвращает true в случае успешного выполнения,
  или false в случае ошибки.

Для перемещения окна, воспользуемся функцией MoveWindow.

function MoveWindow( hWnd: HWND; X: integer; Y: integer; nWidth: integer;
                     nHeight: integer; bRepeint: LongBool ): LongBool;
  hWnd - указатель на окно, над которым производится действие
  X - новая координата левого верхнего угла по X
  Y - новая координата левого верхнего угла по Y
  nWidth - новая ширина окна
  nHeight - новая высота окна
  bRepeint - флаг, указывающий на необходимость перерисовки окна
  Функция возвращает true в случае успешного выполнения,
  или false в случае ошибки.

Ну а сами функции, перемещающие найденные окна, выглядят следующим образом.

// Двигаем кнопку
procedure TTaskBarFrm.MoveButtonChange(Sender: TObject);
begin
   MoveWindow( WindowBtn, MoveButton.Position-2, 0, Btn.Right - Btn.Left,
               Btn.Bottom - Btn.Top, true );
end;

// Изменяем размер кнопки
procedure TTaskBarFrm.ResizeButtonChange(Sender: TObject);
begin
   GetWindowRect( WindowBtn, Btn );
   MoveWindow( WindowBtn, Btn.Left-2, 0, ResizeButton.Position,
               Btn.Bottom - Btn.Top, true );
end;

// Двигаем Tray
procedure TTaskBarFrm.MoveTrayChange(Sender: TObject);
begin
   MoveWindow( WindowTray, MoveTray.Position-2, 0, Tray.Right - Tray.Left,
               Tray.Bottom - Tray.Top, true );
end;

// Двигаем часы по области Tray
procedure TTaskBarFrm.MoveClockChange(Sender: TObject);
begin
   MoveWindow( TrayClock, MoveClock.Position-3, 1, Clock.Right - Clock.Left,
               Clock.Bottom - Clock.Top, true );
end;

Замечание. При изменении размера кнопки под Windows XP, вместо Btn.Left-2 нужно написать Btn.Left.

Используя функции ShowWindow и EnableWindow найденное окно можно скрыть или сделать его неактивным. И последнее, чтобы при завершении работы вернуть все на место, обработаем событие OnClose.

// Закрытие формы
procedure TTaskBarFrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   MoveButton.Position := MoveButton.Min;
   ResizeButton.Position := ResizeButton.Min;
   MoveTray.Position := MoveTray.Max;
   MoveClock.Position := MoveClock.Max;
end;

Маленькое пояснение. В самом начале мы проинициализировали ползунки первоначальными координатами окна и его компонентов, и теперь перед закрытием нам достаточно вернуть ползунки в начальное состояние.

Этот небольшой пример показывает, как можно работать с посторонними окнами. На этом сегодня все. Удачи вам в программировании.

.: Пример к данной статье :.


При использовании материала - ссылка на сайт обязательна