|
There are some comments reporting problems with not updated selection maps when RVN_SELECTIONCHANGED is received.
Because I also had trouble with that issue I tried to rewrite the SelectRows method of CReportCtrl.
Notice that the behaviour of the message SELECTIONCHANGED is a little bit different:
There will only be one message for the first selected item.
No messages are sent when an item becomes unselected.
The new state of the first item is not sent as parameter (always the same).
I also publish this method to get reports about bugs. So be so kind and tell me if there are problems with this method, please.
Philipp Grohs
PS. I hope you understood what I tried to express in my poor school English.
void CReportCtrl::SelectRows(INT iFirst, INT iLast, BOOL bSelect, BOOL bKeepSelection, BOOL bInvert, BOOL bNotify)
{
if(m_dwStyle&RVS_SINGLESELECT){
iLast = iFirst;
bKeepSelection = FALSE;
}
if(m_iFocusRow > RVI_INVALID &&
iFirst != m_iFocusRow)
{
SetState(m_iFocusRow, 0, RVIS_FOCUSED);
RedrawRows(m_iFocusRow);
}
m_iFocusRow = iFirst;
SetState(iFirst, RVIS_FOCUSED, RVIS_FOCUSED);
if(iFirst > iLast){
iLast += iFirst;
iFirst = iLast - iFirst;
iLast -= iFirst;
}
if(!bKeepSelection && bSelect){
CList<POSITION, POSITION&> cRemList;
for(POSITION Pos = m_listSelection.GetHeadPosition(); Pos != NULL; ){
INT iItem = m_listSelection.GetAt(Pos);
INT iRow = GetRowFromItem(iItem);
UINT nOldState = 0;
UINT nNewState = 0;
nOldState = nNewState = GetState(iRow);
if((iRow < iFirst || iRow > iLast) &&
nOldState & RVIS_SELECTED)
{
nNewState &= ~RVIS_SELECTED;
if(nNewState != nOldState){
if(bNotify && Notify(RVN_SELECTIONCHANGING,
iItem, -1, nNewState) == TRUE)
{
continue;
}
cRemList.AddTail(Pos);
SetState(iRow, nNewState, RVIS_SELECTED);
RedrawRows(iRow);
}
}
m_listSelection.GetNext(Pos);
}
while(!cRemList.IsEmpty())
m_listSelection.RemoveAt(cRemList.RemoveHead());
}
if(bSelect){
for(INT iRow = iFirst; iRow <= iLast; iRow++){
INT iItem = GetItemFromRow(iRow);
UINT nOldState = 0;
UINT nNewState = 0;
nOldState = nNewState = GetState(iRow);
if(bInvert == TRUE)
nNewState ^= RVIS_SELECTED;
else nNewState |= RVIS_SELECTED;
if(nNewState != nOldState){
if(bNotify && Notify(RVN_SELECTIONCHANGING,
iItem, -1, nNewState) == TRUE)
{
continue;
}
POSITION Pos = m_listSelection.Find(iItem);
if((nNewState & RVIS_SELECTED) && Pos == NULL)
m_listSelection.AddTail(iItem);
else if(bInvert == TRUE)
m_listSelection.RemoveAt(Pos);
SetState(iRow, nNewState, RVIS_SELECTED);
RedrawRows(iRow);
}
}
}
if(bNotify)
Notify(RVN_SELECTIONCHANGED, GetItemFromRow(iFirst));
UpdateWindow();
}
|
|
|
|
|
there is a small bug when RVS_TREEMASK and RVS_FOCUSSUBITEMS are enabled:
<br />
void CReportCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)<br />
.<br />
.<br />
case VK_LEFT:<br />
.<br />
.<br />
<br />
iFirst = GetRowFromItem(m_iFocusRow);<br />
RedrawRows( iFirst );<br />
<br />
.<br />
.<br />
should be changed to
<br />
<br />
RedrawRows( m_iFocusRow );<br />
<br />
The same bug is in case VK_RIGHT.
Hope this is useful for you too.
With best regards
Frank Kobs
Palette CAD GmbH
|
|
|
|
|
Dear Maarten,
thanks for sharing this excellent written control! It's really what I was looking for.
As others mentioned, some sourcecode doc (at least some comments on the styles and properties) would have been good, but I will not complain. Better a good control without comments than a lousy control with comments
However, I have made some additions which someone might be useful: Drawing lines on the tree:
here is the code:
Inside void CReportCtrl::DrawRow() locate:
.
.
.
if(iColumn == 0 && lprvi->iIndent >= 0)
{
if(lprvi->nState&RVIS_TREEMASK)
{
rectItem.left -= m_iDefaultHeight;
DrawTreeBox(pDC, rectItem, lprvi->nState&RVIS_TREEOPENED);
rectItem.left += m_iDefaultHeight;
}
.
.
.
}
and add:
.
.
.
if(iColumn == 0 && lprvi->iIndent >= 0)
{
LPTREEITEM lpti = m_arrayItems[lprvi->iItem].lptiItem;
CRect rectTreeLines( rectItem );
for (int n=0;n<lprvi->iIndent;n++)
{
int nDrawMode = 0;
if (n == 0)
nDrawMode += 2;
ASSERT( lpti );
if (lpti && lpti->lptiSibling)
nDrawMode += 1;
rectTreeLines.left -= m_iDefaultHeight;
DrawTreeLines(pDC, rectTreeLines, nDrawMode );
lpti = lpti->lptiParent;
}
if(lprvi->nState&RVIS_TREEMASK)
{
rectItem.left -= m_iDefaultHeight;
DrawTreeBox(pDC, rectItem, lprvi->nState&RVIS_TREEOPENED);
rectItem.left += m_iDefaultHeight;
}
.
.
.
}
Finally code the DrawTreeLines function (don't forget to add it to header)
void CReportCtrl::DrawTreeLines(CDC* pDC, CRect rectBox, INT nDrawMode)
{
if(rectBox.right < rectBox.left)
return;
if (nDrawMode == 0)
return;
rectBox.right = rectBox.left + rectBox.Height();
CPoint point = rectBox.CenterPoint();
CPen pen(PS_SOLID, 1, RGB(192,192,192));
CPen* pPen = pDC->SelectObject(&pen);
switch (nDrawMode)
{
case 1:
pDC->MoveTo( point.x, rectBox.top );
pDC->LineTo( point.x, rectBox.bottom );
break;
case 2:
pDC->MoveTo( point.x, rectBox.top );
pDC->LineTo( point.x, point.y );
pDC->LineTo( rectBox.right, point.y );
break;
case 3:
pDC->MoveTo( point.x, rectBox.top );
pDC->LineTo( point.x, rectBox.bottom );
pDC->MoveTo( point.x, point.y );
pDC->LineTo( rectBox.right, point.y );
break;
default:
ASSERT( FALSE );
}
pDC->SelectObject(pPen);
}
Maybe some optimizations can be done but generally it seems to work.
With best regards,
Frank Kobs
Palette CAD GmbH
|
|
|
|
|
you have a little bug, you should replace :
for (int n=0;niIndent;n++)
by
for (int n=0;n < iIndent;n++)
thanks for your code !
|
|
|
|
|
Thanks for the fix - was obviously a typo!
Good to see that this code (even if it's old) is still useful for others!
With best regards,
Frank
|
|
|
|
|
Hi!
I created a dialog class and a member variable in my view.
in the OnCreate event i assigned the parent to the
CReportCtrl member variable (which I allready created):
m_wndContactsDetails.Create(IDD_FRMCONTACT, &m_wndReportCtrl);
I keep track on the expanded (previewed) item and on the OnRvnItemDrawPreview event I do:
m_wndContactsDetails.MoveWindow(&lpnmrvdp->rect);
in order to display the dialog in the preview area
all works well except in case I scroll the ReportCtrl down and the expanded item is the first - the dialog remains shown.
if instead I do the dc.DrawText function - it disappears correctly.
the problem never happens when scrolling up.
how do I solve this? Thanks.
|
|
|
|
|
|
Hi all,
I'm using the SuperGrid Report Control written by Maarten Hoeben and appreciate this software as very multifunctional and convinient as well. But since introduction we have experienced a little trouble with it. I'm wondering why the bug i'm going to describe below hasn't been reported yet.
Bug description:
The thing is, when you are resizing the header in the list control(CFlatHeaderCtrl class) too fast, the software starts recognizing your action in a incorrect way. Actualy, it places itself in the drag and drop mode as though you're going to change column's places. This is an ugly bug because after it is occured, the headers jump out of the grid and become independent from it. One has a little chance to get it in proper position again.
Suggested solution to eliminate the bug
In the class CFlatHeaderCtrl, there is a function called OnMouseMove. Everything one needs, is to check m_bResizing flag when the software means it should start in the drag'n drop mode. The Author already sets und resets that flag properly (I suppose ). Here's the code of the OnMouseMove routine where the bug is not present anymore:
void CFlatHeaderCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
if(m_bButtonDownOnItem && m_nClickFlags&MK_LBUTTON && m_iHotIndex>=0)
{
if(m_bResizing)
CHeaderCtrl::OnMouseMove(nFlags, point);
if(m_hdhtiHotItem.flags&HHT_ONHEADER)
{
if(m_bDragging)
{
..............
..............
}
else if(GetStyle()&HDS_DRAGDROP && m_bResizing == FALSE) // the only change (hanryz)
{
.............
.............
}
}
}
That's it.
The Author's opinion to this solution would be appreciated
So long.
|
|
|
|
|
This is a fantastic contribution with some great functionality.
However, I'm using it in my SDI app in a splitterwnd, when I switchview to a CFormView or other class and then try to go back to CReport it no longer appears leaving the last view still visible and still working.
Does this class lack a refresh view? or something?
I love the column sorting!
|
|
|
|
|
Working through this;
Apparently we need to send and have the following
ON_MESSAGE_VOID(WM_INITIALUPDATE, OnInitialUpdate)
void CMainFrame::OnConfig()
{
m_wndSplitter.ReplaceView(1,1,RUNTIME_CLASS(CSrsConf),CSize(0,26));
m_wndSplitter.GetPane(1,1)->SendMessage(WM_INITIALUPDATE);
}
This works with CFormViews but not CReportView, gives assert errors on line 3613 in ReportCtrl.cpp
ASSERT(lprvi->iSubItem < m_arraySubItems.GetSize());
|
|
|
|
|
Kind of works, after thinking about the error it was giving I thought, what if it can't add the lines 'cos the table is not there?
The bInit var was set to TRUE, stopping the creation of the table. I removed the 'static' keyword and everything works.... or does it?
BOOL bInit = FALSE;
Is this a bad idea? works for me anyway.
Dan
|
|
|
|
|
I changed
LPCTSTR lpsz = GetString();
but still get following error.
ReportCtrl.cpp
..\ReportCtrl\ReportCtrl.cpp(7229) : error C2360: initialization of 'points' is skipped by 'case' label
..\ReportCtrl\ReportCtrl.cpp(7185) : see declaration of 'points'
..\ReportCtrl\ReportCtrl.cpp(7230) : error C2360: initialization of 'points' is skipped by 'case' label
..\ReportCtrl\ReportCtrl.cpp(7185) : see declaration of 'points'
|
|
|
|
|
simple fix for this is to wrap the
Case statements in brackets. ex:
switch (pMsg->message)<br />
{<br />
case WM_LBUTTONDOWN:<br />
{<br />
dwTick = GetTickCount();<br />
bDoubleClick = ((dwTick - m_dwLastLButtonDown) <= m_dwDblClickMsecs);<br />
m_dwLastLButtonDown = dwTick;<br />
<br />
}<br />
case WM_RBUTTONDOWN:<br />
case WM_MBUTTONDOWN:<br />
{<br />
POINTS points = MAKEPOINTS(pMsg->lParam);<br />
POINT point;<br />
point.x = points.x;<br />
point.y = points.y;<br />
<br />
ClientToScreen(&point);<br />
pWnd = WindowFromPoint(point);<br />
<br />
if(pWnd == this)<br />
pWnd = m_pReportCtrl;<br />
<br />
iHitTest = (INT)pWnd->SendMessage(WM_NCHITTEST, 0, MAKELONG(point.x, point.y));<br />
<br />
if(iHitTest == HTCLIENT)<br />
{<br />
pWnd->ScreenToClient(&point);<br />
pMsg->lParam = MAKELONG(point.x,point.y);<br />
}<br />
else<br />
{<br />
switch (pMsg->message)<br />
{<br />
case WM_LBUTTONDOWN: pMsg->message = WM_NCLBUTTONDOWN; break;<br />
case WM_RBUTTONDOWN: pMsg->message = WM_NCRBUTTONDOWN; break;<br />
case WM_MBUTTONDOWN: pMsg->message = WM_NCMBUTTONDOWN; break;<br />
}<br />
<br />
pMsg->wParam = iHitTest;<br />
pMsg->lParam = MAKELONG(point.x,point.y);<br />
}<br />
<br />
Hide();<br />
<br />
pWnd->PostMessage(bDoubleClick ? WM_LBUTTONDBLCLK : pMsg->message,pMsg->wParam,pMsg->lParam);<br />
return TRUE;<br />
}<br />
case WM_KEYDOWN:<br />
case WM_SYSKEYDOWN:<br />
{<br />
Hide();<br />
m_pReportCtrl->PostMessage(pMsg->message,pMsg->wParam,pMsg->lParam);<br />
return TRUE;<br />
}<br />
}
|
|
|
|
|
(My englisch is very bad, i'm from Czech Rep)
I have aplication that use CListCtrl, now i use CReportCtrl.
When i change section (by mouse or keys) in CListCtrl from item 1 to item 2, then CListCtrl sends four notifications in this ORDER:
1) changing ... unselect 1
2) changed .... unselect 1
3) changing ... select 2
4) changed .... select 2
but CReportCtrl send the same notifications in another ORDER
1) changing ... select 2
2) changed .... select 2
3) changing ... unselect 1
4) changed .... unselect 1
|
|
|
|
|
it doesn't support multiline... do you know something like this with multiline support ?
Stewe
|
|
|
|
|
I just want to know how can we implement drag drop in this control.
What till now i have implemented is this control in tree view as today and tomorrow etc as tree nodes.
What i want to do now is dran some list item from this to other panel in my window.
Can this be done?? If yes How??
If anyone does know. please post the message here as soon as possible.
regards,
Yadvinder Brar
|
|
|
|
|
I have the same problem,
could anyone help me , please ?
VANNAM
|
|
|
|
|
Is it possible, when I use the owner draw style of the Control, to set the lParam in OnRvnItemCallback and to get it back in OnRvnSelectionChanged? If so, could you please give me a short example? If not, why is it not possible?
Thanks
Andreas
|
|
|
|
|
I have a list that loads data in a non-ordered fashion. For example, if I have data items A, B, and C, they could conceivably load into the list as follows:
C
A
B
Consequently, after I have finished loading the data, I call SortItems (0, TRUE) to sort them alphabetically. I also want to automatically select the first item in the list, so I then call SetSelection (0) , however, the item that is actually selected is the item that was first inserted into the list, not the item at the top of the list after a call to SortItems .
I have a feeling that the internal selection map does not get updated. I will be digging through the code, but if you or anyone else already has a fix for it, I would greatly appreciate the time savings.
Thanks!
|
|
|
|
|
Hi, I'm trying to subclass the CReportHeaderCtrl in a class subclassed from CReportCtrl called CMyReportCtrl in order to have the HeaderCtrl react to NM_CUSTOMDRAW. However, I keep getting ASSERTS when doing it like this:
<br />
SubclassWindow(m_wndHeader->GetSafeHwnd())<br />
I know I'm doing something wrong, but I'm not quite sure what. Could anyone assist me here?
|
|
|
|
|
i use Mfc to creat OCX
class CSDIGridApp
class CSDIGridCtrl
class CSDIGridPropPage
now let CridCtrl join it
on CSDIGridCtrl::OnDraw i create CGidCtrl
in CSDIGRIDCtrl i can't get event of OnLButtonDown,
why?
|
|
|
|
|
If you send me the code I can help you.
I'm looking for it to.
Best regards
|
|
|
|
|
Any chance you could post your code?
|
|
|
|
|
When you drag a column out of the report control to hide it, you don't have to drag it into the field chooser; you can simply drag it out of the frame window and drop it anywhere. I know where to modify the code to change this behavior (CReportCtrl::OnHdnEndDrag ), but I'm curious as to why you made this design decision. Can anyone else shed some light on this? Have you seen this behavior before in other list control's?
Jon Sagara
A bottle a night isn't alcoholism - it's persistence!
-- A coworker, jokingly
|
|
|
|
|
Is there a way to persist the control's sort settings (e.g., subitem and direction)?
Jon Sagara
A bottle a night isn't alcoholism - it's persistence!
-- A coworker, jokingly
|
|
|
|
|