Objective Grid: CGXWndWrapper and printing

Problem


CGXWndWrapper and printing
 


Cause


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.


Action


However, it is possible to add support for printing a window if this window provides a method for rendering its content to a device context. The following example shows how to subclass CGXWndWrapper and add support for printing CGXGridWnd cells.

Example:
 

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;

}

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))
);


 



Article ID: 81
Last updated: 22 Jun, 2018
Revision: 4
Stingray -> Objective Grid -> Objective Grid: CGXWndWrapper and printing
https://rwkbp.makekb.com/entry/81/