Programmieren mit C++

Visual C++

Systemnahe Lösungen mit VC++

Logo zwischen Fenstertitel und Menü

Wie kann man ähnlich dem RealPlayer ein Logo zwischen Fenstertitel und Menü platzieren?

Frage

Die Applikation RealPlayer fügt ihr Logo zwischen der Titelzeile und der Menüzeile ein.

Abbildung 5/2.6.3.18-1: Logo zwischen Fenstertitel und Menü

Der Effekt kann in SDI- wie auch MDI-Anwendungen integ-riert werden. Nachfolgend wird die grundlegende Vorgehensweise anhand einer Dialog-basierten Anwendung aufgezeigt.

Lösung

Das Logo wird in Form einer Bitmap-Ressource in das Projekt eingebunden. Um Platz für das Bild zu schaffen, wird ein Dummy-Eintrag im Menü an der ersten Position eingefügt. Durch Implementieren der Methode OnMeasureItem() kann die Anwendung selbst ermitteln, wie groß der Platzbedarf für die Bitmap ist, so dass ein entsprechend großer Bereich für das Logo reserviert werden kann.

void CLogoDlg::OnMeasureItem(int nIDCtl, 
LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
{
 if (lpMeasureItemStruct->CtlType == ODT_MENU)
 {
  if (lpMeasureItemStruct->itemID == IDM_IMAGE)
   lpMeasureItemStruct->itemWidth = m_rectLogo.Width() + 5;
 }
 
 CDialog::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}

In der Methode OnInitDialog (für die Dialog-basierte Anwendung) ist der nachfolgende Code einzufügen, um die Logo-Bitmap zu laden.

m_hBmp = (HBITMAP)LoadImage(AfxGetInstanceHandle(), 
                            MAKEINTRESOURCE(IDB_Logo), 
                            IMAGE_BITMAP, 0, 0, 
                            LR_CREATEDIBSECTION);
 
BITMAP bm;
GetObject(m_hBmp, sizeof(bm), &bm); 
 
m_rectLogo.left   = 15;
m_rectLogo.right  = 15 + bm.bmWidth;
m_rectLogo.top    = 2 ;
m_rectLogo.bottom = 2 + bm.bmHeight;

Die Methode DrawLogo() zeichnet das Logo über einen simplen BitBlt()-Aufruf an der gewünschten Position, deren linke obere Ecke mit (15, 2) vorgegeben wird.

void CLogoDlg::DrawLogo()
{
 CDC* pdc= GetWindowDC();
 
 CDC memdc; 
 memdc.CreateCompatibleDC(pdc); 
 memdc.SelectObject(m_hBmp); 
 
 pdc->BitBlt(15, 2, m_rectLogo.Width(),m_rectLogo.Height(), 
             &memdc, 0, 0, SRCCOPY); 
 
 ReleaseDC(pdc); 
}

Um zu verhindern, dass die Methode OnInitMenu() im Fens-ter eine Linie zwischen TitleBar und MenuBar zeichnet, muss diese Methode überschrieben werden, so dass DrawLogo() ausgeführt wird.

Bitmap-Ressource

void CLogoDlg::OnInitMenu(CMenu* pMenu) 
{
 CDialog::OnInitMenu(pMenu);
 
 DrawLogo();
}

Analog dazu wird die Methode OnSysMenu() überschrieben. Ebenso muss OnSysCommand() überschrieben werden, um das Logo zu zeichnen und – hier als Beispiel – einen About-Dialog anzuzeigen. Dazu testet die Methode als erstes auf das Anliegen des entsprechenden Events und erzeugt ggfs. den modalen About-Dialog.

Methode OnInitMenu

void CLogoDlg::OnSysCommand(
   UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }

Für alle übrigen Aktionen zeichnet die Methode das Logo über DrawLogo(), da die System-Routinen zum Update des Fensters natürlich das Default-Aussehen reproduzieren.

 else
 {
  DrawLogo();
 
  CDialog::OnSysCommand(nID, lParam);
 }
}

Zu guter Letzt ist noch die Methode OnNcPaint() zu überschreiben, da auch für die Nicht-Client-Bereiche das Logo korrekt gezeichnet werden soll, anstelle der Default-Ausgaben.

Methode OnSysCommand

void CLogoDlg::OnNcPaint() 
{
 // Default a la CDialog::OnNcPaint() 
 Default();
 
 DrawLogo();
}

Methode OnNcPaint





Sachgebiet


© 2009-2012 by Alojado Publishing. Alle Rechte vorbehalten. Ausgewiesene Marken gehören ihren jeweiligen Eigentümern.
Mit der Benutzung dieser Seite erkennen Sie die Nutzungsbedingungen und die Datenschutzerklärung an. Der Betreiber übernimmt keine Haftung für den Inhalt verlinkter externer Internetseiten.
Seite erzeugt 2012-05-20 02:31:58 von textarchiv.alojado.de