| 
| 
 | Вопрос # 2 991/ вопрос открыт / | 
 |  Добрый день! Возникла проблема с использованием компонента меню в стиле ХР. Давно бьюсь над этой проблемой. Прошу прощения за много букв.
 В заголовках пунктов меню подчеркивается первый символ, а если заголовок начинается с того же символа, что и предыдущий, то второй. Меня это не устраивает, хотелось бы, чтобы подчеркивался или все время первый символ, или вообще подчеркивания не было. Дело в том, что меню расположено на тулбаре. Без тулбара помогает команда:
 TMainMenu.AutoHotKeys := maManual
 С тулбаром не помогает. Причем наблюдается следующее:
 если у MainMenu AutoMerge:=true не ставить (получается 2 меню: одно сверху, другое пониже на тулбаре), то происходит странная вещь: сначала пункты верхнего меню не подчеркнутые, но если сходить в меню тулбара, то они (верхние) последовательно (какой пункт посмотришь) становятся подчеркнутые (как в тулбаре).
 Что происходит? Можно ли как-нибудь нейтрализовать эффект тулбара?
 
|  |   Вопрос задал: Alenov (статус: Посетитель)Вопрос отправлен: 13 июля 2009, 16:28
 Состояние вопроса: открыт, ответов: 1.
 |  Ответ #1. Отвечает эксперт: Егор Здравствуйте, Alenov!Может я чего-то не так понял, поправьте.
 Если в свойстве Caption пункта меню есть символ &, то следующий за ним символ будет подчёркнут, т.е. если написать:
 MainMenu1.N1.Caption:="&Файл";
 то будет подчёркнута буква "Ф". Если же убрать символ &:
 MainMenu1.N1.Caption:="Файл";
 то подчёркивания не будет.
 Просто уберите ненужные символы &.
 Есть, правда, одна тонкость - если пункты меню набраны на английском, то этот подход может и не сработать (первые буквы будут подчёркиваться всё равно)
 
|  | Ответ отправил: Егор (статус: 10-ый класс)Время отправки: 13 июля 2009, 16:48
 Оценка за ответ: 4
 |  
 Мини-форум вопросаВсего сообщений: 8; последнее сообщение — 13 июля 2009, 19:25; участников в обсуждении: 3. 
|   | Alenov (статус: Посетитель), 13 июля 2009, 17:28 [#1]:Пункты на английском. Значок & не использую, подчеркивание выставляется автоматически, хотя я это и запретил. Сначала думал на компонент, но в нем ничего связанного с этой функцией нет, что подтверждается и тем, что без тулбара меню получается без подчеркиваний, а вот с тулбаром подчеркивания появляются. |  
|   | Вадим К (статус: Академик), 13 июля 2009, 17:44 [#2]:Их добавляет винда. Потому что в ней принято, что по alt+буква можно открывать меню. Это просто удобство. Есть группа людей которая это использует. Если не нравиться - пишите свое меню.
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Егор (статус: 10-ый класс), 13 июля 2009, 17:45 [#3]:Тогда только могу посоветовать явно указывать, где должно стоять подчёркивание. Среда какая? Delphi, C++, версия (6, 7, 2006...)?
 Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.— Donald E. Knuth.
 |  
|   | Alenov (статус: Посетитель), 13 июля 2009, 18:21 [#4]:Пробовал указывать явно, с тулбаром не работает. Среда Delphi 2006 |  
|   | Alenov (статус: Посетитель), 13 июля 2009, 18:41 [#5]:Правда (сейчас попробовал), если просто меню на тулбар положить, то в нем все нормально работает. Значит дело в реакции моего компонента на тулбар. Получается, если какого-то специального способа воздействовать на тулбар нет, то единственный способ - менять компонент. |  
|   | Егор (статус: 10-ый класс), 13 июля 2009, 18:46 [#6]:Что-то я не понял. Сейчас в bds 2006 сделал форму, на toolbar поместил меню. Добавил три пункта window, window2, window3. Во всех пунктах символ & отсутствует, соответственно и подчёркивания нет.
 После запуска подчёркивания также нет ни в одном пункте.
 Свойство AutoHotkeys стоит в maAutomatic.
 Вроде всё работает, как вы хотите. В чём проблема?..
 Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.— Donald E. Knuth.
 |  
|   | Alenov (статус: Посетитель), 13 июля 2009, 18:57 [#7]:Я использую сторонний компонент меню в стиле ХР - MXPMenu (о чем и написал в самом начале). Похоже проблема связана с ним, но проявляется только на тулбаре. |  
|   | Alenov (статус: Посетитель), 13 июля 2009, 19:25 [#8]:Вот листинг этого компонента, может в нем что-нибудь заметите: 
 unit MyXPMenu;
 
 interface
 
 uses
 Windows, Graphics, Controls, Classes;
 
 type
 TMXPMenu = class(TComponent)
 private
 FOwner: TComponent;
 FActive: Boolean;
 FSelectedBackColor: TColor;
 FIconBackColor: TColor;
 FSeparatorColor: TColor;
 FBackColor: TColor;
 FSelectedFontColor: TColor;
 FSelectedBorderColor: TColor;
 FFontColor: TColor;
 FCheckSignColor: TColor;
 FCheckedColor: TColor;
 FDisabledFontColor: TColor;
 FInterval: Integer;
 procedure SetActive(Value: boolean);
 protected
 procedure DrawMenuItem(Sender: TObject; ACanvas: TCanvas; ARect: TRect; State: TOwnerDrawState);
 procedure MeasureMenuItem(Sender: TObject; ACanvas: TCanvas; var Width, Height: Integer);
 public
 constructor Create(AOwner: TComponent); override;
 destructor Destroy; override;
 procedure HookDrawItemEventHandlers;
 published
 property Active: boolean read FActive Write SetActive;
 property BackColor: TColor read FBackColor Write FBackColor;
 property IconBackColor: TColor read FIconBackColor Write FIconBackColor;
 property SelectedBackColor: TColor read FSelectedBackColor Write FSelectedBackColor;
 property FontColor: TColor read FFontColor Write FFontColor;
 property SelectedFontColor: TColor read FSelectedFontColor Write FSelectedFontColor;
 property SelectedBorderColor: TColor read FSelectedBorderColor Write FSelectedBorderColor;
 property DisabledFontColor: TColor read FDisabledFontColor Write FDisabledFontColor;
 property SeparatorColor: TColor read FSeparatorColor Write FSeparatorColor;
 property CheckedColor: TColor read FCheckedColor Write FCheckedColor;
 property CheckedSignColor: TColor read FCheckSignColor Write FCheckSignColor;
 property Interval: Integer read FInterval write FInterval;
 end;
 
 procedure Register;
 
 implementation
 
 uses
 Menus;
 
 procedure Register;
 begin
 RegisterComponents('MyXPMenu', [TMXPMenu]);
 end;
 
 constructor TMXPMenu.Create;
 begin
 inherited;
 FOwner:=AOwner;
 FBackColor:=$00E1E1E1;
 FIconBackColor:=$00D1D1D1;
 FSelectedBackColor:=$00DCCFC7;
 FFontColor:=clBlack;
 FSelectedFontColor:=clNavy;
 FSelectedBorderColor:=clNavy;
 FDisabledFontColor:=clGray;
 FSeparatorColor:=$00D1D1D1;
 FCheckedColor:=clGray;
 FCheckSignColor:=$00A56D39;
 FInterval:=0;
 Active:=True;
 end;
 
 procedure TMXPMenu.SetActive(Value: boolean);
 var
 i,j: integer;
 begin
 if (FActive<>Value) then begin
 FActive:=Value;
 with FOwner do begin
 HookDrawItemEventHandlers;
 for i:=0 to ComponentCount-1 do begin
 if (Components[i] is TMenu) then
 TMenu(Components[i]).OwnerDraw:=FActive;
 if (Components[i] is TMainMenu) then begin
 with TMainMenu(Components[i]) do begin
 for j:=0 to Items.Count-1 do begin
 if Items[j].Visible then begin
 Items[j].Visible:=False;
 Items[j].Visible:=True;
 end;
 end;
 end;
 end;
 end;
 end;
 end;
 end;
 
 procedure TMXPMenu.HookDrawItemEventHandlers;
 
 procedure Hook(MenuItem: TMenuItem);
 var
 i: integer;
 begin
 if FActive then begin
 MenuItem.OnAdvancedDrawItem:=DrawMenuItem;
 MenuItem.OnMeasureItem:=MeasureMenuItem;
 end else begin
 MenuItem.OnAdvancedDrawItem:=nil;
 MenuItem.OnMeasureItem:=nil;
 end;
 for i:=0 to MenuItem.Count-1 do
 Hook(MenuItem.Items[i]);
 end;
 
 var
 i,j: integer;
 Menu: TMenu;
 begin
 with FOwner do begin
 for i:=0 to ComponentCount-1 do begin
 if (Components[i] is TMenu) then begin
 Menu:=TMenu(Components[i]);
 Menu.AutoHotkeys:=maManual;
 for j:=0 to Menu.Items.Count-1 do
 Hook(Menu.Items[j]);
 end;
 end;
 end;
 end;
 
 procedure TMXPMenu.DrawMenuItem;
 var
 Text: string;
 Bitmap: TBitmap;
 IconRect,
 TextRect,
 CheckRect: TRect;
 i,x1,x2,TextFormat: integer;
 MenuItem: TMenuItem;
 Menu: TMenu;
 begin
 MenuItem:=TMenuItem(Sender);
 Menu:=MenuItem.Parent.GetParentMenu;
 Menu.AutoHotkeys:=maManual;
 if Menu.IsRightToLeft then begin
 x1:=ARect.Right-20;
 x2:=ARect.Right;
 end else begin
 x1:=ARect.Left;
 x2:=ARect.Left+20;
 end;
 //ARect.Top:=ARect.Top+FInterval;
 //ARect.Bottom:=ARect.Bottom+FInterval; //Изменение интервала
 IconRect:=Rect(x1,ARect.Top,x2,ARect.Bottom);
 TextRect:=ARect;
 Text:=#32+MenuItem.Caption;
 Bitmap:=TBitmap.Create;
 Bitmap.Transparent:=True;
 if Assigned(MenuItem.Parent.GetParentMenu.Images) or Assigned(MenuItem.Parent.SubMenuImages) then begin
 if (MenuItem.ImageIndex<>-1) then begin
 if Assigned(MenuItem.Parent.SubMenuImages) then
 MenuItem.Parent.SubMenuImages.GetBitmap(MenuItem.ImageIndex,Bitmap)
 else
 MenuItem.Parent.GetParentMenu.Images.GetBitmap(MenuItem.ImageIndex,Bitmap)
 end;
 end;
 if Menu.IsRightToLeft then begin
 x1:=ARect.Left;
 x2:=ARect.Right-20;
 end else begin
 x1:=ARect.Left+20;
 x2:=ARect.Right;
 end;
 //ARect.Top:=ARect.Top+FInterval;
 //ARect.Bottom:=ARect.Bottom+FInterval; //Изменение интервала
 TextRect:=Rect(x1,ARect.Top,x2,ARect.Bottom);
 ACanvas.Brush.Color:=FBackColor;
 ACanvas.FillRect(TextRect);
 if (Menu is TMainMenu) then begin
 for i:=0 to MenuItem.GetParentMenu.Items.Count-1 do begin
 if (MenuItem.GetParentMenu.Items[i]=MenuItem) then begin
 ACanvas.Brush.Color:=FIconBackColor;
 ACanvas.FillRect(ARect);
 if (MenuItem.ImageIndex=-1) and (MenuItem.Bitmap.Width=0) then begin
 TextRect:=ARect;
 Break;
 end;
 end;
 end;
 end;
 ACanvas.Brush.Color:=FIconBackColor;
 ACanvas.FillRect(IconRect);
 if MenuItem.Enabled then
 ACanvas.Font.Color:=FFontColor
 else
 ACanvas.Font.Color:=FDisabledFontColor;
 if (odSelected in State) or (odHotLight in State) then begin
 ACanvas.Brush.Style:=bsSolid;
 ACanvas.Brush.Color:=FSelectedBackColor;
 ACanvas.FillRect(TextRect);
 ACanvas.Pen.Color:=FSelectedBorderColor;  //Цвет рамки области выделения
 ACanvas.Brush.Style:=bsClear;
 ACanvas.RoundRect(TextRect.Left,TextRect.Top,TextRect.Right,TextRect.Bottom,6,6); //Углы области выделения
 if MenuItem.Enabled then
 ACanvas.Font.Color:=FSelectedFontColor;
 end;
 x1:=IconRect.Left+2;
 if MenuItem.Checked then begin    //Галочка
 ACanvas.Pen.Color:=FCheckedColor;
 ACanvas.Brush.Style:=bsClear;
 if (Bitmap.Width=0) then begin
 ACanvas.RoundRect(IconRect.Left+5,IconRect.Top+5,IconRect.Right-5,IconRect.Bottom-5,3,3);
 CopyRect(CheckRect,IconRect);
 InflateRect(CheckRect,-7,-7);
 ACanvas.Brush.Color:=FCheckSignColor;
 ACanvas.FillRect(CheckRect);
 end else begin
 ACanvas.Brush.Color:=FCheckSignColor;
 ACanvas.RoundRect(IconRect.Left,IconRect.Top,IconRect.Right,IconRect.Bottom,3,3);
 end;
 end;
 if Assigned(Bitmap) then
 ACanvas.Draw(x1,IconRect.Top+1,Bitmap);
 if not MenuItem.IsLine then begin
 SetBkMode(ACanvas.Handle,TRANSPARENT);
 ACanvas.Font.Name:='Tahoma';
 ACanvas.Font.Style:=[];
 if Menu.IsRightToLeft then
 ACanvas.Font.Charset:=ARABIC_CHARSET;
 if Menu.IsRightToLeft then
 TextFormat:=DT_RIGHT+DT_RTLREADING
 else
 TextFormat:=0;
 if MenuItem.Default then
 ACanvas.Font.Style:=ACanvas.Font.Style+[fsBold];
 inc(TextRect.Left,2);
 inc(TextRect.Top,FInterval); //Возможно, здесь опускается текст
 DrawTextEx(ACanvas.Handle,PChar(Text),Length(Text),TextRect,TextFormat,nil);
 Text:=ShortCutToText(MenuItem.ShortCut)+' ';
 if Menu.IsRightToLeft then
 TextFormat:=DT_LEFT
 else
 TextFormat:=DT_RIGHT;
 DrawTextEx(ACanvas.Handle,PChar(Text),Length(Text),TextRect,TextFormat,nil);
 end else begin
 ACanvas.Pen.Color:=FSeparatorColor;  //Сепаратор
 ACanvas.MoveTo(ARect.Left+10,TextRect.Top+Round((TextRect.Bottom-TextRect.Top)/2));
 ACanvas.LineTo(ARect.Right-2,TextRect.Top+Round((TextRect.Bottom-TextRect.Top)/2));
 end;
 Bitmap.Free;
 Menu.AutoHotkeys:=maManual;
 end;
 
 destructor TMXPMenu.Destroy;
 begin
 Active:=False;
 inherited;
 end;
 
 procedure TMXPMenu.MeasureMenuItem(Sender: TObject; ACanvas: TCanvas;
 var Width, Height: Integer);
 begin
 end;
 
 end.
 |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |