XTPReportControl.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:134k
- // top
- default :
- break;
- }
- }
- CXTPCompatibleDC memWatermarkDC(&dc, m_hbmpWatermark);
- COLORREF clrBk = GetPaintManager()->m_clrControlBack;
- CRect rcReport00(0, 0, rc.Width(), rc.Height());
- CBitmap bmpTmp;
- bmpTmp.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height());
- CXTPCompatibleDC memDCtmp(&dc, &bmpTmp);
- memDCtmp.FillSolidRect(&rcReport00, clrBk);
- if(GetWatermarkAlignment() & xtpReportWatermarkStretch)
- {
- CBitmap bmpWatermarkTmp;
- bmpWatermarkTmp.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height());
- CXTPCompatibleDC memWatermarkDCtmp(&dc, &bmpWatermarkTmp);
- memWatermarkDCtmp.FillSolidRect(&rc, RGB(255, 255, 255));
- memWatermarkDCtmp.SetStretchBltMode(HALFTONE);
- memWatermarkDCtmp.StretchBlt(rcDst.left, rcDst.top, rcDst.Width(), rcDst.Height(), &memWatermarkDC, 0, 0, rcSrc.Width(), rcSrc.Height(), SRCCOPY);
- XTPImageManager()->AlphaBlend2(memDCtmp, rc, memWatermarkDCtmp, rc, m_WatermarkTransparency);
- }
- else
- {
- XTPImageManager()->AlphaBlend2(memDCtmp, rcDst, memWatermarkDC, rcSrc, m_WatermarkTransparency);
- }
- XTPImageManager()->TransparentBlt(memDCtmp, rcReport00, memDC, rcReport00, clrBk);
- memDC.BitBlt(0, 0, rc.right, rc.bottom, &memDCtmp, 0, 0, SRCCOPY);
- }
- dc.BitBlt(0, 0, rc.right, rc.bottom, &memDC, 0, 0, SRCCOPY);
- memDC.SelectObject(pOldBitmap);
- }
- else
- {
- CXTPCompatibleDC memDC(&dc, &m_bmpCache);
- dc.BitBlt(0, 0, rc.right, rc.bottom, &memDC, 0, 0, SRCCOPY);
- }
- // count drawing time
- #ifdef XTP_DEBUG
- LARGE_INTEGER iEndCount;
- QueryPerformanceCounter(&iEndCount);
- XTP_TRACE(_T("Draw counter ticks: %dn"), iEndCount.LowPart-iStartCount.LowPart);
- #endif
- }
- LRESULT CXTPReportControl::OnPrintClient(WPARAM wParam, LPARAM /*lParam*/)
- {
- CDC* pDC = CDC::FromHandle((HDC)wParam);
- if (pDC)
- {
- if (m_bmpCache.GetSafeHandle() == 0)
- OnDraw(pDC);
- else
- {
- CXTPCompatibleDC memDC(pDC, &m_bmpCache);
- CXTPClientRect rc(this);
- pDC->BitBlt(0, 0, rc.right, rc.bottom, &memDC, 0, 0, SRCCOPY);
- }
- }
- return TRUE;
- }
- BOOL CXTPReportControl::OnEraseBkgnd(CDC* /*pDC*/)
- {
- return TRUE; // Don't erase the background.
- }
- void CXTPReportControl::OnDraw(CDC* pDC)
- {
- if (GetExStyle() & WS_EX_RTLREADING)
- {
- pDC->SetTextAlign(TA_RTLREADING);
- }
- // draw new image
- pDC->FillSolidRect(CXTPClientRect(this), GetPaintManager()->GetControlBackColor(this));
- CXTPReportHeader* pHeader = GetReportHeader();
- CRect rcHeader = m_rcHeaderArea;
- rcHeader.right = rcHeader.left + pHeader->GetWidth();
- // draw header
- if (pHeader)
- pHeader->Draw(pDC, rcHeader, m_nLeftOffset);
- // draw group by box
- if (pHeader)
- pHeader->DrawGroupByControl(pDC, m_rcGroupByArea);
- DrawRows(pDC, m_rcReportArea);
- if (m_bHeaderRecordsVisible && m_pHeaderRows->GetCount() > 0)
- {
- DrawFixedRows(pDC, m_rcHeaderRecordsArea, m_pHeaderRows);
- DrawFixedRecordsDivider(pDC, m_rcHeaderRecordsDividerArea, TRUE);
- }
- if (m_bFooterRecordsVisible && m_pFooterRows->GetCount() > 0)
- {
- DrawFixedRows(pDC, m_rcFooterRecordsArea, m_pFooterRows);
- DrawFixedRecordsDivider(pDC, m_rcFooterRecordsDividerArea, FALSE);
- }
- CRect rcFooter = m_rcFooterArea;
- if (rcFooter.Height() > 0)
- pHeader->DrawFooter(pDC, rcFooter, m_nLeftOffset);
- if (m_nDropPos != -1)
- {
- DrawDropMarker(pDC);
- }
- // update flag
- SetChanged(FALSE);
- }
- void CXTPReportControl::DrawDropMarker(CDC* pDC)
- {
- CRect rc(m_rcReportArea.left, m_nDropPos, m_rcReportArea.right, m_nDropPos + 1);
- pDC->FillSolidRect(rc, GetPaintManager()->m_clrHotDivider);
- CXTPPenDC pen (*pDC, GetPaintManager()->m_clrHotDivider);
- CXTPBrushDC brush (*pDC, GetPaintManager()->m_clrHotDivider);
- int x = rc.left;
- int y = m_nDropPos;
- POINT ptsLeftArrow[] =
- {
- {x, y - 2}, {x + 2, y - 2}, {x + 2, y - 5}, {x + 7, y},
- {x + 2, y + 5}, {x + 2, y + 2}, {x, y + 2}
- };
- pDC->Polygon(ptsLeftArrow, 7);
- x = rc.right - 1;
- POINT ptsRightArrow[] =
- {
- {x, y - 2}, {x - 2, y - 2}, {x - 2, y - 5}, {x - 7, y},
- {x - 2, y + 5}, {x - 2, y + 2}, {x, y + 2}
- };
- pDC->Polygon(ptsRightArrow, 7);
- }
- void CXTPReportControl::OnSize(UINT nType, int cx, int cy)
- {
- if (m_bOnSizeRunning)
- return;
- m_bOnSizeRunning = TRUE;
- CWnd::OnSize(nType, cx, cy);
- AdjustLayout();
- AdjustScrollBars();
- m_bOnSizeRunning = FALSE;
- }
- void CXTPReportControl::OnRButtonDown(UINT nFlags, CPoint point)
- {
- CWnd::OnRButtonDown(nFlags, point);
- }
- void CXTPReportControl::OnRButtonUp(UINT nFlags, CPoint point)
- {
- HWND hWnd = m_hWnd;
- CWnd::OnRButtonUp(nFlags, point);
- if (!IsWindow(hWnd)) // Can be destroyed in WM_CONTEXTMENU
- return;
- }
- void CXTPReportControl::OnLButtonDown(UINT nFlags, CPoint point)
- {
- CWnd::OnLButtonDown(nFlags, point);
- SetFocus();
- EditItem(NULL);
- // columns processing
- CXTPReportHeader* pHeader = GetReportHeader();
- if (pHeader)
- {
- pHeader->OnLButtonDown(point);
- }
- // rows selection
- CXTPReportRow* pRow = HitTest(point);
- if (pRow)
- {
- XTP_REPORTRECORDITEM_CLICKARGS clickArgs;
- clickArgs.pControl = this;
- clickArgs.pRow = pRow;
- clickArgs.ptClient = point;
- clickArgs.pColumn = NULL;
- // find clicked item
- clickArgs.pItem = pRow->HitTest(point, &clickArgs.rcItem, &clickArgs.pColumn);
- if (pRow->OnLButtonDown(&clickArgs))
- return;
- // some rows may be unaccessible for end user
- if (pRow->GetType() == xtpRowTypeHeader && !m_bHeaderRowsAllowAccess)
- return;
- if (pRow->GetType() == xtpRowTypeFooter && !m_bFooterRowsAllowAccess)
- return;
- bool bIgnoreSelection = GetKeyState(VK_CONTROL) < 0 || IsMultiSelectionMode();
- bool bSelectBlock = GetKeyState(VK_SHIFT) < 0;
- BOOL bFocusChanged = TRUE;
- CXTPReportColumn* pFocusedColumn = clickArgs.pColumn;
- CUpdateContext updateContext(this);
- if (m_bFocusSubItems && pFocusedColumn && pRow->GetRecord() && pRow->GetRecord()->GetItem(pFocusedColumn)->IsFocusable())
- {
- SetFocusedColumn(pFocusedColumn);
- }
- if (pRow->IsSelected() && !bIgnoreSelection && !bSelectBlock)
- {
- m_pSelectOnUpRow = pRow;
- }
- else
- {
- bFocusChanged = SetFocusedRow(pRow, bSelectBlock, bIgnoreSelection);
- }
- BOOL bSelectionChanged = m_pSelectedRows->IsChanged();
- if (bFocusChanged && bIgnoreSelection && IsSelectionEnabled())
- {
- m_pSelectedRows->Invert(pRow);
- if(!bSelectionChanged && m_pSelectedRows->IsChanged())
- OnSelectionChanged();
- }
- m_pointDrag = point;
- m_bPrepareDrag = TRUE;
- }
- }
- void CXTPReportControl::OnLButtonUp(UINT nFlags, CPoint point)
- {
- CWnd::OnLButtonUp(nFlags, point);
- m_bPrepareDrag = FALSE;
- EnsureStopAutoVertScroll();
- // columns processing
- CXTPReportHeader* pHeader = GetReportHeader();
- if (pHeader)
- {
- pHeader->OnLButtonUp(nFlags, point);
- }
- CXTPReportRow* pRow = HitTest(point);
- if (pRow)
- {
- if (pRow == m_pSelectOnUpRow)
- {
- SetFocusedRow(pRow, FALSE, FALSE);
- }
- XTP_REPORTRECORDITEM_CLICKARGS clickArgs;
- clickArgs.pControl = this;
- clickArgs.pRow = pRow;
- clickArgs.ptClient = point;
- clickArgs.pColumn = NULL;
- // find clicked item
- clickArgs.pItem = pRow->HitTest(point, &clickArgs.rcItem, &clickArgs.pColumn);
- pRow->OnLButtonUp(&clickArgs);
- }
- m_pSelectOnUpRow = NULL;
- if (!m_bMultipleSelection || (GetKeyState(VK_SHIFT) >= 0 && (GetKeyState(VK_CONTROL) >= 0 && !IsMultiSelectionMode())))
- {
- // rows processing
- if (pRow && pRow->IsFocused())
- {
- pRow->OnClick(point);
- }
- }
- }
- void CXTPReportControl::OnLButtonDblClk(UINT nFlags, CPoint ptDblClick)
- {
- CWnd::OnLButtonDblClk(nFlags, ptDblClick);
- // columns processing
- CXTPReportHeader* pHeader = GetReportHeader();
- if (pHeader)
- {
- pHeader->OnLButtonDblClk(ptDblClick);
- }
- // rows processing
- CXTPReportRow* pRow = HitTest(ptDblClick);
- if (pRow)
- {
- pRow->OnDblClick(ptDblClick);
- }
- else
- {
- // just notify parent
- SendMessageToParent(NULL, NULL, NULL, NM_DBLCLK, &ptDblClick);
- }
- }
- void CXTPReportControl::OnContextMenu(CWnd* /*pWnd*/, CPoint pos)
- {
- if (GetMouseMode() != xtpReportMouseNothing)
- return;
- CPoint ptClient = pos;
- ScreenToClient(&ptClient);
- // call context menu handler for report header if clicked inside
- if (m_rcHeaderArea.PtInRect(ptClient) ||
- m_rcGroupByArea.PtInRect(ptClient))
- {
- CXTPReportHeader* pHeader = GetReportHeader();
- if (pHeader)
- pHeader->OnContextMenu(ptClient);
- return;
- }
- // call context menu handler for report area if clicked inside
- if (m_rcReportArea.PtInRect(ptClient) ||
- m_rcHeaderRecordsArea.PtInRect(ptClient) ||
- m_rcFooterRecordsArea.PtInRect(ptClient))
- {
- // rows processing
- CXTPReportRow* pRow = HitTest(ptClient);
- if (pRow)
- {
- SetFocusedRow(pRow, pRow->IsSelected());
- pRow->OnContextMenu(ptClient);
- }
- else
- {
- SendMessageToParent(NULL, NULL, NULL, NM_RCLICK, &pos);
- }
- return;
- }
- if (pos == CPoint(-1, -1))
- {
- CXTPReportRow* pFocusedRow = GetFocusedRow();
- if (pFocusedRow)
- {
- ptClient = CPoint(pFocusedRow->GetRect().left, pFocusedRow->GetRect().bottom);
- pFocusedRow->OnContextMenu(ptClient);
- }
- else
- {
- pos = m_rcReportArea.TopLeft();
- ClientToScreen(&pos);
- SendMessageToParent(NULL, NULL, NULL, NM_RCLICK, &pos);
- }
- }
- }
- CXTPReportColumn* CXTPReportControl::GetNextFocusableColumn(CXTPReportRow* pRow, int nColumnIndex, int nDirection)
- {
- if (!pRow->GetRecord())
- return NULL;
- for (;;)
- {
- CXTPReportColumn* pColumn = GetReportHeader()->GetNextVisibleColumn(nColumnIndex, nDirection);
- if (!pColumn)
- return NULL;
- CXTPReportRecordItem* pItem = pRow->GetRecord()->GetItem(pColumn);
- if (pItem && pItem->IsFocusable())
- return pColumn;
- nColumnIndex = pColumn->GetIndex();
- }
- }
- BOOL CXTPReportControl::OnPreviewKeyDown(UINT& rnChar, UINT nRepCnt, UINT nFlags)
- {
- XTP_NM_REPORTPREVIEWKEYDOWN nmParams;
- ::ZeroMemory(&nmParams, sizeof(nmParams));
- nmParams.nChar = rnChar;
- nmParams.nRepCnt = nRepCnt;
- nmParams.nFlags = nFlags;
- nmParams.bCancel = FALSE;
- SendNotifyMessage(XTP_NM_REPORT_PREVIEWKEYDOWN, (NMHDR*)&nmParams);
- rnChar = nmParams.nChar;
- return !nmParams.bCancel;
- }
- void CXTPReportControl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- // TRACE(_T("ReportControl, OnKeyDown('%d') n"), nChar);
- // Moved to PreTranslateMessage
- // if (!OnPreviewKeyDown(nChar, nRepCnt, nFlags))
- // {
- // return;
- // }
- CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
- BOOL bSelectBlock = GetKeyState(VK_SHIFT) < 0;
- BOOL bSignoreSelection = GetKeyState(VK_CONTROL) < 0 || IsMultiSelectionMode();
- CXTPReportRow* pFocusedRow = GetFocusedRow();
- CXTPDrawHelpers::KeyToLayout(this, nChar);
- if (m_pRows->GetCount() != 0)
- switch (nChar)
- {
- case VK_ADD:
- if (bSignoreSelection)
- ExpandAll();
- else if (pFocusedRow && pFocusedRow->HasChildren() && !pFocusedRow->IsExpanded())
- {
- pFocusedRow->SetExpanded(TRUE);
- }
- break;
- case VK_SUBTRACT:
- if (bSignoreSelection)
- CollapseAll();
- else if (pFocusedRow && pFocusedRow->HasChildren() && pFocusedRow->IsExpanded())
- {
- pFocusedRow->SetExpanded(FALSE);
- }
- break;
- case VK_RIGHT:
- if (pFocusedRow && pFocusedRow->HasChildren() && !pFocusedRow->IsExpanded())
- {
- pFocusedRow->SetExpanded(TRUE);
- break;
- }
- if (pFocusedRow && m_bFocusSubItems && m_pFocusedColumn)
- {
- CXTPReportColumn* pColumn = GetNextFocusableColumn(pFocusedRow, m_pFocusedColumn->GetIndex(), +1);
- if (pColumn)
- {
- SetFocusedColumn(pColumn);
- SetFocusedRow(GetFocusedRow());
- }
- break;
- }
- case VK_DOWN:
- GetNavigator()->MoveDown(bSelectBlock, bSignoreSelection);
- break;
- case VK_LEFT:
- if (pFocusedRow && pFocusedRow->HasChildren() && pFocusedRow->IsExpanded())
- {
- pFocusedRow->SetExpanded(FALSE);
- break;
- }
- if (pFocusedRow && m_bFocusSubItems && m_pFocusedColumn)
- {
- CXTPReportColumn* pColumn = GetNextFocusableColumn(pFocusedRow, m_pFocusedColumn->GetIndex(), -1);
- if (pColumn)
- {
- SetFocusedColumn(pColumn);
- SetFocusedRow(GetFocusedRow());
- }
- break;
- }
- if (pFocusedRow && !pFocusedRow->HasChildren() && pFocusedRow->GetParentRow() && !bSelectBlock)
- {
- SetFocusedRow(pFocusedRow->GetParentRow());
- pFocusedRow->SetExpanded(FALSE);
- break;
- }
- case VK_UP:
- GetNavigator()->MoveUp(bSelectBlock, bSignoreSelection);
- break;
- case VK_HOME:
- GetNavigator()->MoveFirstRow(bSelectBlock, FALSE);
- break;
- case VK_END:
- GetNavigator()->MoveLastRow(bSelectBlock, FALSE);
- break;
- case VK_NEXT:
- GetNavigator()->MovePageDown(bSelectBlock, FALSE);
- break;
- case VK_PRIOR:
- GetNavigator()->MovePageUp(bSelectBlock, FALSE);
- break;
- case VK_RETURN:
- if (pFocusedRow && pFocusedRow->HasChildren())
- {
- pFocusedRow->SetExpanded(!pFocusedRow->IsExpanded());
- }
- break;
- case VK_ESCAPE:
- if (m_mouseMode != xtpReportMouseNothing)
- {
- GetReportHeader()->CancelMouseMode();
- }
- break;
- case VK_F2:
- GetNavigator()->BeginEdit();
- break;
- case VK_SPACE:
- if(IsSelectionEnabled() && bSignoreSelection && pFocusedRow)
- {
- // m_pSelectedRows->Invert(pFocusedRow);
- if(pFocusedRow->IsSelected())
- m_pSelectedRows->Remove(pFocusedRow);
- else
- m_pSelectedRows->Add(pFocusedRow);
- OnSelectionChanged();
- }
- break;
- }
- NMKEY nmgv;
- nmgv.nVKey = nChar;
- nmgv.uFlags = nFlags;
- SendNotifyMessage(NM_KEYDOWN, (NMHDR*)&nmgv);
- }
- void CXTPReportControl::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- CWnd::OnSysKeyDown(nChar, nRepCnt, nFlags);
- }
- void CXTPReportControl::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
- }
- void CXTPReportControl::OnSysKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- CWnd::OnSysKeyUp(nChar, nRepCnt, nFlags);
- }
- void CXTPReportControl::OnChar(UINT nChar, UINT nRepCntr, UINT nFlags)
- {
- // TRACE(_T("ReportControl, OnChar('%d') n"), nChar);
- // Moved to PreTranslateMessage
- // if (!OnPreviewKeyDown(nChar, nRepCntr, nFlags))
- // {
- // return;
- // }
- NMCHAR nmgv;
- ZeroMemory(&nmgv, sizeof(NMCHAR));
- nmgv.ch = nChar;
- SendNotifyMessage(NM_CHAR, (NMHDR*)&nmgv);
- CXTPReportRow* pFocusedRow = GetFocusedRow();
- if (m_bFocusSubItems && pFocusedRow && (nChar == VK_TAB))
- {
- EditItem(NULL);
- BOOL bBack = GetKeyState(VK_SHIFT) < 0;
- GetNavigator()->MoveLeftRight(bBack);
- return;
- }
- if (m_pFocusedColumn && pFocusedRow && pFocusedRow->GetRecord() && (nChar != VK_RETURN) && (nChar != VK_ESCAPE))
- {
- XTP_REPORTRECORDITEM_ARGS itemArgs(this, pFocusedRow, m_pFocusedColumn) ;
- if (itemArgs.pItem && itemArgs.pItem->OnChar(&itemArgs, nChar))
- return;
- }
- CWnd::OnChar(nChar, nRepCntr, nFlags);
- }
- void CXTPReportControl::OnCaptureChanged(CWnd* pWnd)
- {
- if (m_mouseMode != xtpReportMouseNothing)
- {
- GetReportHeader()->CancelMouseMode();
- }
- CWnd::OnCaptureChanged(pWnd);
- }
- void CXTPReportControl::OnEnable(BOOL bEnable)
- {
- UNREFERENCED_PARAMETER(bEnable);
- AdjustScrollBars();
- }
- void CXTPReportControl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- if (pScrollBar != NULL)
- {
- CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
- return;
- }
- int nCurPos = m_nTopRow;
- // decide what to do for each diffrent scroll event
- switch (nSBCode)
- {
- case SB_TOP: nCurPos = 0; break;
- case SB_BOTTOM: nCurPos = GetScrollLimit(SB_VERT); break;
- case SB_LINEUP: nCurPos = max(nCurPos - 1, 0); break;
- case SB_LINEDOWN: nCurPos = min(nCurPos + 1, GetScrollLimit(SB_VERT)); break;
- case SB_PAGEUP: nCurPos = max(nCurPos - GetReportAreaRows(nCurPos, false), 0); break;
- case SB_PAGEDOWN: nCurPos = min(nCurPos + GetReportAreaRows(nCurPos, true), GetScrollLimit(SB_VERT)); break;
- case SB_THUMBTRACK:
- case SB_THUMBPOSITION:
- {
- SCROLLINFO si;
- ZeroMemory(&si, sizeof(SCROLLINFO));
- si.cbSize = sizeof(SCROLLINFO);
- si.fMask = SIF_TRACKPOS;
- if (!GetScrollInfo(SB_VERT, &si))
- return;
- nCurPos = si.nTrackPos;
- }
- break;
- }
- SetTopRow(nCurPos);
- }
- void CXTPReportControl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- if (pScrollBar != NULL)
- {
- CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
- return;
- }
- int nCurPos = m_nLeftOffset;
- // FCS - full column scrolling
- int nLeftOffset_new = m_nLeftOffset;
- CXTPReportColumn *pPrev = NULL, *pCurr = NULL, *pNext = NULL;
- int nScrollPos = 0, nScrollMax = 0;
- int nFreezOffset = 0;
- if (m_bFullColumnScrolling)
- nFreezOffset = GetReportHeader()->GetFulColScrollInfo(pPrev, pCurr, pNext, nScrollPos, nScrollMax);
- // decide what to do for each different scroll event
- switch (nSBCode)
- {
- case SB_TOP:
- nCurPos = 0;
- nLeftOffset_new = 0;
- nScrollPos = 0;
- break;
- case SB_BOTTOM:
- nCurPos = GetScrollLimit(SB_HORZ);
- if (m_bFullColumnScrolling)
- {
- int nVisColCount = GetColumns()->GetVisibleColumnsCount();
- CXTPReportColumn *pLast = GetColumns()->GetVisibleAt(max(nVisColCount-1, 0));
- ASSERT(pLast);
- if (!pLast)
- return;
- nLeftOffset_new = labs(GetReportHeader()->m_rcHeader.left - pLast->GetRect().left) - nFreezOffset;
- nScrollPos = max(nScrollMax - 1, 0);
- }
- break;
- case SB_LINEUP:
- nCurPos = max(nCurPos - m_nHScrollStep, 0);
- if (m_bFullColumnScrolling && pPrev)
- {
- nLeftOffset_new = labs(GetReportHeader()->m_rcHeader.left - pPrev->GetRect().left) - nFreezOffset;
- nScrollPos = max(nScrollPos - 1, 0);
- }
- break;
- case SB_LINEDOWN:
- nCurPos = min(nCurPos + m_nHScrollStep, GetScrollLimit(SB_HORZ));
- if (m_bFullColumnScrolling && pNext)
- {
- nLeftOffset_new = labs(GetReportHeader()->m_rcHeader.left - pNext->GetRect().left) - nFreezOffset;
- nScrollPos = nScrollPos + 1;
- }
- break;
- case SB_PAGEUP:
- nCurPos = max(nCurPos - m_rcReportArea.Width(), 0);
- if (m_bFullColumnScrolling && pPrev)
- {
- nLeftOffset_new = labs(GetReportHeader()->m_rcHeader.left - pPrev->GetRect().left) - nFreezOffset;
- nScrollPos = max(nScrollPos - 1, 0);
- }
- break;
- case SB_PAGEDOWN:
- nCurPos = min(nCurPos + m_rcReportArea.Width(), GetScrollLimit(SB_HORZ));
- if (m_bFullColumnScrolling && pNext)
- {
- nLeftOffset_new = labs(GetReportHeader()->m_rcHeader.left - pNext->GetRect().left) - nFreezOffset;
- nScrollPos = nScrollPos + 1;
- }
- break;
- case SB_THUMBTRACK:
- case SB_THUMBPOSITION:
- nCurPos = nPos;
- if (m_bFullColumnScrolling)
- {
- int nVisColCount = GetColumns()->GetVisibleColumnsCount();
- int nCurrCol = nVisColCount - nScrollMax + nPos;
- CXTPReportColumn *pCurrScroll = GetColumns()->GetVisibleAt(nCurrCol);
- ASSERT(pCurrScroll);
- if (!pCurrScroll)
- return;
- nLeftOffset_new = labs(GetReportHeader()->m_rcHeader.left - pCurrScroll->GetRect().left) - nFreezOffset;
- nScrollPos = nPos;
- }
- break;
- }
- if (m_bFullColumnScrolling)
- {
- SetLeftOffset(nLeftOffset_new);
- SetScrollPos(SB_HORZ, nScrollPos);
- }
- else
- {
- SetLeftOffset(nCurPos);
- }
- }
- UINT CXTPReportControl::GetMouseScrollLines()
- {
- int nScrollLines = 3; // default value
- if (XTPSystemVersion()->IsWin95())
- {
- HKEY hKey;
- if (ERROR_SUCCESS == RegOpenKeyEx(
- HKEY_CURRENT_USER, _T("Control Panel\Desktop"), 0, KEY_QUERY_VALUE, &hKey))
- {
- TCHAR szData[128];
- DWORD dwKeyDataType;
- DWORD dwDataBufSize = sizeof(szData);
- if (ERROR_SUCCESS == RegQueryValueEx(
- hKey, _T("WheelScrollLines"), NULL, &dwKeyDataType, (LPBYTE) &szData, &dwDataBufSize))
- {
- nScrollLines = _tcstoul(szData, NULL, 10);
- }
- RegCloseKey(hKey);
- }
- }
- // win98 or greater
- else
- SystemParametersInfo (SPI_GETWHEELSCROLLLINES, 0, &nScrollLines, 0);
- return nScrollLines;
- }
- BOOL CXTPReportControl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
- {
- if (!m_bVScrollBarVisible)
- return CWnd::OnMouseWheel(nFlags, zDelta, pt);
- UINT uiMsg;
- int nScrollsCount = 0;
- // calculate what should be sent
- if (m_nRowsPerWheel == -1)
- {
- // A m_nRowsPerWheel value less than 0 indicates that the mouse wheel scrolls whole pages, not just lines.
- int nPagesScrolled = zDelta / 120;
- uiMsg = nPagesScrolled > 0 ? SB_PAGEUP : SB_PAGEDOWN;
- nScrollsCount = nPagesScrolled > 0 ? nPagesScrolled : -nPagesScrolled;
- }
- else
- {
- int nRowsScrolled = m_nRowsPerWheel * zDelta / 120;
- uiMsg = nRowsScrolled > 0 ? SB_LINEUP : SB_LINEDOWN;
- nScrollsCount = nRowsScrolled > 0 ? nRowsScrolled : -nRowsScrolled;
- }
- BeginUpdate();
- // send scroll messages
- for (int i = 0; i < nScrollsCount; i++)
- {
- OnVScroll(uiMsg, 0, NULL);
- }
- EndUpdate();
- UpdateWindow();
- return CWnd::OnMouseWheel(nFlags, zDelta, pt);
- }
- void CXTPReportControl::OnMouseLeave()
- {
- OnMouseMove(0, CPoint(-1, -1));
- }
- void CXTPReportControl::OnMouseMove(UINT nFlags, CPoint point)
- {
- CWnd::OnMouseMove(nFlags, point);
- CXTPReportHeader* pHeader = GetReportHeader();
- if (pHeader)
- {
- pHeader->OnMouseMove(nFlags, point);
- }
- if (GetMouseMode() == xtpReportMouseNothing)
- {
- CXTPReportRow* pRow = HitTest(point);
- if (pRow)
- {
- pRow->OnMouseMove(nFlags, point);
- if (m_bShowTooltips && nFlags == 0)
- {
- pRow->ShowToolTip(point, &m_wndTip);
- }
- }
- if (m_pHotRow != pRow)
- {
- TRACKMOUSEEVENT tme =
- {
- sizeof(TRACKMOUSEEVENT), TME_LEAVE, GetSafeHwnd(), 0
- };
- _TrackMouseEvent (&tme);
- m_pHotRow = pRow;
- }
- // If mouse moved some since down...
- if (m_bPrepareDrag && (labs (point.x - m_pointDrag.x) > 3 ||
- labs (point.y - m_pointDrag.y) > 3))
- {
- // Prevent duplicate
- m_bPrepareDrag = FALSE;
- m_pSelectOnUpRow = NULL;
- // Begin a drag operation
- OnBeginDrag(m_pointDrag);
- }
- }
- }
- void CXTPReportControl::OnBeginDrag(CPoint point)
- {
- if (SendMessageToParent(NULL, NULL, NULL, LVN_BEGINDRAG, &point))
- return;
- if (m_cfReport == NULL)
- return;
- CXTPReportSelectedRows* pSelectedRows = GetSelectedRows();
- if (!pSelectedRows)
- return;
- if ((m_dwDragDropFlags & xtpReportAllowDrag) == 0)
- return;
- int nCount = pSelectedRows->GetCount();
- for (int i = nCount - 1; i >= 0; i--)
- {
- CXTPReportRow* pRow = pSelectedRows->GetAt(i);
- if (pRow->IsGroupRow())
- {
- pRow->SetExpanded(TRUE);
- pRow->SelectChilds();
- }
- }
- COleDataSource ds;
- int nRowsCount = pSelectedRows->GetCount();
- if (nRowsCount < 1)
- return;
- // minimize memory reallocs to improve performance
- UINT nAveRecordsSize = 1500; // bytes
- UINT nGrowBytes = ((nRowsCount * nAveRecordsSize) / 4096 + 1) * 4096;
- UINT nAllocFlags = GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT;
- CSharedFile fileRecords(nAllocFlags, nGrowBytes);
- BOOL bSucceed = FALSE;
- //------------------------------------------------------------------------
- const int cErrTextSize = 1024;
- TCHAR szErrText[cErrTextSize + 1];
- CXTPReportRecords* pDragRecords = new CXTPReportRecords(TRUE);
- if (!_GetSelectedRows(pDragRecords))
- {
- CMDTARGET_RELEASE(pDragRecords);
- return;
- }
- try
- {
- CArchive ar(&fileRecords, CArchive::store);
- CXTPPropExchangeArchive px(ar);
- bSucceed = _WriteRecordsData(&px, pDragRecords);
- ar.Close(); // perform Flush() and detach from file
- }
- catch(CArchiveException* pE)
- {
- if (pE->GetErrorMessage(szErrText, cErrTextSize))
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Copy() - %sn"), szErrText);
- }
- pE->Delete();
- }
- catch(CFileException* pE)
- {
- if (pE->GetErrorMessage(szErrText, cErrTextSize))
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Copy() - %sn"), szErrText);
- }
- pE->Delete();
- }
- catch(...)
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Copy() - Unhandled Exception!n"));
- }
- if (!bSucceed)
- {
- CMDTARGET_RELEASE(pDragRecords);
- return;
- }
- HGLOBAL hGlobal = fileRecords.Detach();
- m_bDragMode = TRUE;
- DROPEFFECT dropEffectMask =
- ((m_dwDragDropFlags & xtpReportAllowDragCopy) ? DROPEFFECT_COPY : 0) +
- ((m_dwDragDropFlags & xtpReportAllowDragMove) ? DROPEFFECT_MOVE : 0);
- XTP_NM_REPORTDRAGDROP nmData;
- ZeroMemory(&nmData, sizeof(nmData));
- nmData.pRecords = pDragRecords;
- if (SendNotifyMessage(XTP_NM_REPORT_BEGINDRAG, (NMHDR*)&nmData) == -1)
- return;
- ds.CacheGlobalData (m_cfReport, hGlobal);
- DROPEFFECT dropEffect = ds.DoDragDrop(dropEffectMask);
- m_bDragMode = FALSE;
- nmData.dropEffect = dropEffect;
- SendNotifyMessage(XTP_NM_REPORT_DRAGDROP_COMPLETED, (NMHDR*)&nmData);
- if ((dropEffect == DROPEFFECT_MOVE) && (dropEffectMask & DROPEFFECT_MOVE))
- {
- Cut();
- }
- CMDTARGET_RELEASE(pDragRecords);
- EnsureStopAutoVertScroll();
- }
- DROPEFFECT CXTPReportControl::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point, int nState)
- {
- DROPEFFECT dropEffect = DROPEFFECT_MOVE;
- BOOL bAbove = TRUE;
- CXTPReportRecord* pTargetRecord = NULL;
- if ((dwKeyState & MK_CONTROL) == MK_CONTROL)
- dropEffect = DROPEFFECT_COPY;
- if (!m_nOLEDropMode)
- {
- if (m_cfReport == NULL)
- dropEffect = DROPEFFECT_NONE;
- if ((m_dwDragDropFlags & xtpReportAllowDrop) == 0)
- dropEffect = DROPEFFECT_NONE;
- if ((dropEffect != DROPEFFECT_NONE) && (!pDataObject || !pDataObject->IsDataAvailable(m_cfReport)))
- dropEffect = DROPEFFECT_NONE;
- }
- int nDropPos = m_nDropPos;
- m_nDropPos = -1;
- if (dropEffect != DROPEFFECT_NONE)
- {
- DoAutoVertScrollIfNeed(m_pointDrag, point);
- if (GetColumns()->GetSortOrder()->GetCount() == 0 && GetColumns()->GetGroupsOrder()->GetCount() == 0)
- {
- CXTPReportRow* pRow = HitTest(point);
- if (pRow && pRow->GetRecord())
- {
- bAbove = pRow->GetRect().CenterPoint().y < point.y ? FALSE : TRUE;
- pTargetRecord = pRow->GetRecord();
- m_nDropPos = (pRow->GetRect().CenterPoint().y < point.y ? pRow->GetRect().bottom - 1: pRow->GetRect().top - 1);
- }
- }
- }
- if(nState == 0)
- {
- // entering, get report records
- CMDTARGET_RELEASE(m_pDropRecords);
- CFile* pFile = m_cfReport ? pDataObject->GetFileData(m_cfReport) : NULL;
- if (pFile)
- {
- m_pDropRecords = new CXTPReportRecords();
- const int cErrTextSize = 1024;
- TCHAR szErrText[cErrTextSize + 1];
- try
- {
- CArchive ar(pFile, CArchive::load);
- CXTPPropExchangeArchive px(ar);
- if (!_ReadRecodsFromData(&px, *m_pDropRecords))
- {
- m_pDropRecords->RemoveAll();
- }
- ar.Close(); // detach from file
- }
- catch(CArchiveException* pE)
- {
- if (pE->GetErrorMessage(szErrText, cErrTextSize))
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - %sn"), szErrText);
- }
- pE->Delete();
- }
- catch(CFileException* pE)
- {
- if (pE->GetErrorMessage(szErrText, cErrTextSize))
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - %sn"), szErrText);
- }
- pE->Delete();
- }
- catch(...)
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - Unhandled Exception!n"));
- }
- delete pFile;
- }
- }
- else if(nState == 1)
- {
- // leaving, release drop records
- CMDTARGET_RELEASE(m_pDropRecords);
- }
- XTP_NM_REPORTDRAGDROP nmData;
- nmData.pRecords = m_pDropRecords;
- nmData.pTargetRecord = pTargetRecord;
- nmData.bAbove = bAbove;
- nmData.dropEffect = dropEffect;
- nmData.pt = point;
- nmData.nState = nState;
- SendNotifyMessage(XTP_NM_REPORT_DRAGOVER, (NMHDR*)&nmData);
- if (m_nDropPos != nDropPos)
- {
- RedrawControl();
- }
- return dropEffect;
- }
- void CXTPReportControl::OnTimer(UINT_PTR uTimerID)
- {
- if (m_uAutoScrollTimerID == uTimerID)
- {
- CPoint ptMouse;
- if (::GetCursorPos(&ptMouse))
- {
- ScreenToClient(&ptMouse);
- DoAutoVertScrollIfNeed(m_pointDrag, ptMouse);
- }
- //TRACE(_T("AutoScrollTimer n"));
- }
- CWnd::OnTimer(uTimerID);
- }
- void CXTPReportControl::EnsureStopAutoVertScroll()
- {
- if (m_uAutoScrollTimerID)
- {
- KillTimer(m_uAutoScrollTimerID);
- m_uAutoScrollTimerID = 0;
- //TRACE(_T("AutoScroll STOP n"));
- }
- }
- void CXTPReportControl::EnsureStartAutoVertScroll()
- {
- if (!m_uAutoScrollTimerID)
- {
- m_uAutoScrollTimerID = SetTimer(XTP_REPORT_AUTO_SCROLL_TIMER_ID, XTP_REPORT_AUTO_SCROLL_TIMER_RESOLUTION_MS, NULL);
- }
- }
- void CXTPReportControl::DoAutoVertScrollIfNeed(CPoint ptClick, CPoint pt)
- {
- if (!m_arrScreenRows.GetCount())
- {
- EnsureStopAutoVertScroll();
- return;
- }
- CXTPReportRow* pRow0 = m_arrScreenRows.GetAt(0);
- CXTPReportRow* pRow1 = m_arrScreenRows.GetAt(m_arrScreenRows.GetCount() - 1);
- if (!pRow0 || !pRow1)
- {
- EnsureStopAutoVertScroll();
- return;
- }
- int nDirection = 0;
- CRect rc0 = m_rcReportArea; //pRow0->GetRect();
- CRect rc1 = m_rcReportArea; //pRow1->GetRect();
- rc0.bottom = m_rcReportArea.top + 20;
- rc1.top = m_rcReportArea.bottom - 20;
- if (rc0.PtInRect(pt))
- nDirection = -1;
- else if (rc1.PtInRect(pt))
- nDirection = 1;
- if (!nDirection ||
- m_bDragMode &&
- (nDirection == 1 && pt.y - ptClick.y < 3 ||
- nDirection == -1 && ptClick.y - pt.y < 3)
- )
- {
- EnsureStopAutoVertScroll();
- return;
- }
- //-----------------------------------------------------
- int nTopRow = GetTopRowIndex();
- int nRowsCount = m_pRows->GetCount();
- if (nDirection == -1 && nTopRow > 0 ||
- nDirection == 1 &&
- (pRow1->GetIndex() < nRowsCount ||
- pRow1->GetRect().bottom > m_rcReportArea.bottom)
- )
- {
- //TRACE(_T("AutoScroll direction=%d, nextRow=%dn"), nDirection, nTopRow+nDirection);
- SetTopRow(nTopRow + nDirection);
- EnsureStartAutoVertScroll();
- return;
- }
- EnsureStopAutoVertScroll();
- }
- BOOL CXTPReportControl::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
- {
- CMDTARGET_RELEASE(m_pDropRecords);
- EnsureStopAutoVertScroll();
- CUpdateContext updateContext(this);
- int nDropPos = m_nDropPos;
- m_nDropPos = -1;
- if (dropEffect != DROPEFFECT_COPY && dropEffect != DROPEFFECT_MOVE)
- return FALSE;
- if (IsVirtualMode())
- return FALSE;
- if (!pDataObject || !pDataObject->IsDataAvailable(m_cfReport))
- return FALSE;
- if ((m_dwDragDropFlags & xtpReportAllowDrop) == 0)
- return FALSE;
- int nInsert = GetRecords()->GetCount();
- BOOL bAbove = TRUE;
- CXTPReportRecord* pTargetRecord = NULL;
- CXTPReportRow* pRow = HitTest(point);
- if (pRow)
- {
- bAbove = pRow->GetRect().CenterPoint().y < point.y ? FALSE : TRUE;
- pTargetRecord = pRow->GetRecord();
- if(pTargetRecord)
- nInsert = pTargetRecord->GetIndex() + (bAbove ? 0 : 1);
- }
- if (m_bDragMode && dropEffect == DROPEFFECT_MOVE)
- {
- if (nDropPos == -1)
- return FALSE;
- CXTPReportRecords* pDropRecords = new CXTPReportRecords(TRUE);
- if (!_GetSelectedRows(pDropRecords))
- {
- CMDTARGET_RELEASE(pDropRecords);
- return FALSE;
- }
- XTP_NM_REPORTDRAGDROP nmData;
- nmData.pRecords = pDropRecords;
- nmData.pTargetRecord = pTargetRecord;
- nmData.bAbove = bAbove;
- nmData.dropEffect = dropEffect;
- CMDTARGET_ADDREF(pTargetRecord);
- if (SendNotifyMessage(XTP_NM_REPORT_DROP, (NMHDR*)&nmData) == -1)
- {
- CMDTARGET_RELEASE(pDropRecords);
- return FALSE;
- }
- GetRecords()->Move(nInsert, pDropRecords);
- Populate();
- _SelectRows(pDropRecords);
- RedrawControl();
- SendNotifyMessage(XTP_NM_REPORT_RECORDS_DROPPED, (NMHDR*)&nmData);
- CMDTARGET_RELEASE(pDropRecords);
- CMDTARGET_RELEASE(pTargetRecord);
- return FALSE;
- }
- CFile* pFile = pDataObject->GetFileData(m_cfReport);
- if (!pFile)
- return FALSE;
- CXTPReportRecords* pDropRecords = new CXTPReportRecords();
- const int cErrTextSize = 1024;
- TCHAR szErrText[cErrTextSize + 1];
- try
- {
- CArchive ar(pFile, CArchive::load);
- CXTPPropExchangeArchive px(ar);
- if (!_ReadRecodsFromData(&px, *pDropRecords))
- {
- pDropRecords->RemoveAll();
- }
- ar.Close(); // detach from file
- }
- catch(CArchiveException* pE)
- {
- if (pE->GetErrorMessage(szErrText, cErrTextSize))
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - %sn"), szErrText);
- }
- pE->Delete();
- }
- catch(CFileException* pE)
- {
- if (pE->GetErrorMessage(szErrText, cErrTextSize))
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - %sn"), szErrText);
- }
- pE->Delete();
- }
- catch(...)
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - Unhandled Exception!n"));
- }
- delete pFile;
- XTP_NM_REPORTDRAGDROP nmData;
- nmData.pRecords = pDropRecords;
- nmData.pTargetRecord = pTargetRecord;
- nmData.bAbove = bAbove;
- nmData.dropEffect = dropEffect;
- if (SendNotifyMessage(XTP_NM_REPORT_DROP, (NMHDR*)&nmData) == -1)
- {
- CMDTARGET_RELEASE(pDropRecords);
- return FALSE;
- }
- // Add and Populate records
- int nRecordsCount = pDropRecords->GetCount();
- if (nRecordsCount > 0)
- {
- // Add
- for (int i = 0; i < nRecordsCount; i++)
- {
- CXTPReportRecord* pRecord = pDropRecords->GetAt(i);
- if (pRecord)
- {
- CMDTARGET_ADDREF(pRecord);
- m_pRecords->InsertAt(nInsert, pRecord);
- nInsert++;
- }
- }
- Populate();
- _SelectRows(pDropRecords);
- RedrawControl();
- SendNotifyMessage(XTP_NM_REPORT_RECORDS_DROPPED, (NMHDR*)&nmData);
- }
- CMDTARGET_RELEASE(pDropRecords);
- return TRUE;
- }
- BOOL CXTPReportControl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
- {
- if (nHitTest == HTCLIENT)
- {
- switch (m_mouseMode)
- {
- case xtpReportMouseOverColumnDivide:
- SetCursor(GetReportHeader()->m_hResizeCursor);
- return TRUE;
- }
- }
- return CWnd::OnSetCursor(pWnd, nHitTest, message);
- }
- LRESULT CXTPReportControl::SendNotifyMessage(UINT nMessage, NMHDR* pNMHDR) const
- {
- if (!IsWindow(m_hWnd))
- return 0;
- NMHDR nmhdr;
- if (pNMHDR == NULL)
- pNMHDR = &nmhdr;
- pNMHDR->hwndFrom = GetSafeHwnd();
- pNMHDR->idFrom = GetDlgCtrlID();
- pNMHDR->code = nMessage;
- CWnd *pOwner = GetOwner();
- if (pOwner && IsWindow(pOwner->m_hWnd))
- return pOwner->SendMessage(WM_NOTIFY, pNMHDR->idFrom, (LPARAM)pNMHDR);
- else
- return 0;
- }
- LRESULT CXTPReportControl::SendMessageToParent(CXTPReportRow* pRow, CXTPReportRecordItem* pItem, CXTPReportColumn* pColumn, UINT nMessage, CPoint* pPoint, int nHyperlink) const
- {
- if (!IsWindow(m_hWnd))
- return 0;
- XTP_NM_REPORTRECORDITEM nmgv;
- nmgv.pItem = pItem;
- nmgv.pColumn = pColumn;
- nmgv.pRow = pRow;
- nmgv.nHyperlink = nHyperlink;
- nmgv.pt.x = 0;
- nmgv.pt.y = 0;
- if (pPoint)
- {
- nmgv.pt = *pPoint;
- }
- return SendNotifyMessage(nMessage, (NMHDR*)&nmgv);
- }
- void CXTPReportControl::DoPropExchange(CXTPPropExchange* pPX)
- {
- TRY
- {
- pPX->ExchangeSchemaSafe();
- CXTPPropExchangeSection secColumns(pPX->GetSection(_T("Columns")));
- m_pColumns->DoPropExchange(&secColumns);
- PX_Bool(pPX, _T("ShowGroupBox"), m_bGroupByEnabled, FALSE);
- PX_Int(pPX, _T("FreezeColumnsCount"), m_nFreezeColumnsCount, 0);
- if (pPX->GetSchema() >= _XTP_SCHEMA_110)
- {
- PX_Bool(pPX, _T("FullColumnScrolling"), m_bFullColumnScrolling, FALSE);
- PX_Int(pPX, _T("HScrollStep"), m_nHScrollStep, XTP_REPORT_HSCROLL_STEP);
- }
- CXTPPropExchangeSection secHeader(pPX->GetSection(_T("Header")));
- GetReportHeader()->DoPropExchange(&secHeader);
- if (pPX->IsLoading())
- {
- GetReportHeader()->OnColumnsChanged();
- Populate();
- }
- }
- CATCH(CArchiveException, e)
- {
- }
- END_CATCH
- }
- void CXTPReportControl::SerializeState(CArchive& ar)
- {
- CXTPPropExchangeArchive px(ar);
- DoPropExchange(&px);
- }
- void CXTPReportControl::CollapseAll()
- {
- BeginUpdate();
- for (int i = m_pRows->GetCount() - 1; i >= 0; i--)
- m_pRows->GetAt(i)->SetExpanded(FALSE);
- EndUpdate();
- EnsureVisible(GetFocusedRow());
- }
- void CXTPReportControl::ExpandAll()
- {
- BeginUpdate();
- for (int i = m_pRows->GetCount() - 1; i >= 0; i--)
- m_pRows->GetAt(i)->SetExpanded(TRUE);
- EndUpdate();
- EnsureVisible(GetFocusedRow());
- }
- void CXTPReportControl::SetMouseMode(XTPReportMouseMode nMode)
- {
- XTP_TRACE(_T("SetMouseMode: Switching from %d to %dn"), m_mouseMode, nMode);
- m_mouseMode = nMode;
- }
- void CXTPReportControl::RelayToolTipEvent(UINT message)
- {
- if (m_wndTip.GetSafeHwnd() && m_wndTip.IsWindowVisible())
- {
- CPoint pt;
- GetCursorPos(&pt);
- if (!m_wndTip.GetHoverRect().PtInRect(pt))
- {
- m_wndTip.SetTooltipText(NULL);
- m_wndTip.Activate(FALSE, FALSE);
- }
- switch (message)
- {
- case WM_MOUSEWHEEL:
- case WM_KEYDOWN:
- case WM_SYSKEYDOWN:
- case WM_LBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_LBUTTONUP:
- case WM_RBUTTONUP:
- case WM_MBUTTONUP:
- case WM_MOUSELEAVE:
- m_wndTip.Activate(FALSE, FALSE);
- }
- }
- }
- BOOL CXTPReportControl::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
- {
- static BOOL bRelay = FALSE;
- if (m_wndTip.GetSafeHwnd() && m_wndTip.IsWindowVisible() && !bRelay)
- {
- bRelay = TRUE;
- RelayToolTipEvent(message);
- bRelay = FALSE;
- }
- if (m_pToolTipContext && m_bShowTooltips)
- {
- m_pToolTipContext->FilterToolTipMessage(this, message, wParam, lParam);
- }
- return CWnd::OnWndMsg(message, wParam, lParam, pResult);
- }
- void CXTPReportControl::OnSysColorChange()
- {
- CWnd::OnSysColorChange();
- m_pPaintManager->RefreshMetrics();
- RedrawControl();
- }
- UINT CXTPReportControl::OnGetDlgCode()
- {
- return (m_bFocusSubItems ? DLGC_WANTTAB :0) | DLGC_WANTARROWS | DLGC_WANTCHARS;
- }
- void CXTPReportControl::OnSetFocus(CWnd* pOldWnd)
- {
- CWnd::OnSetFocus(pOldWnd);
- RedrawControl();
- }
- void CXTPReportControl::OnKillFocus (CWnd* pNewWnd)
- {
- CWnd::OnKillFocus(pNewWnd);
- EnsureStopAutoVertScroll();
- RedrawControl();
- }
- int CXTPReportControl::GetHeaderIndent() const
- {
- return GetIndent(GetReportHeader()->m_nIndentLevel);
- }
- CXTPReportRow* CXTPReportControl::CreateRow()
- {
- return new CXTPReportRow_Batch();
- }
- CXTPReportGroupRow* CXTPReportControl::CreateGroupRow()
- {
- return new CXTPReportGroupRow_Batch();
- }
- CXTPReportRow* CXTPReportControl::CreateHeaderFooterRow()
- {
- return new CXTPHeapObjectT<CXTPReportRow, CXTPReportAllocatorDefault>;
- }
- void CXTPReportControl::EditItem(XTP_REPORTRECORDITEM_ARGS* pItemArgs)
- {
- CXTPReportRecordItem* pItem = pItemArgs ? pItemArgs->pItem : NULL;
- if (m_pActiveItem != NULL)
- {
- m_pActiveItem->OnCancelEdit(this, TRUE);
- m_pActiveItem = NULL;
- if (!m_bFocusSubItems)
- {
- SetFocusedColumn(NULL);
- }
- }
- CMDTARGET_RELEASE(m_ptrVirtualEditingRow);
- if (pItem && pItemArgs && pItemArgs->pRow)
- {
- if (!HasFocus())
- SetFocus();
- if (!IsVirtualMode())
- {
- AdjustScrollBars();
- RedrawControl();
- UpdateWindow();
- }
- if (IsVirtualMode())
- {
- int nRowIndex = pItemArgs->pRow->GetIndex();
- EnsureVisible(pItemArgs->pRow);
- RedrawControl();
- UpdateWindow();
- pItemArgs->pRow = NULL; // RedrawControl delete and re-create new screen rows
- BOOL bMapped = FALSE;
- int nScrCount = m_arrScreenRows.GetCount();
- for (int i = 0; i < nScrCount; i++)
- {
- CXTPReportRow* pRow = m_arrScreenRows.GetAt(i);
- if (pRow->GetIndex() == nRowIndex)
- {
- pItemArgs->pRow = pRow;
- bMapped = TRUE;
- ASSERT(m_ptrVirtualEditingRow == NULL);
- m_ptrVirtualEditingRow = pRow;
- CMDTARGET_ADDREF(m_ptrVirtualEditingRow);
- break;
- }
- }
- ASSERT(bMapped);
- if (!bMapped)
- return;
- }
- else if (GetFocusedRow() != pItemArgs->pRow)
- {
- SetFocusedRow(pItemArgs->pRow);
- UpdateWindow();
- }
- pItemArgs->rcItem = pItemArgs->pRow->GetItemRect(pItem);
- if(SetFocusedColumn(pItemArgs->pColumn))
- {
- m_pActiveItem = pItem;
- pItem->OnBeginEdit(pItemArgs);
- }
- }
- RedrawControl();
- }
- BOOL CXTPReportControl::HasFocus() const
- {
- const CWnd* pFocusWnd = GetFocus();
- if (!pFocusWnd)
- return FALSE;
- return (pFocusWnd->GetSafeHwnd() == m_hWnd) || (pFocusWnd->GetParent()->GetSafeHwnd() == m_hWnd) || (pFocusWnd->GetOwner()->GetSafeHwnd() == m_hWnd);
- }
- void CXTPReportControl::ReleaseItem(int nIndex)
- {
- int i;
- for (i = 0; i < m_pRecords->GetCount(); i++)
- {
- CXTPReportRecord* pRecord = m_pRecords->GetAt(i);
- pRecord->m_arrItems[nIndex]->InternalRelease();
- pRecord->m_arrItems.RemoveAt(nIndex);
- }
- CXTPReportColumns* pColumns = GetColumns();
- CXTPReportColumn* pColumnToRemove = NULL;
- int nColumnsCount = pColumns->GetCount();
- for (i = 0; i < nColumnsCount; i++)
- {
- CXTPReportColumn* pColumn = pColumns->GetAt(i);
- if (pColumn->m_nItemIndex > nIndex)
- {
- pColumn->m_nItemIndex--;
- }
- else if (pColumn->m_nItemIndex == nIndex)
- {
- pColumnToRemove = pColumn;
- }
- }
- if (pColumnToRemove)
- pColumns->Remove(pColumnToRemove);
- }
- void CXTPReportControl::SetVirtualMode(CXTPReportRecord* pVirtualRecord, int nCount)
- {
- if (m_pRecords)
- m_pRecords->SetVirtualMode(pVirtualRecord, nCount);
- }
- BOOL CXTPReportControl::IsVirtualMode() const
- {
- return m_pRecords ? m_pRecords->IsVirtualMode() : FALSE;
- }
- CXTPReportRow* CXTPReportControl::GetFocusedRow() const
- {
- if (m_nFocusedRow != -1)
- return m_pRows ? m_pRows->GetAt(m_nFocusedRow) : NULL;
- if (m_nFocusedHeaderRow != -1)
- return m_pHeaderRows ? m_pHeaderRows->GetAt(m_nFocusedHeaderRow) : NULL;
- if (m_nFocusedFooterRow != -1)
- return m_pFooterRows ? m_pFooterRows->GetAt(m_nFocusedFooterRow) : NULL;
- return NULL;
- }
- void CXTPReportControl::OnStyleChanged(int nStyleType, LPSTYLESTRUCT lpStyleStruct)
- {
- CWnd::OnStyleChanged(nStyleType, lpStyleStruct);
- RedrawControl();
- }
- CXTPToolTipContext* CXTPReportControl::GetToolTipContext() const
- {
- return m_pToolTipContext;
- }
- INT_PTR CXTPReportControl::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
- {
- ASSERT_VALID(this);
- ASSERT(::IsWindow(m_hWnd));
- // check child windows first by calling CControlBar
- INT_PTR nHit = CWnd::OnToolHitTest(point, pTI);
- if (nHit != -1)
- return nHit;
- nHit = GetReportHeader()->OnToolHitTest(point, pTI);
- if (nHit != -1)
- return nHit;
- CXTPReportRow* pRow = HitTest(point);
- if (pRow)
- {
- nHit = pRow->OnToolHitTest(point, pTI);
- }
- return nHit;
- }
- void CXTPReportControl::SetLayoutRTL(BOOL bRightToLeft)
- {
- if (!XTPSystemVersion()->IsLayoutRTLSupported())
- return;
- if (!m_hWnd)
- return;
- ModifyStyleEx(bRightToLeft ? 0 : WS_EX_LAYOUTRTL, !bRightToLeft ? 0 : WS_EX_LAYOUTRTL);
- GetImageManager()->DrawReverted(bRightToLeft);
- GetInplaceEdit()->DestroyWindow();
- AdjustLayout();
- }
- BOOL CXTPReportControl::IsLayoutRTL()
- {
- if (!XTPSystemVersion()->IsLayoutRTLSupported())
- return FALSE;
- if (!m_hWnd)
- return FALSE;
- return !!(GetWindowLong(m_hWnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL);
- }
- //////////////////////////////////////////////////////////////////////////
- // Clipboard operations
- BOOL CXTPReportControl::CanCopy()
- {
- // Check whether are there any selected rows to be copied
- CXTPReportSelectedRows* pSelRows = GetSelectedRows();
- if ((pSelRows != NULL) && (pSelRows->GetCount() > 0))
- {
- return TRUE;
- }
- return FALSE;
- }
- BOOL CXTPReportControl::CanCut()
- {
- if (IsVirtualMode())
- return FALSE;
- return CanCopy();
- }
- BOOL CXTPReportControl::CanPaste()
- {
- if (IsVirtualMode())
- return FALSE;
- CLIPFORMAT uCF_Records = (CLIPFORMAT)::RegisterClipboardFormat(XTPREPORTCTRL_CF_RECORDS);
- BOOL bCan = FALSE;
- COleDataObject odj;
- if (odj.AttachClipboard())
- {
- bCan = odj.IsDataAvailable(CF_TEXT)
- || odj.IsDataAvailable(CF_UNICODETEXT)
- || odj.IsDataAvailable(uCF_Records) ;
- }
- return bCan;
- }
- void CXTPReportControl::Cut()
- {
- CWaitCursor _WC;
- // Copy selected data into the clipboard
- Copy();
- if (IsVirtualMode())
- return;
- // Delete selected rows
- CXTPInternalCollectionT<CXTPReportRow> arSelectedRows;
- _GetSelectedRows(NULL, &arSelectedRows);
- int nSelRowsCount = (int)arSelectedRows.GetSize();
- int nFirstSelRow = INT_MAX;
- for (int i = nSelRowsCount - 1; i >= 0 ; i--)
- {
- CXTPReportRow* pRow = arSelectedRows.GetAt(i, FALSE);
- if (pRow)
- {
- nFirstSelRow = min(nFirstSelRow, pRow->GetIndex());
- VERIFY(RemoveRowEx(pRow, FALSE));
- }
- arSelectedRows.RemoveAt(i);
- }
- if (GetSelectedRows())
- {
- GetSelectedRows()->Clear();
- if (nFirstSelRow != INT_MAX)
- {
- m_nFocusedRow = min(nFirstSelRow, GetRows()->GetCount() - 1);
- if (GetFocusedRow())
- {
- SetFocusedRow(GetFocusedRow());
- GetSelectedRows()->Add(GetFocusedRow());
- }
- }
- }
- AdjustScrollBars();
- RedrawControl();
- }
- // We support text format with t dividers for record items and
- // rn dividers for records (simple tab-separated text).
- // Such format is also supported by Excel and some other applications.
- void CXTPReportControl::Copy()
- {
- CWaitCursor _WC;
- int nRowsCount = GetSelectedRows() ? GetSelectedRows()->GetCount() : 1;
- // minimize memory reallocs to improve performance
- UINT nAveRecordsSize = 1500; // bytes
- UINT nGrowBytes = ((nRowsCount * nAveRecordsSize) / 4096 + 1) * 4096;
- UINT nAllocFlags = GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT;
- CSharedFile fileRecords(nAllocFlags, nGrowBytes);
- BOOL bIsRecordsData = FALSE;
- //------------------------------------------------------------------------
- const int cErrTextSize = 1024;
- TCHAR szErrText[cErrTextSize + 1];
- try
- {
- CArchive ar(&fileRecords, CArchive::store);
- CXTPPropExchangeArchive px(ar);
- bIsRecordsData = _WriteSelectedRowsData(&px);
- ar.Close(); // perform Flush() and detach from file
- }
- catch(CArchiveException* pE)
- {
- if (pE->GetErrorMessage(szErrText, cErrTextSize))
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Copy() - %sn"), szErrText);
- }
- pE->Delete();
- }
- catch(CFileException* pE)
- {
- if (pE->GetErrorMessage(szErrText, cErrTextSize))
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Copy() - %sn"), szErrText);
- }
- pE->Delete();
- }
- catch(...)
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Copy() - Unhandled Exception!n"));
- }
- //*****
- CString strClipText = _GetSelectedRowsVisibleColsText();
- CLIPFORMAT uCF_Records = (CLIPFORMAT)::RegisterClipboardFormat(XTPREPORTCTRL_CF_RECORDS);
- // Put prepared text into the clipboard
- if (OpenClipboard())
- {
- ::EmptyClipboard();
- // 1 - Text
- int nLen = (strClipText.GetLength() + 1) * sizeof(TCHAR);
- HGLOBAL hText = ::GlobalAlloc(nAllocFlags, nLen);
- if (hText != NULL)
- {
- LPTSTR lptstrCopy = (TCHAR*)GlobalLock(hText);
- STRCPY_S(lptstrCopy, strClipText.GetLength() + 1, (LPCTSTR)strClipText);
- GlobalUnlock(hText);
- #ifndef _UNICODE
- ::SetClipboardData(CF_TEXT, hText);
- #else
- ::SetClipboardData(CF_UNICODETEXT, hText);
- #endif
- }
- // 2 - Blob data
- if (bIsRecordsData)
- {
- HGLOBAL hData = fileRecords.Detach();
- ::GlobalUnlock(hData); // unlock data
- ::SetClipboardData(uCF_Records, hData);
- }
- //-----------------
- ::CloseClipboard();
- }
- }
- void CXTPReportControl::Paste()
- {
- if (IsVirtualMode())
- return;
- CWaitCursor _WC;
- CLIPFORMAT uCF_Records = (CLIPFORMAT)::RegisterClipboardFormat(XTPREPORTCTRL_CF_RECORDS);
- CXTPReportRecords arRecords;
- BOOL bTryPasteFromText = TRUE;
- // Retrieve text from the clipboard
- if (!OpenClipboard())
- return;
- if (::IsClipboardFormatAvailable(uCF_Records))
- {
- HGLOBAL hPasteData = ::GetClipboardData(uCF_Records);
- if (hPasteData)
- {
- bTryPasteFromText = FALSE;
- const int cErrTextSize = 1024;
- TCHAR szErrText[cErrTextSize + 1];
- CSharedFile fileSahred;
- fileSahred.SetHandle(hPasteData, FALSE);
- CArchive ar(&fileSahred, CArchive::load);
- try
- {
- CXTPPropExchangeArchive px(ar);
- if (!_ReadRecodsFromData(&px, arRecords))
- {
- arRecords.RemoveAll();
- }
- }
- catch(CArchiveException* pE)
- {
- if (pE->GetErrorMessage(szErrText, cErrTextSize))
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - %sn"), szErrText);
- }
- pE->Delete();
- }
- catch(CFileException* pE)
- {
- if (pE->GetErrorMessage(szErrText, cErrTextSize))
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - %sn"), szErrText);
- }
- pE->Delete();
- }
- catch(...)
- {
- TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - Unhandled Exception!n"));
- }
- //*********
- ar.Close(); // detach from file
- fileSahred.Detach(); //detach from data
- ::GlobalUnlock(hPasteData); // unlock data
- }
- }
- UINT uCF_TText = sizeof(TCHAR) == 2 ? CF_UNICODETEXT : CF_TEXT;
- if (bTryPasteFromText && ::IsClipboardFormatAvailable(uCF_TText))
- {
- // Try to get text data from the clipboard
- HGLOBAL hglbPaste = ::GetClipboardData(uCF_TText);
- // Import Text data into the control
- if (hglbPaste != NULL)
- {
- TCHAR* lpszClipboard = (TCHAR*)GlobalLock(hglbPaste);
- if (!_ReadRecodsFromText(lpszClipboard, arRecords))
- {
- arRecords.RemoveAll();
- }
- ::GlobalUnlock(hglbPaste);
- }
- }
- ::CloseClipboard();
- //////////////////////////////////////////////////////////////////////////
- CUpdateContext updateContext(this);
- // Add and Populate records
- int nRecordsCount = arRecords.GetCount();
- if (nRecordsCount > 0)
- {
- // Add
- for (int i = 0; i < nRecordsCount; i++)
- {
- CXTPReportRecord* pRecord = arRecords.GetAt(i);
- if (pRecord)
- {
- CMDTARGET_ADDREF(pRecord);
- AddRecord(pRecord);
- }
- }
- Populate();
- // Select added records
- _SelectRows(&arRecords);
- }
- }
- // We support text format with t dividers for record items and
- // rn dividers for records (simple tab-separated text).
- // Such format is also supported by Excel and some other applications.
- CString CXTPReportControl::_GetSelectedRowsVisibleColsText()
- {
- CString strSelText;
- CXTPReportColumns* pColumns = GetColumns();
- if (NULL == pColumns)
- return _T("");
- const int nColumnCount = pColumns->GetVisibleColumnsCount();
- // Iterate over the selected rows and prepare corresponding records text
- CXTPReportSelectedRows* pSelectedRows = GetSelectedRows();
- if ((pSelectedRows != NULL) && (pSelectedRows->GetCount() > 0))
- {
- POSITION pos = pSelectedRows->GetFirstSelectedRowPosition();
- while (pos)
- {
- CXTPReportRow* pRow = pSelectedRows->GetNextSelectedRow(pos);
- if (NULL == pRow)
- break;
- CXTPReportRecord* pRecord = pRow->GetRecord();
- if (NULL == pRecord)
- continue;
- CStringArray arStrings;
- for (int nCol = 0; nCol < nColumnCount; nCol++)
- {
- CXTPReportColumn* pColumn = pColumns->GetVisibleAt(nCol);
- CXTPReportRecordItem* pItem = pRecord->GetItem(pColumn);
- if (NULL == pItem)
- continue;
- arStrings.Add(pItem->GetCaption(pColumn));
- }
- //===============================================================
- BOOL bCanceled = OnBeforeCopyToText(pRecord, arStrings);
- if (bCanceled)
- {
- continue;
- }
- strSelText += XTPStrMake(arStrings, _T("t"));
- strSelText += _T("rn");
- }
- }
- return strSelText;
- }
- BOOL CXTPReportControl::_ReadRecodsFromText(LPCTSTR pcszText,
- CXTPReportRecords& rarRecords)
- {
- //////////////////////////////////////////////////////////////////////////
- // Insert retrieved text into the control
- CStringArray arRecordsStrings;
- XTPStrSplit(pcszText, _T("rn"), arRecordsStrings);
- int nCount = (int)arRecordsStrings.GetSize();
- for (int i = 0; i < nCount; i++)
- {
- CString strRecord = arRecordsStrings[i];
- if (strRecord.IsEmpty())
- {
- continue;
- }
- CXTPReportRecord* pNewRec = _CreateRecodFromText(strRecord);
- // pNewRec = NULL - paste was handled by the user
- if (pNewRec)
- {
- rarRecords.Add(pNewRec);
- }
- }
- return TRUE;
- }
- CXTPReportRecord* CXTPReportControl::_CreateRecodFromText(LPCTSTR pcszRecord)
- {
- if (!GetColumns())
- {
- ASSERT(FALSE);
- return NULL;
- }
- CStringArray arStrings;
- // Read each field from the initial string and set visible field one by one
- XTPStrSplit(pcszRecord, _T("t"), arStrings);
- //=======================================================================
- CXTPReportRecord* pRecord = NULL;
- BOOL bHandled = OnBeforePasteFromText(arStrings, &pRecord);
- if (bHandled)
- {
- return pRecord;
- }
- #if _MFC_VER >= 0x0600 // Not supported by Visual Studio 5.0
- if (!pRecord)
- {
- pRecord = new CXTPReportRecord();
- if (!pRecord)
- {
- return NULL;
- }
- int nDataCount = (int)arStrings.GetSize();
- // Fill record with all items
- int nCount = GetColumns()->GetCount();
- for (int i = 0; i < nCount; i++)
- {
- COleVariant varItem(_T(""));
- CXTPReportRecordItem* pItem = new CXTPReportRecordItemVariant(varItem);
- if (!pItem)
- {
- CMDTARGET_RELEASE(pRecord);
- return NULL;
- }
- pRecord->AddItem(pItem);
- }
- // Iterate all visible columns and set text for each next
- const int nColumnCount = GetColumns()->GetVisibleColumnsCount();
- for (int nCol = 0; nCol < nColumnCount; nCol++)
- {
- COleVariant varItem(nCol < nDataCount ? (LPCTSTR)arStrings[nCol] : _T(""));
- CXTPReportColumn* pColumn = GetColumns()->GetVisibleAt(nCol);
- CXTPReportRecordItem* pItem = pRecord->GetItem(pColumn);
- ASSERT(pItem);
- if (NULL == pItem)
- continue;
- CXTPReportRecordItemVariant* pItemVar = DYNAMIC_DOWNCAST(CXTPReportRecordItemVariant, pItem);
- ASSERT(pItemVar);
- if (pItemVar)
- {
- pItemVar->m_oleValue = varItem;
- }
- }
- }
- #endif
- return pRecord;
- }
- BOOL CXTPReportControl::_WriteRecordsData(CXTPPropExchange* pPX, CXTPReportRecords* pRecords)
- {
- if (!pRecords)
- return FALSE;
- long nSchema = XTP_REPORT_CB_RECORDS_DATA_VER;
- PX_Long(pPX, _T("Version"), (long&)nSchema);
- pPX->ExchangeLocale();
- CXTPPropExchangeSection secRecords(pPX->GetSection(_T("ReportRecords")));
- int nRecordsCount = (int)pRecords->GetCount();
- CXTPPropExchangeEnumeratorPtr pEnumRecords(secRecords->GetEnumerator(_T("Record")));
- POSITION posRecord = pEnumRecords->GetPosition((DWORD)nRecordsCount);
- for (int i = 0; i < nRecordsCount; i++)
- {
- CXTPPropExchangeSection secRecord(pEnumRecords->GetNext(posRecord));
- CXTPReportRecord* pRecord = pRecords->GetAt(i);
- PX_Object(&secRecord, pRecord, RUNTIME_CLASS(CXTPReportRecord));
- }
- return TRUE;
- }
- void CXTPReportControl::_SelectRows(CXTPReportRecords* pRecords)
- {
- CXTPReportRows* pRows = GetRows();
- CXTPReportSelectedRows* pSelRows = GetSelectedRows();
- if (!pRows || !pSelRows)
- return;
- pSelRows->Clear();
- int nRecordsCount = pRecords->GetCount();
- for (int nNewRecNr = 0; nNewRecNr < nRecordsCount; nNewRecNr++)
- {
- CXTPReportRecord* pRec = pRecords->GetAt(nNewRecNr);
- CXTPReportRow* pRow = pRows->Find(pRec);
- if (pRow)
- {
- pSelRows->Add(pRow);
- if (nNewRecNr == nRecordsCount - 1)
- SetFocusedRow(pRow, TRUE);
- }
- }
- }
- BOOL CXTPReportControl::_GetSelectedRows(CXTPReportRecords* pRecords,
- CXTPInternalCollectionT<CXTPReportRow> *pRows)
- {
- ASSERT(!pRecords || pRecords->m_bArray == TRUE);
- CXTPReportSelectedRows* pSelectedRows = GetSelectedRows();
- if (!pSelectedRows || !pSelectedRows->GetCount() || (!pRecords && !pRows))
- {
- return FALSE;
- }
- POSITION pos = pSelectedRows->GetFirstSelectedRowPosition();
- while (pos)
- {
- CXTPReportRow* pRow = pSelectedRows->GetNextSelectedRow(pos);
- CXTPReportRecord* pRecord = pRow ? pRow->GetRecord() : NULL;
- if (NULL == pRow)
- {
- break;
- }
- if (pRecord && pRecords)
- {
- pRecords->Add(pRecord);
- }
- if (pRow && pRows)
- {
- pRows->AddPtr(pRow, TRUE);
- }
- }
- return TRUE;
- }
- BOOL CXTPReportControl::_WriteSelectedRowsData(CXTPPropExchange* pPX)
- {
- if (!pPX || !pPX->IsStoring())
- {
- ASSERT(FALSE);
- return FALSE;
- }
- CXTPReportRecords* pSelectedRecords= new CXTPReportRecords(TRUE);
- if (!_GetSelectedRows(pSelectedRecords) || !_WriteRecordsData(pPX, pSelectedRecords))
- {
- CMDTARGET_RELEASE(pSelectedRecords);
- return FALSE;
- }
- CMDTARGET_RELEASE(pSelectedRecords);
- return TRUE;
- }
- BOOL CXTPReportControl::_ReadRecodsFromData(CXTPPropExchange* pPX,
- CXTPReportRecords& rarRecords)
- {
- rarRecords.RemoveAll();
- if (!pPX || !pPX->IsLoading())
- {
- ASSERT(FALSE);
- return FALSE;
- }
- CXTPPropExchangeSection secRecords(pPX->GetSection(_T("ReportRecords")));
- long nSchema = 0;
- PX_Long(pPX, _T("Version"), (long&)nSchema);
- pPX->ExchangeLocale();
- if (nSchema != XTP_REPORT_CB_RECORDS_DATA_VER)
- {
- ASSERT(FALSE);
- return FALSE;
- }
- CXTPPropExchangeEnumeratorPtr pEnumRecords(secRecords->GetEnumerator(_T("Record")));
- POSITION posRecord = pEnumRecords->GetPosition();
- while (posRecord)
- {
- CXTPPropExchangeSection secRecord(pEnumRecords->GetNext(posRecord));
- CXTPReportRecord* pRecord = NULL;
- PX_Object(&secRecord, pRecord, RUNTIME_CLASS(CXTPReportRecord));
- if (!pRecord)
- {
- AfxThrowArchiveException(CArchiveException::badClass);
- }
- CXTPReportRecord* pRecord2 = pRecord;
- BOOL bCanceled = OnBeforePaste(&pRecord2);
- if (bCanceled || pRecord2 != pRecord)
- {
- CMDTARGET_RELEASE(pRecord);
- }
- if (bCanceled)
- {
- continue;
- }
- rarRecords.Add(pRecord2);
- }
- return TRUE;
- }
- BOOL CXTPReportControl::OnBeforeCopyToText(CXTPReportRecord* pRecord, CStringArray& rarStrings)
- {
- XTP_NM_REPORT_BEFORE_COPYPASTE nmParams;
- ::ZeroMemory(&nmParams, sizeof(nmParams));
- CXTPReportRecord* pRecordTmp = pRecord;
- nmParams.ppRecord = &pRecordTmp;
- nmParams.parStrings = &rarStrings;
- LRESULT lResult = SendNotifyMessage(XTP_NM_REPORT_BEFORE_COPY_TOTEXT, (NMHDR*)&nmParams);
- return lResult != 0;
- }
- BOOL CXTPReportControl::OnBeforePasteFromText(CStringArray& arStrings,
- CXTPReportRecord** ppRecord)
- {
- XTP_NM_REPORT_BEFORE_COPYPASTE nmParams;
- ::ZeroMemory(&nmParams, sizeof(nmParams));
- nmParams.parStrings = &arStrings;
- nmParams.ppRecord = ppRecord;
- LRESULT lResult = SendNotifyMessage(XTP_NM_REPORT_BEFORE_PASTE_FROMTEXT, (NMHDR*)&nmParams);
- return lResult != 0;
- }
- BOOL CXTPReportControl::OnBeforePaste(CXTPReportRecord** ppRecord)
- {
- XTP_NM_REPORT_BEFORE_COPYPASTE nmParams;
- ::ZeroMemory(&nmParams, sizeof(nmParams));
- nmParams.ppRecord = ppRecord;
- LRESULT lResult = SendNotifyMessage(XTP_NM_REPORT_BEFORE_PASTE, (NMHDR*)&nmParams);
- return lResult != 0;
- }
- int CXTPReportControl::OnGetColumnDataBestFitWidth(CXTPReportColumn* pColumn)
- {
- CXTPReportPaintManager* pPaintManager = GetPaintManager();
- if (!pColumn || !pPaintManager)
- {
- ASSERT(FALSE);
- return 0;
- }
- if(pColumn->GetBestFitMode() != xtpColumnBestFitModeAllData)
- return 0;
- CClientDC dc(this);
- CXTPFontDC autoFont(&dc, pPaintManager->GetTextFont()); // to reset selected font on exit
- int nDataWidth = OnGetItemsCaptionMaxWidth(&dc, GetRows(), pColumn);
- return nDataWidth;
- }
- int CXTPReportControl::OnGetItemsCaptionMaxWidth(CDC* pDC, CXTPReportRows* pRows,
- CXTPReportColumn* pColumn)
- {
- CXTPReportPaintManager* pPaintManager = GetPaintManager();
- if(!pDC || !pRows || !pColumn || !pPaintManager)
- {
- ASSERT(FALSE);
- return 0;
- }
- XTP_REPORTRECORDITEM_DRAWARGS drawArgs;
- drawArgs.pDC = pDC;
- drawArgs.pControl = this;
- drawArgs.pColumn = pColumn;
- drawArgs.rcItem = pColumn->GetRect();
- XTP_REPORTRECORDITEM_METRICS* pMetrics = new XTP_REPORTRECORDITEM_METRICS();
- int nMaxWidth = 0;
- int nItemIndex = pColumn->GetItemIndex();
- int nCount = pRows->GetCount();
- for (int i = 0; i < nCount; i++)
- {
- CXTPReportRow* pRow = pRows->GetAt(i);
- ASSERT(pRow);
- if (pRow && pRow->IsGroupRow())
- continue;
- CXTPReportRecord* pRec = pRow ? pRow->GetRecord() : NULL;
- CXTPReportRecordItem* pItem = pRec ? pRec->GetItem(nItemIndex) : NULL;
- ASSERT(pItem);
- if (!pItem)
- continue;
- drawArgs.pRow = pRow;
- drawArgs.pItem = pItem;
- pMetrics->strText = pItem->GetCaption(pColumn);
- pRow->GetItemMetrics(&drawArgs, pMetrics);
- pDC->SelectObject(pMetrics->pFont);
- int nWidth = pDC->GetTextExtent(pMetrics->strText).cx + 7;
- nMaxWidth = max(nMaxWidth, nWidth);
- }
- CMDTARGET_RELEASE(pMetrics);
- return nMaxWidth;
- }
- BOOL CXTPReportControl::IsEditMode()
- {
- CXTPReportInplaceEdit* pEdit = GetInplaceEdit();
- BOOL bEditMode = pEdit && pEdit->GetSafeHwnd() && pEdit->IsWindowVisible();
- bEditMode |= GetInplaceList() && GetInplaceList()->GetSafeHwnd() && GetInplaceList()->IsWindowVisible();
- return bEditMode;
- }
- int CXTPReportControl::GetRowsHeight(CXTPReportRows* pRows, int nTotalWidth, int nMaxHeight)
- {
- int nRowsHeight = 0;
- CWindowDC dc (this);
- for(int i = 0; i < pRows->GetCount(); ++i)
- {
- nRowsHeight += GetPaintManager()->GetRowHeight(&dc, pRows->GetAt(i), nTotalWidth);
- if (nMaxHeight >= 0 && nRowsHeight > nMaxHeight)
- return nRowsHeight;
- }
- return nRowsHeight;
- }
- int CXTPReportControl::GetHeaderRowsDividerHeight()
- {
- return GetPaintManager()->GetHeaderRowsDividerHeight();
- }
- int CXTPReportControl::GetFooterRowsDividerHeight()
- {
- return GetPaintManager()->GetFooterRowsDividerHeight();
- }
- void CXTPReportControl::DrawDefaultGrid(CDC* pDC, CRect rcClient, int nRowHeight, int nLeftOffset)
- {
- if (nRowHeight <= 0)
- return;
- // int y = rcClient.top;
- int nFreezeCols = m_nFreezeColumnsCount;
- CRect rcClipBox = GetReportRectangle();
- CRect rcRow;
- rcRow = rcClient;
- rcRow.left -= nLeftOffset;
- rcRow.right -= nLeftOffset;
- rcRow.bottom = rcClient.top + nRowHeight;
- int nIndentWidth = GetHeaderIndent();
- CXTPReportPaintManager* pPaintManager = GetPaintManager();
- CXTPReportColumns arrVisibleColumns(this);
- GetColumns()->GetVisibleColumns(arrVisibleColumns);
- int nVisColCount = arrVisibleColumns.GetCount();
- nFreezeCols = min(nFreezeCols, nVisColCount);
- // fill the empty space
- while(rcRow.top < rcClient.bottom)
- {
- CRect rcItem(rcRow.left, rcRow.top, rcRow.right, rcRow.bottom);
- CRect rcIndent(nFreezeCols ? rcRow : rcRow); /////////////////////
- rcIndent.right = rcIndent.left + nIndentWidth;
- int xMinCol_0 = rcRow.left + nIndentWidth;
- for (int nColumn = nVisColCount-1; nColumn >= 0; nColumn--)
- {
- BOOL bFreezeCol = nColumn < nFreezeCols;
- int nColIdx = bFreezeCol ? nFreezeCols - 1 - nColumn : nColumn;
- CXTPReportColumn* pColumn = arrVisibleColumns.GetAt(nColIdx);
- ASSERT(pColumn && pColumn->IsVisible());
- if (pColumn)
- {
- rcItem.left = pColumn->GetRect().left;
- if (nColIdx == 0)
- {
- rcItem.left = max(xMinCol_0, rcItem.left);
- }
- rcItem.right = pColumn->GetRect().right;
- if (!CRect().IntersectRect(rcClipBox, rcItem))
- continue;
- if (bFreezeCol)
- {
- CRect rcFreeze(rcItem);
- rcFreeze.top +=1;
- pDC->FillSolidRect(rcFreeze, pPaintManager->GetControlBackColor(this));
- }
- CRect rcGridItem(rcItem);
- rcGridItem.left--;
- pPaintManager->DrawGrid(pDC, FALSE, rcGridItem);
- pPaintManager->DrawGrid(pDC, TRUE, rcGridItem);
- if (nColIdx == nFreezeCols - 1)
- pPaintManager->DrawFreezeColsDivider(pDC, rcGridItem, this);
- }
- }
- if (nIndentWidth > 0)
- {
- // draw indent column
- pPaintManager->FillIndent(pDC, rcIndent);
- }
- rcRow.top += nRowHeight;
- rcRow.bottom += nRowHeight;
- }
- }
- BOOL CXTPReportControl::PreTranslateMessage(MSG* pMsg)
- {
- if (pMsg->message == WM_KEYDOWN)
- {
- if (!OnPreviewKeyDown((UINT&)pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam)) )
- {
- TRACE(_T("ReportControl, PreTranslateMessagem-OnPreviewKeyDown('%d') = CANCEL n"), pMsg->wParam);
- return TRUE;
- }
- }
- return CWnd::PreTranslateMessage(pMsg);
- }
- BOOL CXTPReportControl::OnConstraintSelecting(CXTPReportRow* pRow, CXTPReportRecordItem* pItem, CXTPReportColumn* pColumn,
- CXTPReportRecordItemConstraint* pConstraint)
- {
- XTP_NM_REPORTCONSTRAINTSELECTING nmConstraint;
- ::ZeroMemory(&nmConstraint, sizeof(nmConstraint));
- nmConstraint.pRow = pRow;
- nmConstraint.pColumn = pColumn;
- nmConstraint.pItem = pItem;
- nmConstraint.pConstraint = pConstraint;
- LRESULT lResult = SendNotifyMessage(XTP_NM_REPORT_CONSTRAINT_SELECTING, (NMHDR*)&nmConstraint);
- return lResult != 0;
- }
- const XTP_NM_REPORTTOOLTIPINFO& CXTPReportControl::OnGetToolTipInfo(CXTPReportRow* pRow, CXTPReportRecordItem* pItem, CString& rstrToolTipText)
- {
- ::ZeroMemory(m_pCachedToolTipInfo, sizeof(XTP_NM_REPORTTOOLTIPINFO));
- m_pCachedToolTipInfo->pRow = pRow;
- m_pCachedToolTipInfo->pItem = pItem;
- m_pCachedToolTipInfo->pstrText = &rstrToolTipText;
- SendNotifyMessage(XTP_NM_REPORT_GETTOOLTIPINFO, (NMHDR*)m_pCachedToolTipInfo);
- return *m_pCachedToolTipInfo;
- }
- CRect CXTPReportControl::GetElementRect(int nElement) const
- {
- switch(nElement)
- {
- case xtpReportElementRectGroupByArea : return m_rcGroupByArea; break;
- case xtpReportElementRectHeaderArea : return m_rcHeaderArea; break;
- case xtpReportElementRectFooterArea : return m_rcFooterArea; break;
- case xtpReportElementRectHeaderRecordsArea : return m_rcHeaderRecordsArea; break;
- case xtpReportElementRectFooterRecordsArea : return m_rcFooterRecordsArea; break;
- case xtpReportElementRectHeaderRecordsDividerArea : return m_rcHeaderRecordsDividerArea; break;
- case xtpReportElementRectFooterRecordsDividerArea : return m_rcFooterRecordsDividerArea; break;
- default : return m_rcReportArea; break;
- }
- }
- void CXTPReportControl::EnableMarkup(BOOL bEnable)
- {
- m_pRecords->EnableMarkup(bEnable);
- }
- CXTPMarkupContext* CXTPReportControl::GetMarkupContext() const
- {
- return m_pRecords->GetMarkupContext();
- }