Programmieren mit C++

Visual C++

Oberflächen

PrintPreView Kompatibilität zu VC++ 4.2

Beim Sprung von VC++ 4.2 nach 5.0 änderte sich das bis dahin übliche Verhalten des Druckvorschaufensters in MDI-Applikationen. Worauf beruht diese Änderung und wie kann man sie umgehen?

Frage

Seit VC++ 5.0 wird die Druckvorschau nicht mehr im MDI-Rahmen angezeigt, sondern sie ist ein MDI-Child. Daraus resultiert ein kleinerer Vorschaubereich, dessen Fläche nochmals verkleinert wird, wenn angedockte Toolbars verwendet werden und das Benutzerinterface während der Vorschau voll funktionsfähig ist. Die eigentliche Ursache besteht in der Berechnung der Fenstergröße. Diese ergibt sich unter V 4.2 wie folgt:

BOOL CView::DoPrintPreview(UINT nIDResource, 
                           CView* pPrintView,
                           CRuntimeClass* pPreviewViewClass,   
                           CPrintPreviewState* pState)
{
  ...
  CFrameWnd* pParent = (CFrameWnd*)AfxGetThread()->m_pMainWnd;
  ASSERT_VALID(pParent);
  ASSERT_KINDOF(CFrameWnd, pParent);
  ...
}

Für VC++ 5.0 lautet der entsprechende Code:

BOOL CView::DoPrintPreview(UINT nIDResource, 
                           CView* pPrintView,
                           CRuntimeClass* pPreviewViewClass, 
                           CPrintPreviewState* pState)
{
  ...
  CFrameWnd* pParent;
  CWnd* pNaturalParent = pPrintView->GetParentFrame();
 
  pParent = DYNAMIC_DOWNCAST(CFrameWnd, pNaturalParent);
  if (pParent == NULL || pParent->IsIconic())
    pParent = (CFrameWnd*)AfxGetThread()->m_pMainWnd;
  ...
}

Um zur alten Darstellung zurück zu gelangen, sind mehrere Schritte notwendig. Zunächst muß eine eigene DoPrintPreview() in der MDI View-Klasse implementiert werden. Im großen und ganzen ist die neue Methode eine Kopie der CView::DoPrintPreview() mit zwei Änderungen: Anstelle des MDI-Child verwendet die Methode den MDT-Rahmen.

BOOL CMDIView::DoPrintPreview(UINT nIDResource, 
                              CView* pPrintView,
                              CRuntimeClass* pPreviewViewClass, 
                              CPrintPreviewState* pState)
{
  ...
  CFrameWnd* pParent = (CFrameWnd*)AfxGetThread()->m_pMainWnd;
 
  ASSERT_VALID(pParent);
  ASSERT_KINDOF(CFrameWnd, pParent);

Des weiteren ist das MDI-Child zu deaktivieren und das gewünschte Menü anzuzeigen. Dazu ist als erstes das Originalmenü zu sichern...

  CChildFrame *pChildFrame = DYNAMIC_DOWNCAST (
       CChildFrame, pParent->GetActiveFrame());
  if (pChildFrame)
  {
    HMENU hMenuShared = pChildFrame->GetSharedMenu ();

...bevor das während der Vorschau gewünschte Menü angezeigt oder das Menü auf NULL gesetzt wird.

    pChildFrame->SetSharedMenu (NULL);

Das Deaktivieren des MDI-Childs erfolgt über den Aufruf:

    pChildFrame->SendMessage (WM_MDIACTIVATE, 0, 0);

Abschließend wird das gemeinsam benutzte Menü restauriert.

    pChildFrame->SetSharedMenu (hMenuShared);
  }
  ...
}

Als nächster Schritt ist eine Ableitung von CPreviewView zu bilden, da in CView::DoPrintPreview() viele geschützte Member CPreviewView benutzt werden, was aber in der neuen Methode DoPrintPreview() nicht mehr möglich ist.

Eine mögliche Lösung für dieses Problem besteht darin, eine Klasse CMDIView als friend von CMyPreviewView zu deklarieren.

Lösung

class CMyPreviewView: public CPreviewView
{
  protected:
    CMyPreviewView();
 
    DECLARE_DYNCREATE(CMyPreviewView)
    ...
    friend class CMDIView;
};

Zu guter letzt muß eine Zugriffsfunktion für den MDI Child Frame geschrieben werden. Hierzu wird kurzerhand eine neue Klasse CChildFrame deklariert, die zwei neue Methoden für das Setzen und Lesen des gemeinsam genutzten Menüs implementiert.

Klasse CMyPreviewView

class CChildFrame : public CMDIChildWnd
{
  DECLARE_DYNCREATE(CChildFrame)
 
  public:
    CChildFrame();
 
    HMENU GetSharedMenu () const 
      { 
         return m_hMenuShared; 
      }
 
    void SetSharedMenu (HMENU hMenuShared) 
      { 
         m_hMenuShared = hMenuShared; 
      }
  ...
};

Mit Hilfe der gezeigten Lösung ist es möglich, auch in neueren Versionen von VC++ die liebgewonnene Druckvorschau mit größerem Anzeigebereich einzusetzen. Gleichzeitig bleibt damit ein Stück Kompatibilität zu alten Programmversionen erhalten.

Klasse CChildFrame





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:54:41 von textarchiv.alojado.de