int CEnHeaderCtrl::GetNextVisibleItem(int nItem, BOOL bNext) const { CIntArray aOrder; int nNumItems = GetItemOrder(aOrder); int nPos = GetItemPosition(nItem, aOrder); if (nPos != -1) { if (bNext) { while (++nPos < nNumItems) { nItem = OrderToIndex(nPos); if (IsItemVisible(nItem) && GetItemWidth(nItem)) return nItem; } } else { while (nPos--) { nItem = OrderToIndex(nPos); if (IsItemVisible(nItem) && GetItemWidth(nItem)) return nItem; } } } // outside range return -1; }
int CHeaderCtrlExt::FindVisibleItem(int nIndex) { if(GetVisible(nIndex))return nIndex; int nOrder = IndexToOrder(nIndex); while(nOrder > 0) { nIndex = OrderToIndex(--nOrder); if(GetVisible(nIndex))return nIndex; } return -1; }
//**************************************************************************************** BOOL CBCGPGridSerializeManager::GetBoundingRange (CBCGPGridRange& rangeIndex, const CBCGPGridItemID& idTo) { // range is index // idTo is order ASSERT (m_pOwnerGrid != NULL); BOOL bFirst = TRUE; CBCGPGridRange rangeOrder; for (int i = 0; i < GetRangeCount (); i++) { CBCGPGridRange r2; if (ArrangeRange (i, r2)) { if (bFirst) { rangeOrder = r2; } else { m_pOwnerGrid->UnionRange (&rangeOrder, &r2); } bFirst = FALSE; } else { return FALSE; } } if (idTo.m_nColumn != -1 && idTo.m_nRow != -1) { rangeOrder.m_nLeft += idTo.m_nColumn; rangeOrder.m_nRight += idTo.m_nColumn; rangeOrder.m_nTop += idTo.m_nRow; rangeOrder.m_nBottom += idTo.m_nRow; if (rangeOrder.m_nBottom > m_nLastRow || rangeOrder.m_nRight > m_nLastColumn) { return FALSE; // out of grid range } } if (!OrderToIndex (rangeOrder, rangeIndex)) { return FALSE; } return !bFirst; }
//**************************************************************************************** BOOL CBCGPGridSerializeManager::CanReplaceNewSelection (CBCGPGridItemID idTo, BOOL bQueryNonEmptyItems) { ASSERT (m_pOwnerGrid != NULL); BOOL bPrevQuery = FALSE; // call OnQueryClearNonEmptyItem only once for (int i = 0; i < GetRangeCount (); i++) { CBCGPGridRange rangeOrder; if (!GetRange (i, rangeOrder)) { return FALSE; } rangeOrder.m_nLeft += idTo.m_nColumn; rangeOrder.m_nRight += idTo.m_nColumn; rangeOrder.m_nTop += idTo.m_nRow; rangeOrder.m_nBottom += idTo.m_nRow; if (rangeOrder.m_nBottom > m_nLastRow || rangeOrder.m_nRight > m_nLastColumn) { return FALSE; // out of grid range } CBCGPGridRange rangeIndex; if (!OrderToIndex (rangeOrder, rangeIndex)) { return FALSE; } if (!m_pOwnerGrid->CanClearRange (rangeIndex, bQueryNonEmptyItems, &bPrevQuery, TRUE)) { return FALSE; } } return TRUE; }
void CElcHeaderCtrl::DrawSkinHeader(CDC* pDC) { CRect rcClient = m_rcClient; rcClient.InflateRect(-1, -1); rcClient.right -= 2; BOOL bMirror = (pDC->GetLayout() == LAYOUT_RTL); CRect rcItem; int nItems = GetItemCount(); if (nItems > 0) { int nLastItem = OrderToIndex(GetItemCount()-1); GetItemRect(nLastItem, rcItem); rcItem.left = rcClient.left; rcItem.top = rcClient.top; rcItem.bottom = rcClient.bottom; rcItem.right = max(rcClient.right, rcItem.right); } else { rcItem = rcClient; } if (bMirror) rcItem = MirrorRect(m_rcClient.Width(), rcItem); thePainter.DrawImageGDI(pDC->m_hDC, &m_skin.background, rcItem, 0, 0, 1, 0); CSize sizeSeparator = CElcSkinDoc::GetImageSize(&m_skin.separator); CSize sizeSort = CElcSkinDoc::GetImageSize(&m_skin.sort); for(int i=0; i < nItems; i++) { TCHAR szText[256] = {0}; HD_ITEM hditem = {0}; hditem.iImage = -1; hditem.mask = HDI_TEXT | HDI_FORMAT | HDI_ORDER | HDI_IMAGE; hditem.pszText = szText; hditem.cchTextMax = 255; GetItem(i, &hditem); GetItemRect(i, rcItem); if (rcItem.IsRectEmpty()) continue; CRect rcSeparator; rcSeparator.left = rcItem.right - sizeSeparator.cx; rcSeparator.top = (rcItem.Height() - sizeSeparator.cy) / 2; rcSeparator.right = rcSeparator.left + sizeSeparator.cx; rcSeparator.bottom = rcSeparator.top + sizeSeparator.cy; thePainter.DrawImageGDI(pDC->m_hDC, &m_skin.separator, bMirror ? MirrorRect(m_rcClient.Width(), rcSeparator) : rcSeparator, 0, 0, 1, 0); CRect rcText = rcItem; rcText.left += 4; rcText.right -= 4; UINT nFormat = DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | DT_WORDBREAK | DT_NOFULLWIDTHCHARBREAK | DT_NOPREFIX; if ((hditem.fmt & LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT) nFormat |= DT_LEFT; else if ((hditem.fmt & LVCFMT_JUSTIFYMASK) == LVCFMT_CENTER) nFormat |= DT_CENTER; else if ((hditem.fmt & LVCFMT_JUSTIFYMASK) == LVCFMT_RIGHT) nFormat |= DT_RIGHT; if (hditem.iImage != -1 && m_skin.sort.pImage) { CRect rcDest; rcDest.right = rcItem.right - 4; rcDest.left = rcDest.right - sizeSort.cx; rcDest.top = rcItem.top + (rcItem.Height() - sizeSort.cy) / 2; rcDest.bottom = rcDest.top + sizeSort.cy; thePainter.DrawImageGDI(pDC->m_hDC, &m_skin.sort, bMirror ? MirrorRect(m_rcClient.Width(), rcDest) : rcDest, hditem.iImage, 0, 0, 0); rcText.right = rcDest.left - 4; } rcText.OffsetRect(1, 1); pDC->SetTextColor(m_skin.crTextShadow); pDC->DrawText(szText, rcText, nFormat); rcText.OffsetRect(-1, -1); pDC->SetTextColor(m_skin.crText); pDC->DrawText(szText, rcText, nFormat); } }
void CFlatHeaderCtrl::DrawCtrl(CDC* pDC) { CRect rectClip; if (pDC->GetClipBox(&rectClip) == ERROR) return; CRect rectClient, rectItem; GetClientRect(&rectClient); pDC->FillSolidRect(rectClip, m_cr3DFace); INT iItems = GetItemCount(); ASSERT(iItems >= 0); CPen penHighLight(PS_SOLID, 1, m_cr3DHighLight); CPen penShadow(PS_SOLID, 1, m_cr3DShadow); CPen* pPen = pDC->GetCurrentPen(); CFont* pFont = pDC->SelectObject(GetFont()); pDC->SetBkColor(m_cr3DFace); pDC->SetTextColor(m_crText); INT iWidth = 0; for(INT i=0;i<iItems;i++) { INT iItem = OrderToIndex(i); TCHAR szText[FLATHEADER_TEXT_MAX]; HDITEM hditem; hditem.mask = HDI_WIDTH|HDI_FORMAT|HDI_TEXT|HDI_IMAGE|HDI_BITMAP; hditem.pszText = szText; hditem.cchTextMax = sizeof(szText); VERIFY(GetItem(iItem, &hditem)); VERIFY(GetItemRect(iItem, rectItem)); if (rectItem.right >= rectClip.left || rectItem.left <= rectClip.right) { if(hditem.fmt&HDF_OWNERDRAW) { DRAWITEMSTRUCT disItem; disItem.CtlType = ODT_BUTTON; disItem.CtlID = GetDlgCtrlID(); disItem.itemID = iItem; disItem.itemAction = ODA_DRAWENTIRE; disItem.itemState = 0; disItem.hwndItem = m_hWnd; disItem.hDC = pDC->m_hDC; disItem.rcItem = rectItem; disItem.itemData = 0; DrawItem(&disItem); } else { rectItem.DeflateRect(m_iSpacing, 0); DrawItem(pDC, rectItem, &hditem, iItem == m_iSortColumn, m_bSortAscending); rectItem.InflateRect(m_iSpacing, 0); if(m_nClickFlags&MK_LBUTTON && m_iHotIndex == iItem && m_hdhtiHotItem.flags&HHT_ONHEADER) pDC->InvertRect(rectItem); } if(i < iItems-1) { pDC->SelectObject(&penShadow); pDC->MoveTo(rectItem.right-1, rectItem.top+2); pDC->LineTo(rectItem.right-1, rectItem.bottom-2); pDC->SelectObject(&penHighLight); pDC->MoveTo(rectItem.right, rectItem.top+2); pDC->LineTo(rectItem.right, rectItem.bottom-2); } } iWidth += hditem.cxy; } if(iWidth > 0) { rectClient.right = rectClient.left + iWidth; pDC->Draw3dRect(rectClient, m_cr3DHighLight, m_cr3DShadow); } pDC->SelectObject(pFont); pDC->SelectObject(pPen); penHighLight.DeleteObject(); penShadow.DeleteObject(); }
void CFlatHeaderCtrl::AutoSizeItemsImpl(INT iItem) { ASSERT(iItem >= -1); INT i, iItems = GetItemCount(), iTemp; INT iOrder = -1; if(iItems <= 0) return; HDITEM hditem; HDITEMEX hditemex; if(iItem >= 0) { hditem.mask = HDI_ORDER; GetItem(iItem, &hditem); iOrder = hditem.iOrder; if(iOrder == iItems-1) { iItem = -1; iOrder = -1; } } CArray<FHAUTOSIZE, FHAUTOSIZE&> arrayItems; arrayItems.SetSize(iItems); INT iWidth = 0; INT iMinWidth = 0; INT iMaxWidth = 0; for(i=iOrder+1; i<iItems; i++) { INT iIndex = OrderToIndex(i); hditem.mask = HDI_WIDTH; VERIFY(GetItem(iIndex, &hditem)); VERIFY(GetItemEx(iIndex, &hditemex)); FHAUTOSIZE fhas; fhas.iIndex = iIndex; fhas.iWidth = hditem.cxy; fhas.iMinWidth = hditemex.iMinWidth; fhas.iMaxWidth = hditemex.iMaxWidth; arrayItems[i] = fhas; iWidth += fhas.iWidth; iMinWidth += fhas.iMinWidth; iMaxWidth += MAXWIDTH(fhas.iMaxWidth); } ASSERT(GetParent() != NULL); CRect rectClient; GetParent()->GetClientRect(rectClient); if(rectClient.Width() <= 0) return; INT iClientWidth = max(rectClient.Width(), iMinWidth); if(iItem >= 0) { CRect rectItem; GetItemRect(iItem, rectItem); iClientWidth -= rectItem.right; } if(iOrder >= 0) { FHAUTOSIZE& fhas = arrayItems[iOrder]; iTemp = min(fhas.iWidth, iClientWidth - iMinWidth); iTemp = max(fhas.iMinWidth, iTemp); iTemp = min(MAXWIDTH(fhas.iMaxWidth), iTemp); arrayItems[iOrder].iWidth = iTemp; iWidth -= iTemp; iClientWidth -= iTemp; } iWidth = max(1, iWidth); INT iResult = 0; for(i=iOrder+1; i<iItems; i++) { FHAUTOSIZE& fhas = arrayItems[i]; iTemp = max(fhas.iMinWidth, (fhas.iWidth * iClientWidth)/iWidth); iTemp = min(MAXWIDTH(fhas.iMaxWidth), iTemp); arrayItems[i].iWidth = iTemp; iResult += iTemp; } if(iResult != iClientWidth) { INT iLast = -1; i = iOrder+1; while(iResult != iClientWidth && iResult != iLast) { FHAUTOSIZE& fhas = arrayItems[i]; iTemp = fhas.iWidth; if(iResult < iClientWidth && iTemp < MAXWIDTH(fhas.iMaxWidth)) { iTemp = min(iTemp+1, MAXWIDTH(fhas.iMaxWidth)); iResult += iTemp - fhas.iWidth; } else if(iResult > iClientWidth && iTemp > fhas.iMinWidth) { iTemp = max(iTemp-1, fhas.iMinWidth); iResult -= fhas.iWidth - iTemp; } iLast = iResult; arrayItems[i].iWidth = iTemp; i = i+1 < iItems ? i+1:iOrder+1; } } m_bAutoSizing = TRUE; for(i=iOrder+1; i<iItems; i++) { hditem.mask = HDI_WIDTH; hditem.cxy = arrayItems[i].iWidth; VERIFY(SetItem(arrayItems[i].iIndex, &hditem)); } m_bAutoSizing = FALSE; }
void CSHeaderCtrl::DrawCtrl(CDC* pDC) { CRect rectClip; if (pDC->GetClipBox(&rectClip) == ERROR) return; CRect rectClient, rectItem; GetClientRect(&rectClient); // pDC->FillSolidRect(rectClient, m_cr3DFace); COLORREF colorStart = RGB(255, 255, 255); COLORREF colorEnd = RGB(199, 210, 226); gtb::DrawGradient(pDC, &rectClient, colorStart, colorEnd, FALSE); int iItems = GetItemCount(); ASSERT(iItems >= 0); CPen* pOldPen = pDC->GetCurrentPen(); CFont* pOldFont = pDC->SelectObject(GetFont()); COLORREF oldBkColor = pDC->SetBkColor(m_cr3DFace); pDC->SetTextColor(m_crBtnText); CPen penBorder(PS_SOLID, 1, m_crBorder); int iWidth = 0; CRect rectInter; for (int i = 0; i < iItems; i++) { int iItem = OrderToIndex(i); TCHAR szText[FLATHEADER_TEXT_MAX]; HDITEM hditem; hditem.mask = HDI_WIDTH|HDI_FORMAT|HDI_TEXT|HDI_IMAGE|HDI_BITMAP; hditem.pszText = szText; hditem.cchTextMax = sizeof(szText); VERIFY(GetItem(iItem, &hditem)); VERIFY(GetItemRect(iItem, rectItem)); //The item should be repaint rectClip.InflateRect(1, 0); //Inflate 1 pixel for the separator if(rectInter.IntersectRect(&rectItem, &rectClip)) { //Owner draw if (hditem.fmt & HDF_OWNERDRAW) { DRAWITEMSTRUCT disItem; disItem.CtlType = ODT_BUTTON; disItem.CtlID = GetDlgCtrlID(); disItem.itemID = iItem; disItem.itemAction = ODA_DRAWENTIRE; disItem.itemState = 0; disItem.hwndItem = m_hWnd; disItem.hDC = pDC->m_hDC; disItem.rcItem = rectItem; disItem.itemData = 0; DrawItem(&disItem); } //Draw by this else { rectItem.DeflateRect(m_nSpace, 0); DrawItem(pDC, rectItem, &hditem); rectItem.InflateRect(m_nSpace, 0); } //Draw separator if(m_bDividerLines) { pDC->SelectObject(&penBorder); pDC->MoveTo(rectItem.right, rectItem.top); pDC->LineTo(rectItem.right, rectItem.bottom); } } iWidth += hditem.cxy; } //Draw Border: bottom only pDC->FillSolidRect(rectClient.left, rectClient.bottom, rectClient.Width(), -1, m_crBorder); pDC->SetBkColor(oldBkColor); pDC->SelectObject(pOldFont); pDC->SelectObject(pOldPen); penBorder.DeleteObject(); }
//**************************************************************************************** BOOL CBCGPGridSerializeManager::DoDropItems (CBCGPGridItemID idDropTo, CBCGPGridItemID idDragFrom, BOOL bMove) { // idDropTo - index // idDragFrom - index ASSERT (m_pOwnerGrid != NULL); ASSERT (m_ClipboardFormatType == CF_Items); if (GetRangeCount () == 0) { return FALSE; // no data } //--------------------- // Calculate new offset //--------------------- CBCGPGridItemID idTo = GetDropOffset (idDragFrom, idDropTo); ASSERT (idTo.m_nRow >= 0); ASSERT (idTo.m_nColumn >= 0); //------------------------------------ // Can replace content of target area: //------------------------------------ if (!m_bSkipData) { if (!CanReplaceNewSelection (idTo, TRUE)) { return FALSE; // can't clear non empty items } } if (!m_bSkipData && bMove) { //------------------------------------- // Clear content of previous selection: //------------------------------------- if (!ClearPreviousSelection (FALSE)) { return FALSE; // can't clear non empty items } } //------------- // Drop ranges: //------------- int i = 0; for (i = 0; i < GetRangeCount (); i++) { CBCGPGridRange rangeOrder; if (!GetRange (i, rangeOrder)) { return FALSE; } rangeOrder.m_nLeft += idTo.m_nColumn; rangeOrder.m_nRight += idTo.m_nColumn; rangeOrder.m_nTop += idTo.m_nRow; rangeOrder.m_nBottom += idTo.m_nRow; if (rangeOrder.m_nBottom > m_nLastRow || rangeOrder.m_nRight > m_nLastColumn) { return FALSE; // out of grid range } //------------ // Drop range: //------------ UINT nDataSize = 0; BYTE* pData = GetRangeData (i, nDataSize); if (pData == NULL || nDataSize <= 0) { return FALSE; } CMemFile f(pData, nDataSize); CArchive archive (&f, CArchive::load | CArchive::bNoFlushOnDelete); if (!ReadItemsFromArchive (archive, rangeOrder)) { return FALSE; } archive.Close (); } if (!m_bSkipData) { //--------------------------- // Remove previous selection: //--------------------------- UpdateSelectionRect (m_idRangesOffset); //--------------- // Set selection: //--------------- BOOL bFirst = TRUE; for (i = 0; i < GetRangeCount (); i++) { CBCGPGridRange rangeOrder; if (!GetRange (i, rangeOrder)) { continue; } rangeOrder.m_nLeft += idTo.m_nColumn; rangeOrder.m_nRight += idTo.m_nColumn; rangeOrder.m_nTop += idTo.m_nRow; rangeOrder.m_nBottom += idTo.m_nRow; CBCGPGridRange rangeIndex; if (!OrderToIndex (rangeOrder, rangeIndex)) { continue; } CBCGPGridItemID idFirst (rangeIndex.m_nTop, rangeIndex.m_nLeft); CBCGPGridItemID idSecond (rangeIndex.m_nBottom, rangeIndex.m_nRight); DWORD dwSelMode = bFirst ? SM_SINGE_SEL_GROUP : SM_ADD_SEL_GROUP; bFirst = FALSE; m_pOwnerGrid->SetCurSel (idFirst, SM_FIRST_CLICK | dwSelMode, FALSE); m_pOwnerGrid->SetCurSel (idSecond, SM_SECOND_CLICK | SM_CONTINUE_SEL_GROUP, FALSE); } UpdateSelectionRect (idTo); } return TRUE; }