Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Как изменить стандартный цвет ProgressBar 3

Автор: Зайцев О.В.
Оформил: DeeCo

Этой небольшой заметкой я хотел бы открыть серию, в которой будут описаны маленькие хитрости, подобные сегодняшней. А сегодня я расскажу о простой задачке, которую, тем не менее, не сможет решить большинство начинающих программистов на Delphi. Речь пойдет об индикаторе процесса выполнения (Progress Bar'е) нестандартного цвета.

Казалось бы, ничего сложного в этом нет. Просто берем и меняем свойство Color у компонента. Но у компонента нет такого свойства. Вот тут-то и начинается тот самый ступор, в который часто впадают новички в Delphi.

Дело в том, что компонент TProgressBar является, по сути, просто оберткой стандартного системного компонента. Мало того, если внимательно вглядеться в текст компонента TProgressBar, который находится в модуле ComCtrls.pas, то станет понятно, что цвет индикатора вообще нигде не задается. Почему? Да очень просто - по стандартам Microsoft любой индикатор степени выполнения должен иметь цвет, описанный в системе и никакой другой.

Но отчаиваться рано. Раз мы ничего не нашли в исходном тексте компонента, а искать в исходных текстах следует сразу после обращения к помощи Delphi, то наша дорога должна лежать напрямую к сайту MSDN Library, на котором представлена исчерпывающая информация о любом аспекте любой версии Windows. На сайте MSDN Library мы нашли сообщение PBM_SETBARCOLOR, чье переведенное описание я приведу в конце.

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

Решается данная проблема просто - к компоненту TProgressBar надо добавить свойство Color и перекрыть метод, отвечающий за рисование окна. Создаем новый компонент на основе старого и смотрим в текст модуля ComCtrls.pas в поисках названия метода, который надо перекрывать. Опять задержка. Метод Paint отсутствует. Еще более внимательное изучение компонента-родителя даст нам ощущение того, что у TProgressBar вообще нет окна, хоть он и является прямым потомком класса TWinControl.

На самом деле это не так. Окно у индикатора есть, только оно создается, рисуется и сразу же уничтожается. Видимо, для экономии системных ресурсов.

Ввиду всего вышесказанного, получается, что нам надо перекрыть метод, отвечающий за создание окна компонента. Такой метод имеет стандартное имя и называется CreateWnd. Вообще, этот метод часто перекрывают, но это тема для отдельного разговора.

Итак, создав свойство Color типа TColor у нашего наследника перекрываем его метод CreateWnd следующим образом:

procedure TgsProgressBar.CreateWnd;
begin
  inherited;
  if HandleAllocated then
    SendMessage(Handle, PBM_SETBARCOLOR, 0, FColor);
end;

Собственно, почти все. Единственное место, которое требует доработки - во время присвоения нового цвета, индикатор не перерисовывается. Для этого, аналогичный код надо в писать в метод, обрабатывающий установку свойства Color (обычно, SetColor).

В общем, ничего сложного. Как я уже сказал в названии статьи хитрости действительно маленькие.

Удачи!

Сообщение PBM_SETBARCOLOR

Устанавливает цвет индикатора степени выполнения в соответствующем элементе управления.

Синтаксис

Для использования вызовите функцию SendMessage нижеследующим образом.

lResult = SendMessage(// returns LRESULT in lResult
  (HWND)hWndControl, // handle to destination control
  (UINT)PBM_SETBARCOLOR, // message ID
  (WPARAM)wParam, // = 0; not used, must be zero
  (LPARAM)lParam // = (LPARAM) (COLORREF) clrBar;
  );
Параметры

wParam

Должен быть нулем

clrBar

Ссылка COLORREF на новый цвет индикатора. Для задания стандартного системного значения используйте CLR_DEFAULT.

Возвращаемое значение

Возвращает предыдущий цвет индикатора или CLR_DEFAULT, если индикатор был нарисован цветом по-умолчанию.

Информация о сообщении

Минимальные версии DLL: comctl32.dll version 4.71 или более поздняя

Заголовочный файл: commctrl.h

Минимальная ОС: Windows 2000, Windows NT 4.0 с установленным Internet Explorer 4.0, Windows 98, Windows 95 с установленным Internet Explorer 4.0

Текст модуля gsProgressBar
//**! ----------------------------------------------------------
//**! This unit is a part of GSPackage project (Gregory Sitnin's
//**! Delphi Components Package).
//**! ----------------------------------------------------------
//**! You may use or redistribute this unit for your purposes
//**! while unit's code and this copyright notice is unchanged
//**! and exists.
//**! ----------------------------------------------------------
//**! (c) Gregory Sitnin, 2001-2002. All rights reserved.
//**! ----------------------------------------------------------

unit gsProgressBar;

{***} interface {***}

uses
  Windows, Messages, Classes, Graphics, ComCtrls;

type
  TgsProgressBar = class(TProgressBar)
  private
    { Private declarations }
    FColor: TColor;
    procedure SetColor(const Value: TColor);
  protected
    { Protected declarations }
  public
    { Public declarations }
    procedure CreateWnd; override;
  published
    { Published declarations }
    property Color: TColor read FColor write SetColor;
  end;

procedure Register;

{***} implementation {***}

procedure Register;
begin
  RegisterComponents('GSPackage', [TgsProgressBar]);
end;

{ TgsProgressBar }

procedure TgsProgressBar.CreateWnd;
begin
  inherited;
  if HandleAllocated then
    SendMessage(Handle, PBM_SETBARCOLOR, 0, FColor);
end;

procedure TgsProgressBar.SetColor(const Value: TColor);
begin
  FColor := Value;
  if HandleAllocated then
    SendMessage(Handle, PBM_SETBARCOLOR, 0, FColor);
end;

end.
Проект Delphi World © Выпуск 2002 - 2024
Автор проекта: USU Software
Вы можете выкупить этот проект.