<< Return to Main Index

< Return to Class Index

class CGXWndWrapper: public CGXControl

The CGXWndWrapper class is an adapter-like class for any CWnd-derived objects. You can use any CWnd-derived object as cell in the grid when you wrap it with CGXWndWrapper. All you need to do is pass a pointer for your CWnd to the CGXWndWrapper-constructor.

Style attributes which specify the appearance of the cell are:

By default the CGXWndWrapper class does not support printing. This is because CGXWndWrapper only knows the CWnd interface and there is no generic way to force a window to render its contents to a device context.

However, you have the possibility to add support for printing a window if this window provides a method for rendering its device context to a device context. See the attached example.

#include <gxall.h>

Example

The following example demonstrates how to subclass CGXWndWrapper and add support for printing CGXGridWnd cells.

class CMyGridWndWrapper: public CGXWndWrapper
{
public:
   CMyGridWndWrapper(CGXGridCore* pGrid, CWnd* pWnd, BOOL bNeedDestroy, BOOL bCanActivate, BOOL bInvertBorders);
   CMyGridWndWrapper(CGXGridCore* pGrid);
   virtual void Draw(CDC* pDC, CRect rect, ROWCOL nRow, ROWCOL nCol, const CGXStyle& style, const CGXStyle* pStandardStyle);
   virtual void OnNotifyMsg(MSG* pMsg);
};

class CMyGrid: public CGXGridWnd
{
   friend class CMyGridWndWrapper;
};

CMyGridWndWrapper::CMyGridWndWrapper(CGXGridCore* pGrid, CWnd* pWnd, BOOL bNeedDestroy, BOOL bCanActivate, BOOL bInvertBorders)
   : CGXWndWrapper(pGrid, pWnd, bNeedDestroy, bCanActivate, bInvertBorders)
{
}

CMyGridWndWrapper::CMyGridWndWrapper(CGXGridCore* pGrid)
   : CGXWndWrapper(pGrid)
{
}

void CMyGridWndWrapper::OnNotifyMsg(MSG* pMsg)
{
   // Called from CGXGridCore::OnVScroll, OnHScroll
   pMsg;

   // deactivate the current cell when the user scrolls

   if (pMsg->message == WM_VSCROLL
      || pMsg->message == WM_HSCROLL)
   {
      SetActive(FALSE);
      Refresh();
   }
}

void CMyGridWndWrapper::Draw(CDC* pDC, CRect rect, ROWCOL nRow, ROWCOL nCol, const CGXStyle& style, const CGXStyle* pStandardStyle)
{
   // Only let the base class draw the active current cell
   if (m_pWnd == NULL
      || !m_pWnd->IsKindOf(RUNTIME_CLASS(CGXGridWnd))
      || !Grid()->IsPrinting() && nRow == m_nRow && nCol == m_nCol && m_bIsActive)
   {
      CGXWndWrapper::Draw(pDC, rect, nRow, nCol, style, pStandardStyle);
   }
   else // render a CGXGridWnd object to the device context
   {
      ASSERT(::IsWindow(m_pWnd->m_hWnd));
      // ASSERTION-> Did you forget to call Create? ->END

      ASSERT(pDC != NULL && pDC->IsKindOf(RUNTIME_CLASS(CDC)));
      // ASSERTION-> Invalid Device Context ->END
      ASSERT(nRow <= Grid()->GetRowCount() && nCol <= Grid()->GetColCount());
      // ASSERTION-> Cell coordinates out of range ->END

      ASSERT_VALID(pDC);

      CMyGrid* pGrid = (CMyGrid*) m_pWnd;

      // Erase Frame around the cell
      DrawFrame(pDC, rect, style);

      rect = GetCellRect(nRow, nCol, &rect, &style);

      CRect rectDisplay = CRect(0, 0, rect.Width(), rect.Height());

      // The grid below only prints to CRect(0,0,x,y) -
      // Therefore I have to change the mapping mode so that
      // rectDisplay maps to (0,0,x,y)

      pDC->SaveDC();
      CPoint pt = pDC->OffsetWindowOrg(-rect.left, -rect.top);
      pDC->IntersectClipRect(rectDisplay);

      pGrid->SetGridRect(TRUE, rectDisplay);

      pGrid->DrawDirectToDC(pDC);

      pGrid->SetGridRect(FALSE, rectDisplay);

      // Reset device context
      pDC->RestoreDC(-1);

      // child Controls: spin-buttons, hotspot, combobox btn, ...
      // CGXControl::Draw(pDC, rect, nRow, nCol, style, pStandardStyle);
   }

   // Unreferenced:
   pStandardStyle;
}

and in OninitialUpdate add

   CGXGridWnd* pGridWnd = new CGXGridWnd();
   VERIFY(pGridWnd->Create(WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE, CRect(0,0,1,1), this, IDS_CTRL_GRIDCHILD));
   pGridWnd->Initialize();
   pGridWnd->SetRowCount(32);
   pGridWnd->SetColCount(16);


   RegisterControl(IDS_CTRL_GRIDCHILD,
      new CMyGridWndWrapper(this,
            pGridWnd,
            TRUE, // must delete
            TRUE, // can activate
            FALSE // no invert borders
         ));

   ...

   SetCoveredCellsRowCol(5, 1, 10, 5);
   SetStyleRange(CGXRange(5,1), CGXStyle()
         .SetControl(IDS_CTRL_GRIDCHILD)
         .SetDraw3dFrame(gxFrameInset)
         //.SetBorders(gxBorderAll, CGXPen().SetWidth(2))
      );

See Also

CGXGridCore::RegisterControl CGXStyle::SetControl CGXStyle

CGXWndWrapper

Class Members