|
I had the same problem when I scrolled verticaly. The two bugs are identical so what I have done for my problem can be easily adapted for yours.
In the GridCtrl.cpp file, search for the OnDraw function. Then inside of this function, we have a part commented as :
// draw rest of non-fixed cells"
Inside this block of code, begining with
<br />
rect.bottom = nFixedRowHeight-1;<br />
for (row = minVisibleRow; row <= maxVisibleRow; row++)<br />
You will find the following line :
<br />
if(!pCell->IsMergeWithOthers())<br />
Replace it by :
<br />
if(!pCell->IsMergeWithOthers() || row == minVisibleRow )<br />
One of the next lines is :
<br />
pCell->Draw(pDC, row, col, rect, FALSE);<br />
Replace it by :
<br />
if( row == minVisibleRow && pCell->IsMergeWithOthers())<br />
pCell->KLDraw(pDC, row, col, rect, FALSE);<br />
else<br />
pCell->Draw(pDC, row, col, rect, FALSE);<br />
Where KLDraw is exactly the same as the Draw function but without the lines :
<br />
if(m_Hide && !IsMerged())<br />
{<br />
return TRUE;<br />
}<br />
That works for me and solve my problem with the vertical scroll and the resize of the grid.
Minimum changes should be made to solve the same problem with the horizontal croll.
|
|
|
|
|
This is only informtation for those who have the same problem.
I solve it by small changing function
void CGridCtrl::PrintColumnHeadings(CDC *pDC, CPrintInfo* /*pInfo*/)
Main loop I change from:
for (int row = 0; row < GetFixedRowCount(); row++)
to:
for (int row = 0; row < GetRowCount(); row++)
Maybe it isn't "neat" and it is worth to fix it in next version.
Wojtek
|
|
|
|
|
the upper method has bug on printing more pages!!
I solved the problem accurately by changing function
void CGridCtrl::PrintRowButtons(CDC *pDC, CPrintInfo* /*pInfo*/)
removed this code:
<br />
replace by these codes:
<br />
if (pCell)<br />
{<br />
if(!pCell->IsMerged())<br />
{<br />
if(!pCell->IsMergeWithOthers())<br />
{<br />
pCell->PrintCell(pDC, iRow, iCol, rect);<br />
}<br />
}<br />
else<br />
{<br />
CRect mergerect=rect;<br />
if(GetCellRangeRect(pCell->m_MergeRange,&mergerect))<br />
{<br />
mergerect.OffsetRect(rect.TopLeft()-mergerect.TopLeft());<br />
pCell->PrintCell(pDC, iRow, iCol, mergerect);<br />
}<br />
}<br />
}<br />
yuhonggang
|
|
|
|
|
I tried your solution, but the problem is still there.
void CGridCtrl::PrintRowButtons(CDC *pDC, CPrintInfo* /*pInfo*/)
{
CFont *pOldFont = pDC->SelectObject(&m_PrinterFont);
CRect rect;
rect.right = -1;
BOOL bFirst = TRUE;
for( int iCol = 0; iCol < GetFixedColumnCount(); iCol++)
{
rect.left = rect.right+1;
rect.right = rect.left
+ GetColumnWidth( iCol)
- 1;
rect.bottom = -1;
for( int iRow = m_nCurrPrintRow; iRow < GetRowCount(); iRow++)
{
rect.top = rect.bottom+1;
rect.bottom = rect.top + GetRowHeight( iRow) - 1;
if( rect.bottom > m_nPageHeight)
break;
CGridCellBase* pCell = GetCell(iRow, iCol);
if (pCell)
{
//Used for merge cells
if(!pCell->IsMerged())
{
if(!pCell->IsMergeWithOthers())
{
pCell->PrintCell(pDC, iRow, iCol, rect);
}
}
else
{
CRect mergerect=rect;
if(GetCellRangeRect(pCell->m_MergeRange,&mergerect))
{
mergerect.OffsetRect(rect.TopLeft()-mergerect.TopLeft());
pCell->PrintCell(pDC, iRow, iCol, mergerect);
}
}
}
}
}
pDC->SelectObject(pOldFont);
}
Cui Sheng
|
|
|
|
|
When a new color is applied to a cell, the new color covers the bottom and right grid lines around the cell which looks very ugly. I tried Chris Maunder's original version and this did not happen on his version but I need the merge features. Any ideas on how to fix this problem?
Cheers.
|
|
|
|
|
Here is my fix to the problem not showing grid lines when changing cell colors:
In the function CGridCtrl::OnDraw:
1. I removed the following lines:
if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_VERT)
{
int x = nFixedColWidth;
for (col = minVisibleCol; col <= maxVisibleCol; col++)
{
if (GetColumnWidth(col) <= 0) continue;
x += GetColumnWidth(col);
pDC->MoveTo(x-1, nFixedRowHeight);
pDC->LineTo(x-1, VisRect.bottom);
}
}
if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_HORZ)
{
int y = nFixedRowHeight;
for (row = minVisibleRow; row <= maxVisibleRow; row++)
{
if (GetRowHeight(row) <= 0) continue;
y += GetRowHeight(row);
pDC->MoveTo(nFixedColWidth, y-1);
pDC->LineTo(VisRect.right, y-1);
}
}
pDC->SelectStockObject(NULL_PEN);
2. I added lines in the following block marked by a <==Add:
if(!pCell->IsMerged())
{
if(!pCell->IsMergeWithOthers())
{
CRect rtNonMerge = rect; <==Add
rtNonMerge.DeflateRect(0,0,1,1); <==Add
pCell->SetCoords(row,col);
pCell->Draw(pDC, row, col, rect, FALSE);
if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_VERT) <==Add
{ <==Add
pDC->MoveTo(rtNonMerge.right+1, rtNonMerge.top); <==Add
pDC->LineTo(rtNonMerge.right+1, rtNonMerge.bottom+1); <==Add
} <==Add
if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_HORZ) <==Add
{ <==Add
pDC->MoveTo(rtNonMerge.left, rtNonMerge.bottom+1); <==Add
pDC->LineTo(rtNonMerge.right+1, rtNonMerge.bottom+1); <==Add
} <==Add
}
else
{
CGridCellBase* pMergedCell=GetCell(pCell->GetMergeCellID());
CRect mergerect=rect;
if(GetCellRangeRect(pMergedCell->m_MergeRange,&mergerect))
{
mergerect.DeflateRect(0,0,1,1);
pMergedCell->SetCoords(pCell->GetMergeCellID().row,pCell->GetMergeCellID().col);
pMergedCell->Draw(pDC, pCell->GetMergeCellID().row,pCell->GetMergeCellID().col, mergerect, TRUE);
if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_VERT) <==Add
{ <==Add
pDC->MoveTo(mergerect.right+1, mergerect.top); <==Add
pDC->LineTo(mergerect.right+1, mergerect.bottom+1); <==Add
} <==Add
if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_HORZ) <==Add
{ <==Add
pDC->MoveTo(mergerect.left, mergerect.bottom+1); <==Add
pDC->LineTo(mergerect.right+1, mergerect.bottom+1); <==Add
} <==Add
}
}
}
else
{
CRect mergerect=rect;
if(GetCellRangeRect(pCell->m_MergeRange,&mergerect))
{
mergerect.DeflateRect(0,0,1,1);
pCell->SetCoords(row,col);
pCell->Draw(pDC, row, col, mergerect, TRUE);
if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_VERT) <==Add
{ <==Add
pDC->MoveTo(mergerect.right+1, mergerect.top); <==Add
pDC->LineTo(mergerect.right+1, mergerect.bottom+1); <==Add
} <==Add
if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_HORZ) <==Add
{ <==Add
pDC->MoveTo(mergerect.left, mergerect.bottom+1); <==Add
pDC->LineTo(mergerect.right+1, mergerect.bottom+1); <==Add
} <==Add
}
}
3. Finally, I added the following line:
pDC->SelectStockObject(NULL_PEN); before
Hope this helps.
|
|
|
|
|
Great fix! Works really good, thanks a lot!
|
|
|
|
|
An easier fix than the prior posted fix is to simply change how non merged cells are drawn. The
below code adds 2 lines, and changes one line around line 1650 of GridCtrl.cpp
if (pCell)
{
if(!pCell->IsMerged())
{
if(!pCell->IsMergeWithOthers())
{
<font color=blue>CRect cellrect= rect;
cellrect.DeflateRect(0,0,1,1);
pCell->SetCoords(row,col);
pCell->Draw(pDC, row, col, <font color=blue>cellrect</font>, FALSE); <font color=blue>
}
else
{
CGridCellBase* pMergedCell=GetCell(pCell->GetMergeCellID());
CRect mergerect=rect;
if(GetCellRangeRect(pMergedCell->m_MergeRange,&mergerect))
{
mergerect.DeflateRect(0,0,1,1);
pMergedCell->SetCoords(pCell->GetMergeCellID().row,pCell->GetMergeCellID().col);
pMergedCell->Draw(pDC, pCell->GetMergeCellID().row,pCell->GetMergeCellID().col, mergerect, TRUE);
}
}
}
}
|
|
|
|
|
i solve this problem by the following way
in the following function:
void CGridCtrl::OnPrint(CDC *pDC, CPrintInfo *pInfo)
delete the following code:
//Used for merge cells
//by Huang Wei
// CRect white_rect(CPoint(0,0),m_LogicalPageSize);
// white_rect.top=range.bottom+1;
// pDC->FillSolidRect(white_rect,RGB(255,255,255));
|
|
|
|
|
I have seen many thanks for your article here. It's a waste of time to add once more. But I must say THANK YOU FOR YOUR GREATE article!!!
Keep on.
|
|
|
|
|
Hi!
First of all, I want to thank Huang Wei for his great article. It really saved a lot of our time!
But this solution have a little bug.
//...
MergeCells(5,1,5,3)
SetItemText(5,1,"we are the merged columns!");
InsertRow("123", 3);
InsertRow("123", 3);
SetItemText(5,1,"Now I am unmerged-1");
SetItemText(5,2,"Now I am unmerged-2");
SetItemText(5,3,"Now I am unmerged-3");
// ...
When such a code executes, we get a really strange effect. It seems that row 5 still consiger itself "merged" ). Though, if we click come columns in row 5, they are drawn as "unmerged"...
Maybe, someone faced this problem before?
Thanks a lot!
|
|
|
|
|
Hi!
I fixed bug, which I reported before (1 hour ago ))
If you need to fix it too, you should do the following:
1. In class CGridCellBase add variable
BYTE m_bBaseForMerged;
,and two functions:
void CGridCellBase::InflateMergedRange(int cx, int cy){<br />
m_MergeRange.Set(<br />
m_MergeRange.GetMinRow() + cy,<br />
m_MergeRange.GetMinCol() + cx,<br />
m_MergeRange.GetMaxRow() + cy,<br />
m_MergeRange.GetMaxCol() + cx<br />
);<br />
}<br />
<br />
BYTE CGridCellBase::IsBaseForMerged(){<br />
return bBaseForMerged;<br />
}<br />
Also add
m_bBaseForMerged = 0;
in CGridCellBase::Reset, and
m_bBaseForMerged = 1;
in CGridCellBase::SetMergeRange
2. In CGridCtrl add protected function:
<br />
void CGridCtrl::InflateMergedRanges(int nStartRow, int nStartCol, int cx, int cy)<br />
{<br />
for(int i = nStartRow; i < GetRowCount(); i++){<br />
for(int j = nStartCol; j < GetColumnCount(); j++){<br />
if(GetCell(i, j)->IsBaseForMerged()){<br />
GetCell(i, j)->InflateMergedRange(cx, cy); <br />
}<br />
}<br />
}<br />
}<br />
3. In CGridCtrl::InsertRow add:
InflateMergedRanges(nRow, 0, 0, 1);
, in CGridCtrl::DeleteRow:
InflateMergedRanges(nRow, 0, 0, -1);
In CGridCtrl::InsertColumn add:
InflateMergedRanges(0, nColumn, 1, 0);
, in CGridCtrl::DeleteColumn:
InflateMergedRanges(0, nColumn, -1, 0);
(All these calls I added before ResetScrollBars() call)
4. Enjoy
PS. This code isn't perfect... but it works Of course, code for CGridCtrl::InflateMergedRanges is not perfect at all Maybe, we better need to create some array, which contains all pointers to all m_MergeRanges, or do something else. Unfortunately, I have no time to write it now ;(
Hope, though, it would be useful for someone
|
|
|
|
|
Note that
<br />
BYTE CGridCellBase::IsBaseForMerged()<br />
{<br />
return bBaseForMerged;<br />
}<br />
<br />
should be:<br />
<br />
BYTE CGridCellBase::IsBaseForMerged(){<br />
return m_bBaseForMerged;<br />
}<br />
|
|
|
|
|
Hello,
Thanks for your code.
bug minor bug...
When I merge cells,
and then, Insert row, before merged cells..
Your solution is good..
but...
When I click merged cell(moved.. successfully)....
Or move down cell use (Key down)...
--> Minor bug...
Please solve this problem..^^
Thanks...
|
|
|
|
|
I can't help you. I am not a MFC Grid Guru! For me it functions well, or appears to work sufficiently for my needs.
Andrew
|
|
|
|
|
I implemented your code several months ago. But there is one bug that I can't find the solution to
If your merged cells are the last row in the grid, the program crashes when deleting a row.
Can you help me fix this as I would like to have the ability to delete a row without the program crashing.
Can anyone help me?
Andrew
-- modified at 3:14 Wednesday 24th May, 2006
|
|
|
|
|
I want to load or save the grid like excel fils include
merge cells
thanks
hfghfghfghfg
|
|
|
|
|
Declare CGridCellBase CGridCell CGridDefaultCell and CGridCtrl as serialable, then add Serialize(CArchive &ar) functions for them
|
|
|
|
|
I use our source with the grid 2.24. I'm not quite sure if i missed some lines of our code, but the merge is not working correctly.
I have a grid with 10 rows and 4 cols, where 1 col is fixed. If i merge the cells (1,2) -> (1,4) and then double click with the mouse on the area of (1,3) or (1,4) I still get the editbox for this cell.
this also happends if i navigate with the cursor and press F2...
is this a know bug, or does anyone knows a workaround for this??
thanks
Ben
|
|
|
|
|
here is my solution:
1.
I added a private function
BOOL IsNotSameCell(CCellID& next, CCellID orgCellID);
which looks like this:
BOOL CGridCtrl::IsNotSameCell(CCellID& next, CCellID orgCellID)
{
CGridCellBase* pCell;
pCell = GetCell(next.row, next.col);
if (pCell)
{
if(!pCell->IsMerged())
{
if(!pCell->IsMergeWithOthers())
return TRUE;
else
{
if (pCell->GetMergeCellID() != orgCellID)
{
next = pCell->GetMergeCellID();
return TRUE;
}
}
}
else
if (next != orgCellID)
return TRUE;
}
else
return TRUE;
return FALSE;
}
2.
In the function "OnKeyDown" I replaced
bFoundVisible = TRUE;<br />
break;
with
if (IsNotSameCell(next, orgCellID))
{
bFoundVisible = TRUE;
break;
}
everywhere i found it:
1x in nChar == VK_DOWN
1x in nChar == VK_UP
2x in nChar == VK_LEFT
2x in nChar == VK_RIGHT >
3.
In the same function under
"else if (nChar == VK_RIGHT || (nChar == VK_TAB && !IsSHIFTpressed()) )"
I added:
if (nChar == VK_TAB)
{
pCell = GetCell(next.row, next.col-1);
if (pCell)
{
if(pCell->IsMerged())
{
CCellRange cellRange = pCell->GetMergeRange();
next.col = cellRange.GetMaxCol() + 1;
}
}
...
4.
In the same function under
"else if (nChar == VK_LEFT || (nChar == VK_TAB && IsSHIFTpressed()) )"
I added:
if (nChar == VK_TAB)
{
pCell = GetCell(next.row, next.col+1);
if (pCell)
{
if(pCell->IsMerged())
{
CCellRange cellRange = pCell->GetMergeRange();
next.col = cellRange.GetMinCol() - 1;
}
}
...
I havn't changed anything for the HOME or END key since i don't need that, but i think i will work in the same way.
5.
for the handling of mouse click events i added these lines at the end of the "GetCellFromPt" function:
...
CGridCellBase* pCell;
pCell = GetCell(cellID.row, cellID.col);
if (pCell)
{
if(!pCell->IsMerged())
{
if(pCell->IsMergeWithOthers())
cellID = pCell->GetMergeCellID();
}
}
return cellID;
}
hope i havn't forgot a line
ben
|
|
|
|
|
Use Virtual Mode,and Merge Cells
it's error
what can i do,please
使用虚表格的时候不能合并单元格!
|
|
|
|
|
after adding the Merge Code In the GridCtrl.cpp( all changes in Your Demo i made the same in my project)Borders between Cells Disapper when Select more than one cell.
Note
the problem is found also in your demo to see the difference try to select more than one cell in your Demo ,and do the same in the Chres Mandur Application Without Adding the merge code ,in your demo you will see that Borders Between Cells Dosn't Appear
Mahmoud
|
|
|
|
|
I added couple lines to Wei source to
show the border of the cells.
filename: gridctrl.cpp
line number: 1646 where draws non-fixed cells
if(!pCell->IsMerged())
{
if(!pCell->IsMergeWithOthers())
{
CRect rtNonMerge = rect; <== here
rtNonMerge.DeflateRect(0,0,1,1); <== here
pCell->SetCoords(row,col);
pCell->Draw(pDC, row, col, rtNonMerge, FALSE);
...
Chris draws Cells first and then the gridlinew, whereas
Wei draws gridlines first and then the cell. Therefore, all drawn cells must deflate or else it will draw on top of the gridline.
|
|
|
|
|
first i thank you for your interest but this two lines dosn't solve the problem that after i add them in the postion that you determine :
filename: gridctrl.cpp
line number: 1646 where draws non-fixed cells
but the lines dosn't appear ?
i have solved it but with complicated technique but it very long so if you want to take alook for this solution send me mail on (m_abosafia@hotmail.com)
so if you can solve it by your method please send me also>>>>>
mahmoud
abosafia
|
|
|
|
|
First i would thank you for your merge that i was need it very much in my project but some problems still i have :-
1- after merging Cells ,then if i click LeftButton of mouse on any postion in this merged area ,the cell border of this clicked postion will be showed but after remove the mouse the border will disappear and the value of this cell, so merging has no meaning since users still see the original cells if they click by mouse on any postion.
2-when the focus in this merged area ,if I want to move to other cell that outside this merged area ,by left,right,up,or down keys it require to press the key(down for example)more than on times
example: if i merge cells (5,4),(5,5),(5,6),and(5,7) so after merge if focus in this merged area ,and i want to move to cell (5,8),it will require press the right button (four times)
so please help me to continue my work
|
|
|
|
|