2013-07-04 1 views
2

Delphi Xe4. 양식, ActionManager, ImageList (32x32 아이콘 포함), ActionMainMenuBar.ActionMainMenuBar with 32x32 icon

아이콘이 올바르게 표시되는지 확인할 수 없습니다. 당신은 무엇을해야합니까? 내가 장식의 VCL 스타일을 적용 할 경우 동시에

Pic1

은, 그것을 잘 표시됩니다. 그러나 기본적으로 "Windows"스타일 인 경우 텍스트가 아이콘 밖으로 이동합니다. 도움.

Pic3 나쁜 영어 죄송합니다

Pic4

Pic2

.

+2

아이콘이 너무 큽니다. 'GetSystemMetrics (SM_CXSMICON) '와 같은 크기의 정사각형 아이콘을 사용해야합니다. –

+0

TMainMenu에서 32x32의 아이콘을 사용할 수 있습니다. 그리고 그럴 수 없습니까? –

+0

나는 그것을 이해할 수 없다. –

답변

6

이것은 유효한 질문입니다. TActionMainMenuBar은 네이티브 메뉴에서 잘 처리 할 수있는 것처럼 사용자 지정 아이콘 크기를 메뉴 이미지로 처리 할 수 ​​있도록 설계되었습니다. 그 하나의 표시는 코드 f.i에있는 주석에서 찾을 수 있습니다. 아래의 VCL 코드에서 16 is standard image size so adjust for larger images이라는 주석을 찾을 수 있습니다.

결함 코드는 'ActnMenus.pas'의 TCustomMenuItem.CalcBounds에 있습니다. 아래 발췌 부분은 D2007에서 발췌 한 것입니다. 아래 느낌표에 느낌표가 표시되어 있습니다. 상위 클래스 인 TCustomActionControlCalcLayout 메소드에서 텍스트와 이미지의 위치를 ​​계산 한 후 TCustomMenuItem은 하드 코딩 된 으로 하드 디스크에 저장합니다.

procedure TCustomMenuItem.CalcBounds; 
var 
    AWidth, AHeight: Integer; 
    NewTextBounds: TRect; 
    ImageSize: TPoint; 
    ImageOffset: Integer; 
begin 
    inherited CalcBounds; 
    ImageSize := GetImageSize; 
    AHeight := FCYMenu; 
    if Separator then 
    AHeight := FCYMenu div 3 * 2 
    else 
    // 16 is standard image size so adjust for larger images 
    if ImageSize.Y > 16 then 
     AHeight := ImageSize.Y + 4; 
    if ActionClient = nil then exit; 
    if ImageSize.X <= 16 then 
    ImageOffset := 24 
    else 
    ImageOffset := ImageSize.X + 6; // Leave room for an image frame 
    NewTextBounds := TextBounds; 
    OffsetRect(NewTextBounds, 24 - TextBounds.Left,   // <- !!!!! 
    AHeight div 2 - TextBounds.Bottom div 2 - 1); 
    TextBounds := NewTextBounds; 
    ShortCutBounds := Rect(0,0,0,0); 
    if ActionClient.ShortCut <> 0 then 
    begin 
    Windows.DrawText(Canvas.Handle, PChar(ActionClient.ShortCutText), -1, 
     FShortCutBounds, DT_CALCRECT); 
    // Left offset is determined when the item is painted to make it right justified 
    FShortCutBounds.Top := TextBounds.Top; 
    FShortCutBounds.Bottom := TextBounds.Bottom; 
    AWidth := TextBounds.Right + FShortCutBounds.Right + ImageOffset + Spacing; 
    end 
    else 
    AWidth := TextBounds.Right + TextBounds.Left; 
    SetBounds(Left, Top, AWidth, AHeight); 
end; 



24 16 개 이하의 픽셀 폭을 갖는 이미지에 기초하여 가정된다. 그 대신에 몇 줄 위에 계산 된 값은 ImageOffset입니다.

OffsetRect(NewTextBounds, ImageOffset - TextBounds.Left, 
    AHeight div 2 - TextBounds.Bottom div 2 - 1); 

OffsetRect(NewTextBounds, 24 - TextBounds.Left, 
    AHeight div 2 - TextBounds.Bottom div 2 - 1); 

교체하고 당신은 다음과 같이해야합니다 :

dropped menu

당신은 이미지를 가지고 있지 항목은 아직 정착된다, 그러나 다른 불확실성을 알 수 있습니다를 작은 이미지 레이아웃. IMO 모든 메뉴 항목은 기본 레이아웃이 동일해야하지만, 동작 메뉴의 디자인은 개별 항목에 대해 다른 레이아웃을 허용합니다. 또 다른 이상한 일은 이미지가있는 항목의 상태 ('Action6')입니다. 여기에 설정이 누락되었거나 그렇지 않으면 버그로 분류 될지 확실하지는 않습니다.

+0

+1. 멋지다. :-) 동일한 하드 코딩 된 값이 XE2 및 XE4에 있습니다. –

+0

@Ken - 투표 해 주셔서 감사합니다. –

+0

Hmmmm - 여전히 Delphi 10 Seattle에도 있습니다. 뭐야? – DaveBoltman