|
Inherit from CTreeListCtrl and implement a handler for
the TLN_SELCHANGING Message: ON_NOTIFY_REFLECT( TLN_SELCHANGING,OnSelChanging)
Works for me.
yoko
|
|
|
|
|
I want to put this control in property page. But I'm unable to add this control there. Has anybody tried this? do you have any solution on this?
When I tried to access the propety page, it just gets disappears. Can't feagure out the problem also CPropertyPage::OnInitDialog() doesn't get called..
|
|
|
|
|
hi,first i want to say this a wonderful design since i used it about half year.
recently,i met a trouble,i put this Tree list control in my project,i check scroll bar action in
OnVScroll() event, when the current scrollbar`s positon is the bottomline,i delete all item in the tree,get new parts data then put before data and new data into this tree,strange is i alway lost the scroll bar focus even i can see it and it`s position also right.the same deal if i check with VK_DOWN event,everything is ok,so i can`t make me understand.hope you can give a hand,thanks advance,have a good day!
|
|
|
|
|
First of all congrats on developing a great control. I am using the control in a form using CForview. The moment I add a new toolbar to the form the toolbar works perfectly but the control loose its focus and It is not responding to the messages. My second problem is when I create the control in CFormview class with many colums and rows it flickers while creating and resizing. Please suggest
|
|
|
|
|
I had this same problem. It was getting stuck in a loop starting in void CTreeListCtrl::Layout(). It calls CTreeListCtrl::SetAllScroll() twice. The problem was that the second call to SelAllScroll would result in Layout being fired again and it would get stuck in a loop that it may or may not come back from.
I did a workaround. Not a good one mind you but it functions for now. The issue being that the scroll bars a goofy sometimes. But I opted for that till I could find a proper solution.
I added a member variable of BOOL m_bRedraw which is initialized to TRUE.
Then I added in the beginning of Layout
if (!m_bRedraw)
return;
I also added public method
void CTreeListCtrl::AllowRedraw(BOOL redraw)
{
m_bRedraw = redraw;
}
I also commented out the first call to SetAllScroll() in Layout.
So now if I am giong to do alot of updating of data I just call AllowRedraw(FALSE); apply all the values then call AllowRedraw(TRUE); and if needed I then Invalidate the contorl.
also I needed this on large batch inserts as well as deletes.
Like I said. It functions. but it's not good and it has some problems.
|
|
|
|
|
I have a slightly better solution that does not require the user to explicitly set and reset redraw each time.
Just add the member variable
bool m_bLayoutFlag;
in CTreeListCtrl.h
Add
m_bLayoutFlag(false)
at end of constructor
and change the code in Layout as follows ( changes towards the beginning and end ----
void CTreeListCtrl::Layout()
{
// Following two lines added
if (m_bLayoutFlag)
return;
// layout size
if( !IsWindow( m_wndHeader.GetSafeHwnd() ) )
return;
if( !IsWindow( m_wndTip.GetSafeHwnd() ) )
return;
// Following line added
m_bLayoutFlag = true;
m_wndTip.Hide();
SetAllScroll();
GetClientRect( &m_rcClient );
m_rcHeader = m_rcClient;
m_rcTreeList = m_rcClient;
m_wndHeader.SendMessage( HDM_LAYOUT, (WPARAM)0, (LPARAM)&m_rcHeader );
if( m_rcHeader.Height() == 0 )
{
m_rcTreeList = m_rcClient;
}
else if( m_rcHeader.Height() == m_rcClient.Height() )
{
m_rcTreeList.top = m_rcHeader.bottom;
m_rcTreeList.bottom = m_rcHeader.bottom;
}
else
{
m_rcTreeList.top = m_rcHeader.bottom;
}
SetAllScroll();
// Following line added
m_bLayoutFlag = false;
return;
}
Prabha
-- modified at 10:20 Friday 21st October, 2005
|
|
|
|
|
hello,
i've been using the control for few months (in dll version) for a VC++ 6 application, under windows NT. Now i m trying to execute the same application under windows 2000 or XP. My application runs fine until i call a functionality that uses the TreeControl : Memory access violation blahblah bug.
The bug only happens when executing in release mode. It runs fine when in debug mode, so it's impossible for me to find the source of the bug.
anybody has a clue ?
thanks for your help.
|
|
|
|
|
I create MFC DLL , use this Control, fail? Use it int Exe DLG app , that is good!
|
|
|
|
|
I ran into a similar issue using this control in a DLL and subclassing it. It ended up being a MFC issue because I was trying to expose from my DLL my subclassed version but I was in turn importing from a different DLL.
The workaround I found was this.
//change the definition of AFX_EXT... to make it import
#undef AFX_EXT_CLASS
#undef AFX_EXT_API
#undef AFX_EXT_DATA
#define AFX_EXT_CLASS AFX_CLASS_IMPORT
#define AFX_EXT_API AFX_API_IMPORT
#define AFX_EXT_DATA AFX_DATA_IMPORT
//Include headers for the dll / lib that we use classes from
#include "TreeListCtrl.h"
//put the values back to make AFX_EXT_CLASS export again
#undef AFX_EXT_CLASS
#undef AFX_EXT_API
#undef AFX_EXT_DATA
#define AFX_EXT_CLASS AFX_CLASS_EXPORT
#define AFX_EXT_API AFX_API_EXPORT
#define AFX_EXT_DATA AFX_DATA_EXPORT
All you're basically doing is redefining the MFC macro's so you aren't interpreting the macris in the TreeListCtrl.h header when you use that class in yours. THen you are safe to export your new class from your dll.
|
|
|
|
|
firstly thank u for the wonderful code
I want to link with static lib, how can i do?
thank u,
regards
|
|
|
|
|
The conrol you have written is very much useful. Great Job!!
I can't use same control as it is.. I have similar requirement, where I want to add button control in 3rd column. & I want only 3 columns to be displayed, so how can I achive it. Seeking for your valuable help.
Thanks in advance!!
Regards,
~Vijay.
|
|
|
|
|
// from Root item
BOOL CTreeListCtrl::ExpandAll()
{
// expand an item
CTreeListItem *hItem = GetRootItem();
Expand( hItem, TLE_EXPAND );
while (hItem)
{
hItem = GetNextItem(hItem, TLGN_NEXTVISIBLE);
Expand(hItem, TLE_EXPAND);
}
return TRUE;
}
// from pItem
void CTreeListCtrl::ExpandAll(CTreeListItem *pItem)
{
// expand an item
if(pItem)
Expand( pItem, TLE_EXPAND );
CTreeListItem *pNextItem;
for (pNextItem = GetNextItem(pItem, TLGN_CHILD); pNextItem != NULL; pNextItem = GetNextSiblingItem(pNextItem))
ExpandAll(pNextItem);
}
|
|
|
|
|
That Great,
How about a CollapseAll?
Why I try this code below, the entire tree disappears.
void CTreeListCtrl::CollapseAll( CTreeListItem* pItem )
{
// if pItem is null then get the root, otherwise collapse the item
if( pItem == NULL )
{
pItem = GetRootItem();
}
else
{
Expand( pItem, TLE_COLLAPSE );
}
CTreeListItem *pNextItem = NULL;
for ( pNextItem = GetNextItem(pItem, TLGN_CHILD);
pNextItem != NULL;
pNextItem = GetNextSiblingItem(pNextItem))
{
CollapseAll(pNextItem);
}
}
|
|
|
|
|
The 2 functions you need to collapse are:
BOOL CTreeListCtrl::CollapseAll()
{
// collapse an item
CTreeListItem *hItem = GetRootItem();
Expand( hItem, TLE_COLLAPSE );
while (hItem)
{
hItem = GetNextItem(hItem, TLGN_NEXTVISIBLE);
Expand(hItem, TLE_COLLAPSE);
}
return TRUE;
}
// from pItem
void CTreeListCtrl::CollapseAll(CTreeListItem *pItem)
{
// collapse an item
if(pItem)
Expand( pItem, TLE_COLLAPSE );
CTreeListItem *pNextItem;
for (pNextItem = GetNextItem(pItem, TLGN_CHILD); pNextItem != NULL; pNextItem = GetNextSiblingItem(pNextItem))
CollapseAll(pNextItem);
}
|
|
|
|
|
I want to change the specipic row item color...
but it's hard to implement for me...
like ...
pItem = m_ctrlTreeList.InsertItem("Data OK!");
pItem = m_ctrlTreeList.InsertItem("data FAIL!", pItem);
m_ctrlTreeList.SetItemText(pItem, "failed data.", 1);
m_ctrlTreeList.SetItemColor(pItem, RGB(255,0,0)); // change item color to RED...
m_ctrlTreeList.SetItemBold(pItem); // change item BOLD
could you help me?
|
|
|
|
|
hi,
Is it possible to create a transparent tree control which can be placed in a view (so that it does not block the underlying view contents).
I have tried the approach using WS_EX_LAYERED and WS_EX_TRANSPARENT but it does not work.
thanks
Seshagiri
|
|
|
|
|
I have converted this code from a DLL to a LIB. Can anyone tell me how to use it in my code? Do I have to place a custom control on the dialog and create it?
I'm a bit of a beginner with MFC...
Thanks!
|
|
|
|
|
Hi,
I want to do the same as you, and there are, in fact, problems with the process. The main problem lies with resource access. This is a problem with any LIB, since LIB's can hold code and data, but not resources. This means that any "example.lib" library cannot hold a bitmap or a wave file inside it, under the form of a resource.
******************************************************
By the way TigerX: great module! Exactly right for me!
******************************************************
We can, however, incorporate any data element into a LIB as data. For example, I've written a small C program that takes a file name <file_name> and a C name <c_name> and reads the file <file_name> (as binary) and creates a C file with a variable <c_name> and another <c_name>_size similar to:
// This was generated from "file_name" on yyyy-mm-dd
char c_name[]={
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
0x02, 0x12, 0x00, 0xfa, 0xcc, 0xcc, 0xac,
0x00, 0x67, 0x11, 0x11, 0x11, 0x11, 0x10
};
const long c_name_size=sizeof(c_name);
If your LIB exports these data elements, then you can reconstruct the original data buffer, for example, storing it back to file at run-time, or using it directly from memory.
Although you could try this to load resources from a LIB file, Windows does not provide functions that let you load and store a resource from a binary memory buffer (as far as I know), like the memory buffer that a LIB can provide. The Windows functions all load resources from EXE's and DLL's. As for storing them to a memory buffer, this also is dificult to do (but necessary to get a binary representation of the resource inside the LIB in the first place).
But CBitmap, for example, is derived from a CObject. And a CObject is serializable! Well, not all CObject's: CBitmap is not serializable.
So, and until someone finds an simpler or prettier way to solve your (our) problem, I chose to tell you about the easy way, in 6 small steps, for which I assume you are familiar with VC6 and understand preprocessor, compiler, linker, export, executable, DLL, and LIB concepts (let me know if you don't):
1) Create a LIB project.
2) Create a LIB tester project (that uses the LIB and not the DLL).
3) Transfer the resources from the TurboDLL to the LIB tester project (the LIB project will not need them since it will be unable to export them, so the LIB tester project should be their holder).
4) Change the source files of the CTreeListCtrl so as to let them know where to get the resources from.
5) Build the LIB tester program.
6) Run the LIB tester to see if it runs ok.
Now with a little more detail.
___________________________________________________
1) Create a LIB project.
In the same workspace as TurboDLL add a new Static Library project, with MFC support. I didn't need pre-compiled header support. By using the same workspace it is very simple to copy file references and project settings.
The LIB project should have the same H and CPP fies as the TurboDLL project. You will also need to copy some predefined symbols from TurboDLL for the project to build ok. You find these in Project/Settings/C/C++/General/Preprocessor definitions.
___________________________________________________
2) Do the same as in 1), but select an MFC executable project instead of a static LIB project. Do not include the TurboDLL CPP source files, because this code will come from the LIB.
So, by building the project you will get a lot of unresolved externals. The simplest way to incorporate the LIB is to set a dependency, in Project/Dependencies. You should make the LIB tester project depend on the LIB project. VC6 is very smart, and will know where the LIB is (and distinguish between Debug and Release automatically!) and link with it.
If you are doing it ok, then you will get a successful compilation, although not clean (with some warnings which may be ignored at this stage). If you try to run it you should get an assertion failure, and so the program is not useful yet.
___________________________________________________
3) Transfer the resources from the TurboDLL to the LIB tester project.
Since both projects are in the same workspace, you may copy the BITMAP resources from the TurboDLL to the LIB tester (note that only references are copied, not the files).
I don't know exactly what resources are needed, since I have had contact with the CTreeListCtrl for only a couple of hours yet, just enough to get it running as a LIB without looking at the details. So copying the bitmaps is enough for the thing to run the same demo as TurboDemo, althoug some things behave diferently (like the cursor for resizing the header columns).
___________________________________________________
4) Change the source files of the CTreeListCtrl so as to let them know where to get the resources from.
To minimize the impacts, you should do a backward compatible change. The problem lies in the CTreeListResource constructor and destructor in "TurboDLL.cpp", which call AfxSetResourceHandle(TurboDLL.hResource) and thus change the resource origin from the MFC EXE (the LIB tester) to the LIB (but which the source code still thinks is a DLL, and thus is not valid at run-time).
The objective is to let the LIB use the LIB tester's resources, so these constructors and destructors should do nothing, since, by default, resources will be loaded from the EXE.
You can achieve this in a number of ways. The least intrusive is for you to create a "TurboDLL_lib.cpp" file, which implements an empty constructor and destructor for CTreeListCtrl (all of the remaining code may be deleted).
The LIB project should then include "TurboDLL_lib.cpp" instead of "TurboDLL.cpp". This means you didn't change any of TigerX's code.
TigerX should probably do it diferently. If he wants the same source code to be compatible with both DLL and LIB projects, then he would use the _LIB preprocessor definition in the LIB project, to make decisions in the code like:
#ifndef _LIB
// _LIB not defined, it is a DLL project
... code for the DLL ...
#else
// _LIB defined, it is a LIB project
... code for the LIB, probably testing the
availability of all the required resources...
#endif
___________________________________________________
5) Build the LIB tester program.
When you build the program you will probably get a number of warnings. I have not yet looked at them carefully, ignoring them seems to work. If you do a Rebuild All, the dependencies will cause the LIB to be rebuilt before the LIB tester, and the process will be:
5.1) The LIB is built, with code for the CTreeListCtrl and it's data, but not the resources.
5.2) The LIB tester EXE is built, with code for CTreeListCtrl comming from the LIB project, and with the remainder code for the application. This project will also provide the resources for your application, and the resources for CTreeListCtrl. These will all be linked into the EXE (of the LIB tester).
___________________________________________________
6) Run the LIB tester to see if it runs ok.
It should run ok. As I pointed out the mouse cursor fails to change correctly when you try to resize the columns. This should be easy, just copy the cursors also. I have not yet tried it, but it seems to be a reasonable solution.
To sumarize: this is the easy method, not the cleanest. For every new project you must take along the bitmap files, and recreate the bitmap references, ID's, as well as cursors and the rest. After the project is setup, it should be self-suficient, and the EXE it builds should not require any external DLL's. The way I did it was to enforce the existence of all resources, opening an explanatory dialog box when a resource is missing. This allows me to ensure that any EXE project has all it needs, and that nothing has been forgotten.
I hope this helps,
Rogério
Rogerio Rilhas
rogerio.rilhas@mail.pt
|
|
|
|
|
Hello.
I searched source code, in it there is "GetFirstVisibleItem" function. but the function seems to return the root item only and not return the first visible item of screen. How to get it?
Please help me.
Thank you.
-Freehawk
|
|
|
|
|
this time visible means the item has got a parent in expanded state. But this is independent from the control's view.
You may use HitTest() to get the first item on screen.
vrumfundel
|
|
|
|
|
Hello.
I have a question as the following .Please help me.
1.How to set the font color of cells which I want to modify in the list?
Thank you.
-Freehawk
|
|
|
|
|
Hi,
This is what I did.
1) Subclass CTreeListCtrl
2) Set CTreelistCtrl::DrawItemText(...) to be virtual
3) Implement the DrawItemText in the subclassed window.
Change m_crText to the required color.
<br />
void CMyTreeListCtrl::DrawItemText( CDC* pDC, CRect rcBkgnd, CRect rcText, CTreeListItem* pItem, int iCol )<br />
{<br />
MyItemData* pNode = (MyItemData*) this->GetItemData(pItem);<br />
ASSERT(pNode != NULL);<br />
m_crText = pNode->IsBlue() ? 0xff0000 : 0x000000;<br />
CTreeListCtrl::DrawItemText(pDC,rcBkgnd,rcText,pItem,iCol);<br />
}<br />
Hope this helps.
Itai
|
|
|
|
|
Hello.
At first, thank you for the great job.
I have a question. it is whether edit box or combo box can be added into cells of list? Can it be realized? How to do?
Thank you.
-Freehawk
|
|
|
|
|
TigerX added all of the necessary code already,
first you have to remove the comment characters around VK_RETURN in CTreeListCtrl::PreTranslateKeyDownMessage()
then remove a little bug I found in CTreeListCtrl::GetControl()
CWnd* pWnd;
should be changed in
CWnd* pWnd = NULL;
that's it.
Remember to press ENTER for input on runtime.
standard setting is edit control, replace
TLM_EDIT by TLM_COMBO or TLM_STATIC
in CTurboDemoDlg::OnInitDialog() to get, you guessed it, Combo or Static.
There you go.
Thanks go to TigerX for his nice control.
Hope that helped you out.
vrumfundel
|
|
|
|
|
Thank you very very much.
I modified source code as you said, now it works very goooooooood.
The control is very nice and great.
-Freehawk
|
|
|
|
|