2011-02-26 6 views
1
를 사용 MAINMENU

가능한 중복 :
Owner Drawing TMainMenu over Aero Glass Form?그리기 응용 프로그램은 델파이

안녕,

내가 응용 프로그램의 주 메뉴는 응용 프로그램의 캡션 표시 줄에 그려진 데에 관심이 있어요? iTunes 및 Songbird (Windows 7)와 비슷합니다.

힌트를 사용하면 도움이 될 것입니다. 버튼이나 패널을 그릴 수는 있지만 메뉴는 사용할 수 없습니다. 표준 Windows 메뉴를 재배치 할 수 없습니다

환호

+2

이 내용은 http://stackoverflow.com/questions/4732039/owner-drawing-tmainmenu-over-aero-glass-form과 중복 되나요? –

+0

iTunes는 주 메뉴를 비 클라이언트 영역의 상단에 그려 놓았지만 유리에 주 메뉴를 그려 놓지 않습니다. 비 클라이언트 영역에 메뉴를 그리려면 질문 제목에서 glass라는 단어를 제거하면 복제본으로 닫히지 않습니다. Songbird는 내가 볼 수있는 것에서도 유리를 지원하지 않습니다. –

+0

* 글래스 *가 워렌의 의견에 따라 수정 된 의도하지 않은 실수 였음을 분명히 밝혔 듯이, 다시 투표하기로 결정했습니다. 사실, 다른 질문에서 무엇을 묻는 지 이해하지 못합니다. –

답변

2

는 윈도우 오른쪽 캡션에서 항상 배치합니다. 실제로 "iTunes"와 "WS_CAPTION"을 검색하면 iTunes 윈도우에 WS_CAPTION 스타일이 없음을 알 수 있습니다. 나는 '송 버드'와 마찬가지로 사실 인 것으로 추측한다. 그렇다면이 응용 프로그램에서 캡션을 제거하여 캡션을 맨 위에 놓고 캡션을 시뮬레이트하는 것입니다 (표준 메뉴 및 자체 메뉴 구현이 없을 수도 있지만 그 사실을 알지 못합니다).

당신은 스타일을 제거하여 델파이 폼의 캡션을 제거 할 수 있습니다

SetWindowLong(Handle, GWL_STYLE, 
     GetWindowLong(Handle, GWL_STYLE) and not WS_CAPTION); 
    SetWindowPos(Handle, 0, 0, 0, 0, 0, 
     SWP_NOSIZE or SWP_NOMOVE or SWP_NOZORDER or SWP_FRAMECHANGED); 

그런 다음 메뉴가 (아무 캡션) 상단에 나타납니다. 그런 다음 마우스를 사용하여 창의 주위를 움직일 수있는 캡션에 있기 위해 창 상단에서 마우스 클릭을 가짜로 만듭니다. WM_NCHITTEST 메시지를 처리하여이 작업을 수행 할 수 있습니다. 그러나 메뉴 항목이 차지하는 영역을 제외해야합니다.

type 
    TForm1 = class(TForm) 
    [...] 
    private 
    procedure WmNCHitTest(var Msg: TWMNCHitTest); message WM_NCHITTEST; 
    public 

[...] 

procedure TForm1.WmNCHitTest(var Msg: TWMNCHitTest); 
var 
    Pt: TPoint; 
    MenuBarInfo: TMenuBarInfo; 
    i, MenuWidth: Integer; 
begin 
    inherited; 

    // calculate the total width of top menu items 
    MenuBarInfo.cbSize := SizeOf(MenuBarInfo); 
    MenuWidth := 0; 
    for i := 0 to MainMenu1.Items.Count - 1 do begin 
    GetMenuBarInfo(Handle, OBJID_MENU, 1, MenuBarInfo); 
    MenuWidth := MenuWidth + MenuBarInfo.rcBar.Right - MenuBarInfo.rcBar.Left; 
    end; 

    Pt := ScreenToClient(SmallPointToPoint(Msg.Pos)); 
    Pt.Y := Pt.Y + MenuBarInfo.rcBar.Bottom - MenuBarInfo.rcBar.Top; 
    if (Pt.Y <= GetSystemMetrics(SM_CYCAPTION)) and (Pt.Y >= 0) and 
     (Pt.X > MenuWidth) and (Pt.X < ClientWidth) then 
    Msg.Result := HTCAPTION; 
end; 

사용하는 Delphi 버전에 따라 GetMenuBarInfo 호출에 성공하지 못할 수도 있습니다. F.i. D2007 올바르게 TMenuBarInfo 구조를 압축 된 선언합니다. 따라서 함수를 호출하기 전에 함수와 함수를 다시 선언해야 할 수도 있습니다.

type 
    TMenuBarInfo = record 
    cbSize: DWORD; 
    rcBar: TRect; 
    hMenu: HMENU; 
    hwndMenu: HWND; 
    fBarFocused: Byte; 
    fFocused: Byte; 
    end; 

function GetMenuBarInfo(hend: HWND; idObject, idItem: ULONG; 
    var pmbi: TMenuBarInfo): BOOL; stdcall; external user32; 

마지막으로 사용자가 최소화하고 복원 할 수 있도록 맨 오른쪽에 일부 버튼을 넣을 수 있습니다.

+0

차가움. 나는 실험 할 것이고, 이것이 내가 원하는 것을 할 지 알 것이다! – Mmarquee

+0

작동합니다 - 제어 버튼을 교체하는 방법 만 알고 있다면. – Mmarquee

+0

@Mmarquee - 제어 버튼을 최소화, 닫기 등을 의미하는 경우 커서의 위치에 따라 관련 히트 테스트를 다시 반환 할 수 있습니다. 외모에 관해서는 마우스 버튼을 누르거나 누르는 것에 따라 적절한 이미지를 그릴 수 있습니다. 힌트 : 항상 질문 할 수 있습니다. :) –

관련 문제