![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Прошу обратить внимание всем, кто работает с ActionMainMenuBar [WinXP]
Aleksandr. © (2005-08-25 02:33:00)В Делфи 2005 сначала с радостью убедился, что Борланды исправили наконец баг с необновлением кнопочек Minimize/Restore/Close на ActionMainMenuBar при закрытии максимизированного дочернего окна. А потом вдруг заметил странную вещь - как только максимизируешь в программе дочернее окно, прога начинает выедать все ресурсы процессора. Долго грешил на свой код, день убил на проверку всех OnUpdate для экшнов, WndProc и repaint, пока не обратил внимание именно на связь занятости процессора с наличием этих кнопочек.
А корень оказался в вот этом коде в модуле ActnMenus:
,
procedure TCustomActionMainMenuBar.MDIChildMaximized(ChildForm: TCustomForm);
function SetupMDIButton(Style: TMDIButtonStyle): TCustomMDIMenuButton;
begin
Result := TCustomMDIMenuButton.Create(Self);
with Result do
begin
Visible := False;
Parent := Self;
Top := Self.VertMargin + 1;
Width := GetSystemMetrics(SM_CXMENUSIZE);
Height := GetSystemMetrics(SM_CYMENUSIZE);
ButtonStyle := Style;
Action := TInternalMDIAction.Create(Self);
case Orientation of
boLeftToRight:
begin
Anchors := [akTop, akRight];
case ButtonStyle of
mbMinimize: Left := Self.Width - Width * 3 - VertMargin - 1;
mbRestore: Left := Self.Width - Width * 2 - VertMargin - 1;
mbClose: Left := Self.Width - Width - VertMargin - 1;
end;
end;
boRightToLeft:
case ButtonStyle of
mbMinimize: Left := Width * 2 + VertMargin + 1;
mbRestore: Left := Width + VertMargin + 1;
mbClose: Left := 0 + VertMargin + 1;
end;
end;
with Action as TInternalMDIAction do
case ButtonStyle of
mbMinimize: MDIAction := maMinimize;
mbRestore: MDIAction := maRestore;
mbClose: MDIAction := maClose;
end;
end;
Visible := True;
end;
begin
if csDestroying in ChildForm.ComponentState then exit;
if not Assigned(FRestoreBtn) then
begin
FMinimizeBtn := SetupMDIButton(mbMinimize);
FRestoreBtn := SetupMDIButton(mbRestore);
FCloseBtn := SetupMDIButton(mbClose);
end;
TInternalMDIAction(FMinimizeBtn.Action).Form := ChildForm;
TInternalMDIAction(FRestoreBtn.Action).Form := ChildForm;
TInternalMDIAction(FCloseBtn.Action).Form := ChildForm;
Invalidate;
end;
точнее, в последней строчке Invalidate, которая там, по крайней мере, вне условия, ИМХО нафиг не нужна. Да и три предыдущие тоже. По крайней мере, у меня все стало работать без загрузки процессора и появления багов как в варианте, когда все четыре строчки были убраны внутрь операторных скобок условия, так и в варианте, когда Invalidate было закомментировано.
Проверьте у себя, кому не лень?
ЗЫ. Кстати, борландам как-то об этом глюке сообщить можно?
гвест (2005-08-26 17:52:00) [1]Неофициальное обновление исправляло одни и добавляло другие баги. Вывод такой, что этот бар лучше вообще не использовать, а скажем юзать toolbar2000 или бар от DevExpress.
Aleksandr. (2005-08-26 17:07:00) [2]На новый код не похоже - я в Д7 тоже уже копался во всем этом, стиль довольно похож - те же впечатления, что писал студент-практикант...
REA (2005-08-26 17:02:00) [3]Эти куски вообще криво сделаны и многое в D7 лечилось неофициальным обновлением. Попало ли оно в D2005 или это другая ветвь эволюции неизвестно...
Aleksandr. (2005-08-26 16:59:00) [4]В дополнение - проверка показала, что строчки
TInternalMDIAction(FMinimizeBtn.Action).Form := ChildForm;
TInternalMDIAction(FRestoreBtn.Action).Form := ChildForm;
TInternalMDIAction(FCloseBtn.Action).Form := ChildForm;
стоит оставить вне операторных скобок - иначе конкретно в винде 2003 любое нажатие на кнопки приведет к AV.