|
Вопрос # 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.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|