|
Thanks for the reply. The program is actually dying in the call to Create() so it's too late to call Initialize() after that. The stack trace when it dies is below:
CWnd::GetWindowRect(tagRECT * 0x0012f498 {top=-858993460 bottom=-858993460 left=-858993460 right=-858993460}) line 96 + 43 bytes
CTLFrame::OnSize(unsigned int 0, int 1332, int 938) line 413
CWnd::OnWndMsg(unsigned int 5, unsigned int 0, long 61474100, long * 0x0012f5dc) line 1845
CWnd::WindowProc(unsigned int 5, unsigned int 0, long 61474100) line 1585 + 30 bytes
AfxCallWndProc(CWnd * 0x002f2830 {CTLFrame hWnd=0x00070404}, HWND__ * 0x00070404, unsigned int 5, unsigned int 0, long 61474100) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x00070404, unsigned int 5, unsigned int 0, long 61474100) line 368
AfxWndProcBase(HWND__ * 0x00070404, unsigned int 5, unsigned int 0, long 61474100) line 220 + 21 bytes
USER32! 77e11b60()
USER32! 77e12f29()
USER32! 77e12f4f()
NTDLL! 77fa032f()
USER32! 77e17531()
CWnd::CreateEx(unsigned long 0, const char * 0x0041f258 `string', const char * 0x0041f270 `string', unsigned long 1342177280, int 0, int 0, int 1332, int 938, HWND__ * 0x000d0430, HMENU__ * 0x00000000, void * 0x00000000) line 694 + 54 bytes
CWnd::Create(const char * 0x0041f258 `string', const char * 0x0041f270 `string', unsigned long 1342177280, const tagRECT & {top=0 bottom=938 left=0 right=1332}, CWnd * 0x002f2770 {CMainWindow hWnd=0x000d0430}, unsigned int 0, CCreateContext * 0x00000000) line 743
CMainWindow::OnCreate(tagCREATESTRUCTA * 0x0012fbf4) line 48 + 50 bytes
CWnd::OnWndMsg(unsigned int 1, unsigned int 0, long 1244148, long * 0x0012fa7c) line 1811 + 13 bytes
CWnd::WindowProc(unsigned int 1, unsigned int 0, long 1244148) line 1585 + 30 bytes
AfxCallWndProc(CWnd * 0x002f2770 {CMainWindow hWnd=0x000d0430}, HWND__ * 0x000d0430, unsigned int 1, unsigned int 0, long 1244148) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x000d0430, unsigned int 1, unsigned int 0, long 1244148) line 368
AfxWndProcBase(HWND__ * 0x000d0430, unsigned int 1, unsigned int 0, long 1244148) line 220 + 21 bytes
USER32! 77e11b60()
USER32! 77e12f29()
USER32! 77e16169()
NTDLL! 77fa032f()
USER32! 77e17531()
CWnd::CreateEx(unsigned long 0, const char * 0x00000000, const char * 0x0041f124 `string', unsigned long 13565952, int -2147483648, int -2147483648, int -2147483648, int -2147483648, HWND__ * 0x00000000, HMENU__ * 0x00000000, void * 0x00000000) line 694 + 54 bytes
CFrameWnd::Create(const char * 0x00000000, const char * 0x0041f124 `string', unsigned long 13565952, const tagRECT & {top=-2147483648 bottom=0 left=-2147483648 right=0}, CWnd * 0x00000000 {CWnd hWnd=???}, const char * 0x00000000, unsigned long 0, CCreateContext * 0x00000000) line 568 + 79 bytes
CMainWindow::CMainWindow() line 40
CMyApp::InitInstance() line 27 + 34 bytes
AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x001330e3, int 1) line 39 + 11 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x001330e3, int 1) line 30
WinMainCRTStartup() line 330 + 54 bytes
KERNEL32! 77e8d326()
|
|
|
|
|
I'm having this exact same issue. I used to be using this control from within a view, but the scenerio has changed and I need to create this control "on the fly". I tried creating the control with the name TLFrame instead of LANTIVTREELISTCTRL, and it actually manages to get passed creation...but it isn't really created. Besides that, I get the same results as you.
|
|
|
|
|
ok, here's how I fixed this issue. I went in to the OnSize and MoveWindow code, and added a check GetSafeHwnd() I only check one of the windows, and bail if it fails. The reason this is crashing is because Initialize hasn't been called yet, so those windows haven't been created. (and OnSize gets called when we create the CTLFrame). Anyway, after my Create call, I also call Initialize (made it a public method), this creates the header, tree, etc... I also changed the code in Initialize, where it gets the Parent's Font, changed it to this:
CFont font;
font.Attach(::GetStockObject(DEFAULT_GUI_FONT));
font.GetLogFont(&logfont);
This might not be an issue for you, but it was causing problems for me the way it was. Anyway, hope this helps...
|
|
|
|
|
Anonymous wrote:
PreSubclassWindow is called only when the control is subclassed, and not when created
This is not true. PreSubclassWindow is called from _AfxCbtFilterHook , which is called (indirectly) from CreateWindowEx , which is called to create windows. The call to AfxHookWindowCreate before CreateWindowEx makes sure that the hook function (_AfxCbtFilterHook ) is called. Look in wincore.cpp in the MFC sources.
---
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
|
Great control!
One problem though. I can't seem to be able to read the values found in the subitems text using the GetItemText function.
Example:
m_lstBills.m_tree.GetItemText(x, 1);
The value I keep getting returned is the text found in column 0.
Any help will be appreciated!!
Rolando
|
|
|
|
|
I'm having two small but tricky problems.
If I don't put an icon next to an item then I get a strange redrawing problem where scrolling right shows that right side of the control is not being drawn.
The other thing is I've been trying to use CMemDC or some variant thereof to get flicker free drawing. However after numerous tries I don't seem to be getting anywhere. The problem is that I'm not sure whether to call SetViewportOrg() on the buffered DC or on the original DC. Calling it on the original DC seems to have problems and calling it on the buffered DC seems to either cause problems or not do anything. This is different from the usual CMemDC examples because we want to apply horizontal scrolling effect ourselves manually using m_nOffset, and I just can't seem to do it.
Any help would be VERY much appreciated. Thank you!
Kevin
|
|
|
|
|
This flickering problem has nothing to do with the bitmap buffering. It was caused by additional repainting
and erasing of the background of parent classes. So the simplest
solution is to handle WM_PAINT message for CTLFrame class like this
void CTLFrame::OnPaint()
{
CPaintDC dc(this);
// do nothing here
}
And then handle WM_ERASEBKGND message for CTLViewView class like this
BOOL CTLViewView::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
And it will remove all annoying background flickering.
If you want to go even further you can use memory double buffering
to avoid even text flickering while resizing, however it is not so
annoying, even standard notepad is doing that.
Igor Novikov
|
|
|
|
|
The obvious things you could try (and im sure you've tried them already ) is to set the clipchildren style on the window, and you could return TRUE on any erasebackground that is being called (so it doesnt erase the background).
Senior Developer
Avellino Technologies LTD
UK
|
|
|
|
|
Hi,
Is it possible to add a bitmap to one of the columns instead of text?
Cheers
Magnus
|
|
|
|
|
I tried to close the window of the demo project by clicking on the X button in the title bar, but nothing happened.
Then I realized that I was clicking on the picture included in the article instead of the real application.
I need some coffee....
|
|
|
|
|
you must
- move some files into res subdirectory manualy
- give own path to afx*.rc(in my case C:\Program Files\Microsoft Visual Studio\VC98\MFC\Include)
- remove CTreeListView::GetDocument()
t!
|
|
|
|
|
download demo
run exe from it
try expand all expandable
resize window to minimal width - second (tree's original) scroll bar appears
sometimes two scroll bars
the same without -4 from Paul D'hertoghe's comment
|
|
|
|
|
I understand everything except step #3 .
Layout a user-defined control inside the dialog into which the control is supposed to be intserted. In the class field type: "LANTIVTREELISTCTRL"
Where or how is this done in visual studio?
Can I just add a CListCtrl and derive it from CTLFrame?:confused
|
|
|
|
|
I have extended this project to fit on a CView and also have check boxes and tool tips - I have posted it and so will be soon on code guro.
G.A.Lewis
|
|
|
|
|
Can you send your Extended classes to me
My e-mail a_osin@stinol.ru
|
|
|
|
|
EMail me too, please:
m.rinninger@kubeos.at
Thank you very much.
|
|
|
|
|
Can anybody tell me the use of boolean variable m_RTL
in this application.Its value is set to false(in the constructor)
and is never changed again.What does RTL stands for?.
By the way this is a terrific control.It taught me a lot.
thanks Mr David Lantsman.
|
|
|
|
|
|
Great Control! I have a beginner question though.
How can I catch selection changes in my CTreeListView-derived view class?
Thanks in advance-
Ron:
|
|
|
|
|
BOOL CXXXDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
NMHEADER * pNMHEADER = (NMHEADER *)lParam;
if ((ID_TREE_LIST_CTRL == wParam) && (TVN_SELCHANGED == pNMHEADER->hdr.code))
{
//tree-list control selection changed
TRACE(_T("tree-list control selection changed\n"));
//do something here
return 1; //processed
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
CXXXDlg is the container of a tree-list control.
|
|
|
|
|
Just as a note... If anyone intends to use a Context menu using this control, you'll need to fix the "CTLFrame::OnContextMenu" method.
Before:
void CTLFrame::OnContextMenu(CWnd* pWnd, CPoint point)
{
GetParent()->SendMessage(WM_CONTEXTMENU, (WPARAM)pWnd, 0);
}
After:
void CTLFrame::OnContextMenu(CWnd* pWnd, CPoint point)
{
GetParent()->SendMessage( WM_CONTEXTMENU, (WPARAM)pWnd->GetSafeHwnd(), MAKELPARAM(point.x, point.y) );
}
|
|
|
|
|
I tried to build your project in VC++ 5 and its definitely a no go.
|
|
|
|
|
I think the control is great, and I think a great enhancement would be have the option of display gridlines between columns & rows.
|
|
|
|
|
There is a small bug, that inhibits proper column sorting when positive and negative numbers are present in the same column.
inside:
int CALLBACK CNewTreeListCtrl::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
on line 1192 it reads:
if ((num1 < 0) || (num2 < 0) )
tmpStr1 = str1.SpanExcluding("-0123456789");
tmpStr2 = str2.SpanExcluding("-0123456789");
it should read
tmpStr1 = str1.SpanExcluding("-0123456789");
tmpStr2 = str2.SpanExcluding("-0123456789");
no if statement. Great control by the way. this should be an MFC standard
|
|
|
|
|
There is a small bug, that inhibits proper column sorting when positive and negative numbers are present in the same column.
inside:
int CALLBACK CNewTreeListCtrl::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
on line 1192 it reads:
if ((num1 < 0) || (num2 < 0) )
tmpStr1 = str1.SpanExcluding("-0123456789");
tmpStr2 = str2.SpanExcluding("-0123456789");
it should read
tmpStr1 = str1.SpanExcluding("-0123456789");
tmpStr2 = str2.SpanExcluding("-0123456789");
no if statement. Great control by the way? this should be an MFC standard
|
|
|
|
|