Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Как изменить стиль PROGRESSBAR после создания


Автор: mes 16.1.2006, 02:32
Здравствуйте.
У меня сложилась следующая ситуация :

Если при создании PROGRESSBAR устанавливаю стили, то потом эти стили визуально отображаются:

Код

wClass.lpszClassName  := Progress_Class;
wClass.Style := ws_visible or ws_child or pbs_Vertical or pbs_Smooth;
Handle := CreateWindowEx (wClass);


Если же я хочу установить эти стили после создания, то никакой реакции нету.
Т.е флаг стиля устанавливается, но визуально PROGRESSBAR остаётся прежним.

Код

  NewStyle := GetWindowLong (Handle, GWL_Style) or pbs_Smooth or ws_child or ws_visible;
  SetWindowLong (Handle, GWL_Style, NewStyle);

Может кто сталкивался, подскажите, пожалуйста, как заставить PROGRESSBAR "принять" новый стиль?

Автор: Girder 16.1.2006, 12:10
Тебе надо включить XP стили(XPMan в uses добавь). А для прогресс бара сбросить его SetWindowTheme(PB.Handle,'',''); . И только в ентом случаи у тебя будут работать енти стили в XP.

Автор: mes 16.1.2006, 14:06
Спасибо за совет. Попробовал, пока ничего не получилось, smile
точнее при вызове ф-ции пропрамма прерывается из-за критической ошибки. smile

Буду пробовать еще , однако смущает один момент:
Эти стили у меня работают, только стиль установленый при создании потом я не могу сменить.

Делаю я это с ф-цией:



Код

 NewStyle := GetWindowLong (Handle, GWL_Style) or pbs_Smooth;
                 SetWindowLong (Handle, GWL_Style, NewStyle);


Попробовал с флагом ws_Visible. Всё работает корректно.
т.е не работает изменение именно флагов : pbs_Smooth , pbs_Vertical.


Автор: Girder 16.1.2006, 14:36
Цитата(mes @ 16.1.2006, 14:06 Найти цитируемый пост)

Спасибо за совет. Попробовал, пока ничего не получилось,

Значит не так пробывал.
Вот пример:
Код
program Project1;
                  
uses windows, messages, CommCtrl, XPMan;

{$R *.res}

var   wc_pb : TWndClassEx;
      MainWnd, PB : HWND;
      Mesg : TMsg;
      //Конечно так лудше не делать... грузи динамически!
      function SetWindowTheme(hwnd: HWND; pszSubAppName: LPCWSTR; pszSubIdList: LPCWSTR): HRESULT; stdcall; external 'uxtheme.dll';

function WindowProc(wnd:HWND; Msg : Integer; Wparam:Wparam; Lparam:Lparam):Lresult; stdcall;
begin
 if msg=wm_destroy then
  begin
   postquitmessage(0); 
   Result:=0;
  end else Result:=DefWindowProc(wnd,msg,wparam,lparam);
end;

function InitCommonControl(CC: Integer): Boolean;
var
  ICC: TInitCommonControlsEx;
begin
  ICC.dwSize := SizeOf(TInitCommonControlsEx);
  ICC.dwICC := CC;
  Result := InitCommonControlsEx(ICC);
  if not Result then InitCommonControls;
end;

begin
 with wc_pb do
  begin
   cbSize:=sizeof(wc_pb);
   style:=cs_hredraw or cs_vredraw;
   lpfnWndProc:=@WindowProc;
   cbClsExtra:=0;
   cbWndExtra:=0;
   hInstance:=HInstance;
   hIcon:=LoadIcon(0,idi_application);
   hCursor:=LoadCursor(0,idc_arrow);
   hbrBackground:=COLOR_BTNFACE+1;
   lpszMenuName:=nil;
   lpszClassName:='XPProgress_Bar';
  end;

RegisterClassEx(wc_pb);

MainWnd:=CreateWindow('XPProgress_Bar','Progress_Bar',ws_overlappedwindow,100,100,500,300,0,0,Hinstance,nil);

InitCommonControl(ICC_PROGRESS_CLASS);

PB:=CreateWindowEx(0, PROGRESS_CLASS, '', WS_CHILD or WS_VISIBLE, 3, 18, 220, 50, MainWnd, 0, hInstance, nil);

SendMessage(PB, PBM_SETRANGE, 0, MAKELPARAM(0,100));

SendMessage(PB, PBM_SETPOS, 50, 0);

SetWindowTheme(PB,'','');

SetWindowLong (PB, GWL_Style, WS_CHILD or WS_VISIBLE or 1); //pbs_Smooth=1

SendMessage(PB, PBM_SETPOS, 50, 0);

ShowWindow(MainWnd,CmdShow);
ShowWindow(PB,CmdShow);

While GetMessage(Mesg,0,0,0) do
 begin
  TranslateMessage(Mesg);
  DispatchMessage(Mesg);
 end;

end.

Автор: mes 16.1.2006, 15:18
Спасибо. Твой код работает. Будем иследовать smile
Только вот размер файла значительно увеличивается.
Но это уже мелочи.

Автор: mes 16.1.2006, 19:40
Кстати нашел интерсную особеность, может кому пригодится:
если пишите на WINAPI c XP-стилями и не хотите чтоб размер файла сильно увеличивался
добавьте вместо uses XPMAN ,строчку {$R WindowsXP.res} ( всего 1Кбайт!)


Надеюсь кому-нибудь это поможет.

Автор: mes 16.1.2006, 20:03
После изучения кода всё же главный вопрос остался нерешеным.

Наблюдения:

1) Если я подключаю XP-стили то при изменинии флага pbs_Vertical, ProgressBar визуально меняется.

2) Ф-ция SetWindowTheme(PB,'','') сбрасывает темы однако реакция на флаг от неё не зависит.

Вопрос:

Неужели нельзя добиться реакции на флаг pbs_Vertical , не подлючая
эти стили, ведь при создании она воспринимает же этот флаг.

Автор: Girder 17.1.2006, 04:09
Цитата(mes @ 16.1.2006, 20:03 Найти цитируемый пост)

2) Ф-ция SetWindowTheme(PB,'','') сбрасывает темы однако реакция на флаг от неё не зависит.
Если не сбросиш... то и работать изменение флагов не будет.

Цитата(mes @ 16.1.2006, 20:03 Найти цитируемый пост)

Неужели нельзя добиться реакции на флаг pbs_Vertical , не подлючая
эти стили, ведь при создании она воспринимает же этот флаг.
В XP только так... см. выше.
Добавлено @ 04:10
Хотя... можеш в "классику" переключиться... там работать должно

Автор: mes 17.1.2006, 10:39
Цитата(Girder @ 17.1.2006, 04:09 Найти цитируемый пост)

Цитата(mes @ 16.1.2006, 20:03 )

2) Ф-ция SetWindowTheme(PB,'','') сбрасывает темы однако реакция на флаг от неё не зависит.


Если не сбросиш... то и работать изменение флагов не будет.

Ты удивишься, но изменение флагов происходит не от вышеназваной ф-ции.
Как только я подключаю файл WindowsXp.res, ProgressBar начинает реагировать на флаги
(на флаг pbs_Smooth он не реагирует так как у XP-Progressbar нет такого стиля)

ф-ция SetWindowTheme приводит только к изменению темы.
Ho Если я не подключу WindowsXP.res, то от сброса темы ничего не зависит.
Ho в Windows 98 как то же работают эти стили!?

Чтоб не углубляться я перефразирую свой вопрос.
Если программа составлена для Windows98 и в ней используется
изменение стиля после его создания,то эта программа будет
некоректно работать в среде XP?
Можно ли указать программе что она предназначена для 98
чтоб стили коректно раболи в XP?.


Автор: mes 17.1.2006, 12:23
Цитата(Girder @ 17.1.2006, 04:09 Найти цитируемый пост)

Хотя... можеш в "классику" переключиться... там работать должно


А как это сделать?

Автор: Girder 18.1.2006, 10:29
Цитата(mes @ 17.1.2006, 10:39 Найти цитируемый пост)

Ты удивишься, но изменение флагов происходит не от вышеназваной ф-ции.
Как только я подключаю файл WindowsXp.res, ProgressBar начинает реагировать на флаги
(на флаг pbs_Smooth он не реагирует так как у XP-Progressbar нет такого стиля)
У меня в WinXP+SP1 не работает без сброса.

Цитата(mes @ 17.1.2006, 10:39 Найти цитируемый пост)

Можно ли указать программе что она предназначена для 98
чтоб стили коректно раболи в XP?.
А нафиг?

Должно работать как в W98... так и XP:
1. подключай WindowsXP.res
2. Динамически грузи uxtheme.dll
3. Если загрузилась... то сбрасывай(SetWindowTheme) для прогрессбара(можеш для всех элементов сбросить... что бы не отличался внешний вид). Если не загрузилась или не нашлась функциия SetWindowTheme(Ну мало... ли что smile )... все равно переходи к 4 пункту.
4. Изменяй флаги... через SetWindowLong

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)