|
Where's the OnSize handler that you change the column widths in - The parent window or a class
derived from CListView?
If the scrollbar goes away right when you try to use it is it just a matter of refreshing with
Invalidate()/UpdateWindow()?
Mark
|
|
|
|
|
It doesn't matter where I put the OnSize handler.
The scrollbar doesn't go away right away, only if I actually click it.
As I said to Ravi, I think I'll have to superclass the window and handle WM_SIZE BEFORE the control gets it.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Joe Woodbury wrote: As I said to Ravi, I think I'll have to superclass the window and handle WM_SIZE BEFORE the control gets it.
Since you're using MFC it's easy to try it. Just derive a class from CListView and add the
WM_SIZE handler. Do your stuff in OnSize before passing control to the base class.
Mark
|
|
|
|
|
I ran across an article that suggests when MFC superclasses SysListView32, that what I'm getting is faux superclass, not a genuine one:
http://www.pocketpcdn.com/articles/child_list.html[^]
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
BTW, have you tried listview.Invalidate(); listview.UpdateWindow() after resizing columns in a
WM_SIZE handler? This needs to be done on windows with scroll bars so the scrollbars redraw
properly. Maybe that applies to the listview control as well?
*EDIT* I'm talking from the parent's OnSize(), where presumably you are resizing the listview
and the listview's columns. Rarely IME does a control need to be sub/superclassed for WM_SIZE
notification.
Mark
|
|
|
|
|
Doesn't work.
I tried using in the derived control class since I'm already deriving it for other reasons.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
I found a weird solution. It still results in horizontal scroll bar flash, but I haven't gotten the bar to stick yet.
In short, in the dialog I process WM_SIZING and do the following:
DWORD style = GetWindowLong(m_hWnd, GWL_STYLE);<br />
int scrollWidth = (style & WS_VSCROLL) ? ::GetSystemMetrics(SM_CXVSCROLL) - 2 : 2;<br />
<br />
CRect rect;<br />
m_listCtrl.GetClientRect(rect);<br />
m_listCtrl.SetColumnWidth(CSpyListCtrl::DATA_COLUMN, rect.right - CSpyListCtrl::TIME_COLUMN_WIDTH - CSpyListCtrl::TOPIC_COLUMN_WIDTH - scrollWidth);
When processing the WM_SIZE message (inside the instance of my [C++]subclassed list control, I do the following:
SetColumnWidth(CSpyListCtrl::DATA_COLUMN, cx - TIME_COLUMN_WIDTH - TOPIC_COLUMN_WIDTH - 2);
(I can't use LVSCW_AUTOSIZE_USEHEADER in OnSizing() else the bar sticks. I opted to not use it for OnSize() to keep the width the same.)
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
I guess whatever works for you
If the listview is a child of another window then it is easier IMO to do this stuff from the
parent.
The only reason a scroll bar should appear is if at the time of drawing the column widths exceeds
the size of the window. I've never seen a horizontal scrollbar for no reason
Mark
|
|
|
|
|
Ah, it doesn't show up for no reason. It shows up when resizing and during that resizing operation the column width is momentarily bigger that the size of the window BEFORE its adjusted.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Joe Woodbury wrote: Ah, it doesn't show up for no reason. It shows up when resizing and during that resizing operation the column width is momentarily bigger that the size of the window BEFORE its adjusted.
That's not spurious So, to get me on the same page (apparently I'm not even in the
right book), do you want the scrollbar to not show while it's resizing or do you want the
scrollbar to go away when the resize is finished or both?
|
|
|
|
|
It's spurious in that what I am doing should mean it never shows up. It's also spurious in that when it shows up, clicking on it makes it go away. Even more curious, it doesn't always use XP themes when it shows up. (I'm fairly sure this is a subtle bug in the common control library; I do know it's been around for quite a while, it's just that the nature of my current app makes it especially annoying.)
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
OK, with the following code I never see any horizontal scrollbar (Windows XP Pro, SP2).
This is a simple dialog with only a listview control - nothing else. Border is resizing.
I used a dialog because it was quick to toss together in VC++.
#include "stdafx.h"
#include "MFCTester.h"
#include "TestListViewDialog.h"
#include ".\testlistviewdialog.h"
IMPLEMENT_DYNAMIC(CTestListViewDialog, CDialog)
CTestListViewDialog::CTestListViewDialog(CWnd* pParent )
: CDialog(CTestListViewDialog::IDD, pParent)
{
}
CTestListViewDialog::~CTestListViewDialog()
{
}
void CTestListViewDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, m_ListCtrl);
}
BEGIN_MESSAGE_MAP(CTestListViewDialog, CDialog)
ON_WM_SIZING()
ON_WM_SIZE()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
BOOL CTestListViewDialog::OnInitDialog()
{
CDialog::OnInitDialog();
UpdateData(FALSE);
m_ListCtrl.InsertColumn(0, _T("Column 1"));
m_ListCtrl.InsertColumn(1, _T("Column 2"));
m_ListCtrl.SetExtendedStyle(m_ListCtrl.GetExtendedStyle() | LVS_EX_GRIDLINES);
FitListViewToDialog();
return TRUE;
}
void CTestListViewDialog::OnSizing(UINT fwSide, LPRECT pRect)
{
CDialog::OnSizing(fwSide, pRect);
if (pRect->right - pRect->left < 320)
pRect->right = pRect->left + 320;
if (pRect->bottom - pRect->top < 240)
pRect->bottom = pRect->top + 240;
}
void CTestListViewDialog::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
if (cx > 0 && cy > 0)
{
FitListViewToDialog();
}
}
void CTestListViewDialog::FitListViewToDialog()
{
if (::IsWindow(m_ListCtrl))
{
CRect ClientRect;
GetClientRect(&ClientRect);
m_ListCtrl.MoveWindow(0, 0, ClientRect.Width(), ClientRect.Height(), TRUE);
m_ListCtrl.SetColumnWidth(0, ClientRect.Width() / 2);
m_ListCtrl.SetColumnWidth(1, LVSCW_AUTOSIZE_USEHEADER);
}
}
BOOL CTestListViewDialog::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
-- modified at 19:29 Sunday 28th January, 2007
Added OnEraseBkgnd()
Added gridlines to check for flicker
-- modified at 19:38 Sunday 28th January, 2007
|
|
|
|
|
Here's the header file if you want to try it
#pragma once
#include "afxcmn.h"
class CTestListViewDialog : public CDialog
{
DECLARE_DYNAMIC(CTestListViewDialog)
public:
CTestListViewDialog(CWnd* pParent = NULL);
virtual ~CTestListViewDialog();
enum { IDD = IDD_DIALOG1 };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
void FitListViewToDialog();
DECLARE_MESSAGE_MAP()
public:
virtual BOOL OnInitDialog();
afx_msg void OnSizing(UINT fwSide, LPRECT pRect);
afx_msg void OnSize(UINT nType, int cx, int cy);
CListCtrl m_ListCtrl;
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
};
|
|
|
|
|
I ran your code. I still got horizontal bar flashing, but the bar didn't stick around. My code was very similar, with one key difference (which you had warned me about and I had dismissed); I was changing the column size inside OnSize() of my subclassed CListCtrl.
Thanks for your help.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
I probably missed this in previous posts, but what version OS are you on? What version
is your common controls DLL?
Just for my own reference - I've gone to great lengths over the years to provide flicker-free
smooth non-spurious-crap UI so I'd like to know what other platforms to test on.
Thanks!
Mark
|
|
|
|
|
XP SP2 on both systems I've been working on.
comctl32.dll file version is 5.82.2900.2982
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
hmm same here.
The only way I can get the scrollbar to appear is if I force it by "incorrectly" calculating
column sizes (ie making the width of all columns greater than the control width).
Sorry I couldn't help
Mark
|
|
|
|
|
Mark Salsbery wrote:
The only way I can get the scrollbar to appear is if I force it by "incorrectly" calculating
column sizes (ie making the width of all columns greater than the control width).
Again, to clarify. With your help, I solved the problem of the horizontal scrollbar that stuck around until you clicked it. What I'm still seeing (and have observed this for years with other projects) is the horizontal scroll bar flashing when you resize a dialog smaller very quickly. Moving the OnSize response to the parent reduced this but didn't get rid of it entirely--since most users won't be doing this, it's not a great concern.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Joe Woodbury wrote: What I'm still seeing (and have observed this for years with other projects) is the horizontal scroll bar flashing when you resize a dialog smaller very quickly.
Right. I'm with ya. I just can't make it happen I just tried it on that test code again.
Are you absolutely sure you're (intentionally or not) not redrawing the control before
resizing the columns - even in a seemingly unrelated message handler somewhere? That's still
the only way I could see that happening.
|
|
|
|
|
Mark Salsbery wrote: Are you absolutely sure you're (intentionally or not) not redrawing the control before
resizing the columns - even in a seemingly unrelated message handler somewhere?
No. I even got it to happen with your code from yesterday.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Bummer. I'm obsessive about little crap like that. It even drives me nuts that YOU haven't
solved it
Good luck!
|
|
|
|
|
How can I send text out to a List control in a loop?
for(int i=0; i<10; i++)
{
Sleep(1000);
m_list.AddString("Hello");
}
Now when im in the loop I dont see the text updateing but when the loop is finish then all the text is shown. How can I make so I can see the test updateing at ones?
|
|
|
|
|
A call to Sleep() isn't required, unless you want to convey the illusion of "progress". Try this:
for (int i=0; (i < 10); i++) {
Sleep (1000);
int nIndex = m_listCtrl.InsertItem (i, "Hello");
m_listCtrl.EnsureVisible (nIndex, TRUE);
m_listCtrl.UpdateWindow();
}
/ravi
|
|
|
|
|
I dont have 'InsertItem' only InserString or AddString.
|
|
|
|
|
Larsson wrote: I dont have 'InsertItem' only InserString or AddString.
Then you don't have a list control. You're probably using a CListBox and will need to use SetTopIndex() [^] instead
/ravi
|
|
|
|