[MFC] Cum punem o imagine in bara de menu?

Despre MFC, ATL si alte biblioteci C++ de la Microsoft (forum moderat)
Post Reply
User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

[MFC] Cum punem o imagine in bara de menu?

Post by Ovidiu Cucu » 02 Aug 2011, 11:13

Intrebare
Cum punem o imagine in bara de menu a unei aplicatii SDI, MDI sau dialog-based?
Menubar with logo.jpg
Menubar with logo.jpg (13.87 KiB) Viewed 2731 times
Raspuns
O metoda simpla ar fi adaugarea unui item cu stilul MF_BITMAP. Totusi, o metoda mai flexibila in ce priveste pozitionarea si dimensionarea imaginii este sa folosim un item ownerdrawn (cu stilul MF_OWNERDRAW).
  • In editorul de resurse, adaugam un item sa-i zicem ID_LOGO.
  • Scriem o functie care sa faca item-ul ownerdrawn.

    Code: Select all

    void CMainFrame::_ModifyMenu()
    {
       CMenu* pMenu = GetMenu();
       ASSERT(NULL != pMenu);
       VERIFY(pMenu->ModifyMenu(ID_LOGO, MF_BYCOMMAND|MF_OWNERDRAW, ID_LOGO));
    }
  • In clasa ferestrei care contine meniul tratam mesajul WM_DRAWITEM.

    Code: Select all

    void CMainFrame::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDIS) 
    {
       switch(lpDIS->CtlType)
       {
       case ODT_MENU:
          _DrawMenuImage(lpDIS->hDC, lpDIS->rcItem);
          break;
       // ...
       }
    	
       CFrameWnd::OnDrawItem(nIDCtl, lpDIS);
    }
  • Implementam functia de desenare. In exemplu de mai jos, imaginea se deseneaza in partea din dreapta a barei de menu.
    Exemplu

    Code: Select all

    void CMainFrame::_DrawMenuImage(HDC hDC, const RECT& rcItem)
    {
       // window and memory DC for drawing
       CDC* pDC = CDC::FromHandle(hDC);
       CDC dcMem;
       dcMem.CreateCompatibleDC(pDC);
    
       // load bitmap image and select it in the memory DC
       CBitmap bmpImage;
       bmpImage.LoadBitmap(IDB_LOGO);
       CBitmap* pOldBitmap = (CBitmap*)dcMem.SelectObject(&bmpImage);
    
       // get the bitmap size
       BITMAP bmp;
       bmpImage.GetBitmap(&bmp);
       const int nBmpWidth = bmp.bmWidth;
       const int nBmpHeight = bmp.bmHeight;
    
       // calculate drawing image size and position
       const int nImgHeight = rcItem.bottom - rcItem.top;
       const int nImgWidth = (int)(((double)nImgHeight / nBmpHeight) * nBmpWidth);
       CRect rcClient;
       GetClientRect(rcClient);
       int nImgXPos = rcClient.Width() - nImgWidth;
       const int nImgYPos = rcItem.top;
    
       // special case for maximized MDI child frames
       if(this->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd)))
       {
          BOOL bMaximized = FALSE;
          ((CMDIFrameWnd*)this)->MDIGetActive(&bMaximized);
          if(bMaximized)
          {
             const int nXButton = ::GetSystemMetrics(SM_CXSMSIZE);
             nImgXPos -= 4 * nXButton + 1;
          }
       }
    
       // blit the bitmap in the window DC 
       const int nOldMode = pDC->SetStretchBltMode(HALFTONE);
       pDC->StretchBlt(nImgXPos, nImgYPos, nImgWidth, nImgHeight, 
          &dcMem, 0, 0, nBmpWidth, nBmpHeight, SRCCOPY);
    
       // restore DC and free GDI objects
       pDC->SetStretchBltMode(nOldMode);
       dcMem.SelectObject(pOldBitmap);
    }
  • In fine, apelam functia _ModifyMenu. Pentru o aplicatie SDI se poate face in CMainFrame::OnCreate iar la una dialog-based in OnInitDialog.

    Code: Select all

    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
       // ...
       _ModifyMenu();
       return 0;
    }

    Code: Select all

    BOOL CMainDialog::OnInitDialog()
    {
       // ...
       _ModifyMenu();
       return TRUE;
    };
    Intr-o aplicatie MDI e putin mai complicat, pentru ca meniurile se incarca dinamic in functie de documentul activ. Un loc de unde s-ar putea apela _ModifyMenu este in functia virtuala OnUpdateFrameTitle.

    Code: Select all

    void CMainFrame::OnUpdateFrameTitle(BOOL bAddToTitle)
    {
       _ModifyMenu();
       CMDIFrameWnd::OnUpdateFrameTitle(bAddToTitle);
    }


Vezi si << Back to MFC index



Post Reply