📄 menus.pas
字号:
begin
Dec(GlyphRect.Right);
Dec(GlyphRect.Bottom);
end;
end
else
begin
if (ImageList <> nil) and not TopLevel then
begin
GlyphRect.Right := GlyphRect.Left + ImageList.Width;
GlyphRect.Bottom := GlyphRect.Top + ImageList.Height;
end
else
begin
GlyphRect.Right := GlyphRect.Left;
GlyphRect.Bottom := GlyphRect.Top;
end;
DrawGlyph := False;
end;
end;
with GlyphRect do
begin
Dec(Left);
Dec(Top);
Inc(Right, 2);
Inc(Bottom, 2);
end;
if Checked or Selected and DrawGlyph then
if not WinXP then
DrawEdge(Handle, GlyphRect, EdgeStyle[Checked], BF_RECT);
if Selected then
begin
if DrawGlyph then ARect.Left := GlyphRect.Right + 1;
if not (Win98Plus and TopLevel) then
Brush.Color := clHighlight;
FillRect(ARect);
end;
if TopLevel and Win98Plus and not WinXP then
begin
if Selected then
DrawEdge(Handle, ARect, BDR_SUNKENOUTER, BF_RECT)
else if odHotLight in State then
DrawEdge(Handle, ARect, BDR_RAISEDINNER, BF_RECT);
if not Selected then
OffsetRect(ARect, 0, -1);
end;
if not (Selected and DrawGlyph) then
ARect.Left := GlyphRect.Right + 1;
Inc(ARect.Left, 2);
Dec(ARect.Right, 1);
DrawStyle := DT_EXPANDTABS or DT_SINGLELINE or Alignments[Alignment];
if Win2K and (odNoAccel in State) then
DrawStyle := DrawStyle or DT_HIDEPREFIX;
{ Calculate vertical layout }
SaveRect := ARect;
if odDefault in State then
Font.Style := [fsBold];
DoDrawText(ACanvas, Caption, ARect, Selected, DrawStyle or DT_CALCRECT or DT_NOCLIP);
OffsetRect(ARect, 0, ((SaveRect.Bottom - SaveRect.Top) - (ARect.Bottom - ARect.Top)) div 2);
if TopLevel and Selected and Win98Plus and not WinXP then
OffsetRect(ARect, 1, 0);
DoDrawText(ACanvas, Caption, ARect, Selected, DrawStyle);
if (ShortCut <> 0) and not TopLevel then
begin
ARect.Left := ARect.Right;
ARect.Right := SaveRect.Right - 10;
DoDrawText(ACanvas, ShortCutToText(ShortCut), ARect, Selected, DT_RIGHT);
end;
end;
end;
procedure BiDiDraw;
var
S: string;
begin
with ACanvas do
begin
if WinXP then
begin
if (odSelected in State) or (odHotLight in State) then
begin
Brush.Color := clMenuHighlight;
Font.Color := clHighlightText;
end
else if TopLevel then
Brush.Color := clMenuBar
end;
//ImageList := GetImageList;
{ With XP, we need to always fill in the rect, even when selected }
if not Selected or (WinXP and not Checked) then
FillRect(ARect);
if ParentMenu is TMenu then
Alignment := paLeft
else if ParentMenu is TPopupMenu then
Alignment := TPopupMenu(ParentMenu).Alignment
else
Alignment := paLeft;
GlyphRect.Right := ARect.Right - 1;
GlyphRect.Top := ARect.Top + 1;
if Caption = cLineCaption then
begin
FillRect(ARect);
GlyphRect.Left := GlyphRect.Right + 2;
GlyphRect.Right := 0;
DrawGlyph := False;
end
else
begin
DrawImage := (ImageList <> nil) and ((ImageIndex > -1) and
(ImageIndex < ImageList. Count) or Checked and ((FBitmap = nil) or
FBitmap. Empty));
if DrawImage or Assigned(FBitmap) and not FBitmap. Empty then
begin
DrawGlyph := True;
if DrawImage then
begin
GlyphRect.Left := GlyphRect.Right - ImageList.Width;
GlyphRect.Bottom := GlyphRect.Top + ImageList.Height;
end
else
begin
{ Need to add BitmapWidth/Height properties for TMenuItem if we're to
support them. Right now let's hardcode them to 16x16. }
GlyphRect.Left := GlyphRect.Right - 16;
GlyphRect.Bottom := GlyphRect.Top + 16;
end;
{ Draw background pattern brush if selected }
if Checked then
begin
Dec(GlyphRect.Left);
Inc(GlyphRect.Bottom);
OldBrushColor := Brush.Color;
if not (odSelected in State) then
begin
OldBrushColor := Brush.Color;
Brush.Bitmap := AllocPatternBitmap(clBtnFace, clBtnHighlight);
FillRect(GlyphRect);
end
else
begin
Brush.Color := clBtnFace;
FillRect(GlyphRect);
end;
Brush.Color := OldBrushColor;
Dec(GlyphRect.Right);
Inc(GlyphRect.Top);
end;
if DrawImage then
begin
if (ImageIndex > -1) and (ImageIndex < ImageList.Count) then
ImageList.Draw(ACanvas, GlyphRect.Left, GlyphRect.Top, ImageIndex,
Enabled)
else
begin
{ Draw a menu check }
Glyph := TBitmap.Create;
try
Glyph.Transparent := True;
Glyph.Handle := LoadBitmap(0, PChar(OBM_CHECK));
OldBrushColor := Font.Color;
Font.Color := clBtnText;
Draw(GlyphRect.Left + (GlyphRect.Right - GlyphRect.Left - Glyph.Width) div 2 + 1,
GlyphRect.Top + (GlyphRect.Bottom - GlyphRect.Top - Glyph.Height) div 2 + 1, Glyph);
Font.Color := OldBrushColor;
finally
Glyph.Free;
end;
end;
end
else
begin
SaveRect := GlyphRect;
{ Make sure image is within glyph bounds }
if FBitmap.Width < GlyphRect.Right - GlyphRect.Left then
with GlyphRect do
begin
Right := Right - ((Right - Left) - FBitmap.Width) div 2 + 1;
Left := Right - FBitmap.Width;
end;
if FBitmap.Height < GlyphRect.Bottom - GlyphRect.Top then
with GlyphRect do
begin
Top := Top + ((Bottom - Top) - FBitmap.Height) div 2 + 1;
Bottom := Top + FBitmap.Height;
end;
StretchDraw(GlyphRect, FBitmap);
GlyphRect := SaveRect;
end;
if Checked then
begin
Dec(GlyphRect.Right);
Dec(GlyphRect.Bottom);
end;
end
else
begin
if (ImageList <> nil) and not TopLevel then
begin
GlyphRect.Left := GlyphRect.Right - ImageList.Width;
GlyphRect.Bottom := GlyphRect.Top + ImageList.Height;
end
else
begin
GlyphRect.Left := GlyphRect.Right;
GlyphRect.Bottom := GlyphRect.Top;
end;
DrawGlyph := False;
end;
end;
with GlyphRect do
begin
Dec(Left);
Dec(Top);
Inc(Right, 2);
Inc(Bottom, 2);
end;
if Checked or Selected and DrawGlyph and not WinXP then
DrawEdge(Handle, GlyphRect, EdgeStyle[Checked], BF_RECT);
if Selected then
begin
if DrawGlyph then ARect.Right := GlyphRect.Left - 1;
if not (Win98Plus and TopLevel) then
Brush.Color := clHighlight;
FillRect(ARect);
end;
if TopLevel and Win98Plus and not WinXP then
begin
if Selected then
DrawEdge(Handle, ARect, BDR_SUNKENOUTER, BF_RECT)
else if odHotLight in State then
DrawEdge(Handle, ARect, BDR_RAISEDINNER, BF_RECT);
if not Selected then
OffsetRect(ARect, 0, -1);
end;
if not (Selected and DrawGlyph) then
ARect.Right := GlyphRect.Left - 1;
Inc(ARect.Left, 2);
Dec(ARect.Right, 1);
DrawStyle := DT_EXPANDTABS or DT_SINGLELINE or Alignments[Alignment];
if Win2K and (odNoAccel in State) then
DrawStyle := DrawStyle or DT_HIDEPREFIX;
{ Calculate vertical layout }
SaveRect := ARect;
if odDefault in State then
Font.Style := [fsBold];
DoDrawText(ACanvas, Caption, ARect, Selected, DrawStyle or DT_CALCRECT or DT_NOCLIP);
{ the DT_CALCRECT does not take into account alignment }
ARect.Left := SaveRect.Left;
ARect.Right := SaveRect.Right;
OffsetRect(ARect, 0, ((SaveRect.Bottom - SaveRect.Top) - (ARect.Bottom - ARect.Top)) div 2);
if TopLevel and Selected and Win98Plus then
OffsetRect(ARect, 1, 0);
DoDrawText(ACanvas, Caption, ARect, Selected, DrawStyle);
if (ShortCut <> 0) and not TopLevel then
begin
S := ShortCutToText(ShortCut);
ARect.Left := 10;
ARect.Right := ARect.Left + ACanvas.TextWidth(S);
DoDrawText(ACanvas, S, ARect, Selected, DT_RIGHT);
end;
end;
end;
begin
ParentMenu := GetParentMenu;
ImageList := GetImageList;
Selected := odSelected in State;
Win98Plus := (Win32MajorVersion > 4) or
((Win32MajorVersion = 4) and (Win32MinorVersion > 0));
Win2K := (Win32MajorVersion > 4) and (Win32Platform = VER_PLATFORM_WIN32_NT);
WinXP := (Win32MajorVersion >= 5) and (Win32MinorVersion >= 1);
if (ParentMenu <> nil) and (ParentMenu.OwnerDraw or (ImageList <> nil)) and
(Assigned(FOnAdvancedDrawItem) or Assigned(FOnDrawItem)) then
begin
DrawItem(ACanvas, ARect, Selected);
if Assigned(FOnAdvancedDrawItem) then
FOnAdvancedDrawItem(Self, ACanvas, ARect, State);
end else
if (ParentMenu <> nil) and (not ParentMenu.IsRightToLeft) then
NormalDraw
else
BiDiDraw;
end;
function TMenuItem.GetImageList: TCustomImageList;
var
LItem: TMenuItem;
LMenu: TMenu;
begin
Result := nil;
LItem := Parent;
while (LItem <> nil) and (LItem.SubMenuImages = nil) do
LItem := LItem.Parent;
if LItem <> nil then
Result := LItem.SubMenuImages
else
begin
LMenu := GetParentMenu;
if LMenu <> nil then
Result := LMenu.Images;
end;
end;
procedure TMenuItem.MeasureItem(ACanvas: TCanvas; var Width, Height: Integer);
const
Alignments: array[TPopupAlignment] of Word = (DT_LEFT, DT_RIGHT, DT_CENTER);
var
Alignment: TPopupAlignment;
ImageList: TCustomImageList;
ParentMenu: TMenu;
DrawGlyph: Boolean;
TopLevel: Boolean;
DrawStyle: Integer;
Text: string;
R: TRect;
procedure GetMenuSize;
var
NonClientMetrics: TNonClientMetrics;
begin
NonClientMetrics.cbSize := sizeof(NonClientMetrics);
if SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NonClientMetrics, 0) then
begin
Width := NonClientMetrics.iMenuWidth;
Height := NonClientMetrics.iMenuHeight;
end;
end;
begin
if GetParentComponent is TMainMenu then
begin
TopLevel := True;
GetMenuSize;
end
else TopLevel := False;
ParentMenu := GetParentMenu;
ImageList := GetImageList;
if Caption = cLineCaption then
begin
Height := 5;
Width := -2;
DrawGlyph := False;
end
else if Assigned(ImageList) and ((ImageIndex > -1) or not TopLevel) then
begin
Width := ImageList.Width;
if not TopLevel then
Height := ImageList.Height;
DrawGlyph := True;
end
else if Assigned(FBitmap) and not FBitmap.Empty then
begin
Width := 16;
if not TopLevel then
Height := 16;
DrawGlyph := True;
end
else
begin
Width := -7;
DrawGlyph := False;
end;
if DrawGlyph and not TopLevel then
Inc(Width, 15);
if not TopLevel then
Inc(Height, 3);
FillChar(R, SizeOf(R), 0);
if ParentMenu is TMenu then
Alignment := paLeft
else if ParentMenu is TPopupMenu then
Alignment := TPopupMenu(ParentMenu).Alignment
else
Alignment := paLeft;
if ShortCut <> 0 then
Text := Concat(Caption, ShortCutToText(ShortCut)) else
Text := Caption;
DrawStyle := Alignments[Alignment] or DT_EXPANDTABS or DT_SINGLELINE or
DT_NOCLIP or DT_CALCRECT;
DoDrawText(ACanvas, Text, R, False, DrawStyle);
Inc(Width, R.Right - R.Left + 7);
if Assigned(FOnMeasureItem) then FOnMeasureItem(Self, ACanvas, Width, Height);
end;
function TMenuItem.HasParent: Boolean;
begin
Result := True;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -