|
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
|
|
|
|
|
Did you find answers? I have problems when moving into a merged row via a cursor key and it renders the cell..
|
|
|
|
|
When the year value of Date Time Picker Control is modified from 2003 to more than 2038, there is a big bug. It cannot work well. Why?
hi, I'm Janeyre
|
|
|
|
|
Thank U! Your advice is very helpful.
But I fix this bug after I change all "CTime" class to "COleDateTime" class. Because the Date Time Picker Control has two function about GetTime():
1: GetTime(CTime...)
2: GetTime(COleDateTime...)
first function calls mktime() which cannot return right value when the input date exceeds the "limit" date definition in the regional settings in the control panel of PC. It's the problem of the bug.
while the second function can work well.
|
|
|
|
|
Why did you choose to make your changes stright into Chris' code?
What should we do when Chris posts an update of his original control?
Wouldn't it be better to implement the new features in derived classes?
|
|
|
|
|
Does anyone try to merge cells in virtual mode? The result is fine...
|
|
|
|
|
There is a compiler error at unicode:
OnGetText has a wrong type cast for lstrcpyn. Here is the fix:
LRESULT CCheckComboBox::OnGetText(WPARAM wParam, LPARAM lParam)
{
// Make sure the text is updated
RecalcText();
if (lParam == 0)
return 0;
// Copy the 'fake' window text
lstrcpyn((LPTSTR)lParam, m_strText, (INT)wParam);
return m_strText.GetLength();
}
|
|
|
|
|
I've fixed the bug that I've reported earlier (with merging in the corner).
Top-left fixed cells are processed separately in CGridCtrl::OnDraw function,
so you should add the same code for the fourh time to repaint them correctly:
// draw top-left cells 0..m_nFixedRows-1, 0..m_nFixedCols-1
rect.bottom = -1;
for (row = 0; row < m_nFixedRows; row++)
{
if (GetRowHeight(row) <= 0) continue;
rect.top = rect.bottom+1;
rect.bottom = rect.top + GetRowHeight(row)-1;
rect.right = -1;
for (col = 0; col < m_nFixedCols; col++)
{
if (GetColumnWidth(col) <= 0) continue;
rect.left = rect.right+1;
rect.right = rect.left + GetColumnWidth(col)-1;
pCell = GetCell(row, col);
/* if (pCell)
{
pCell->SetCoords(row,col);
pCell->Draw(pDC, row, col, rect, FALSE);
}*/
if (pCell)
{
//Used for merge cells by Huang Wei
//bugfix by Luther Bruck
if(!pCell->IsMerged())
{
if(!pCell->IsMergeWithOthers())
{
pCell->SetCoords(row,col);
pCell->Draw(pDC, row, col, rect, FALSE);
}
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);
}
}
}
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);
}
}
}
}
Huang, could you add this code to future versions of MergeCells?
|
|
|
|
|
I've added your code ,thank you
|
|
|
|
|