|
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
|
|
|
|
|
Thank you very much for your reply.
Could you spend some time to see my other two question on the top?
-Freehawk
|
|
|
|
|
My users didn't like using return to start editing, so I took the code from VK_RETURN and made a small function ...
void CTreeListCtrl::InitiateCellEditIfSensible()
{
if( m_arSelects.GetSize() > 0 )
{
CTreeListItem* pItem = (CTreeListItem*)m_arSelects[0];
int iModify = m_iSelCol;
if( 0 <= iModify && iModify < m_arColumns.GetSize() )
BeginModify( pItem, iModify );
}
}
Then I modified CTreeListCtrl::OnLButtonDblClk to call the new function ...
if( m_dwStyle&TLC_TREELIST )
{
if ( nFlag&TLHT_ONITEMIMAGE )
{
//SelectItem( pItem, iSubItem );
Expand( pItem, TLE_TOGGLE, iSubItem );
}
else if (nFlag&TLHT_ONITEMTEXT)
{
// double click on text can initiate editing, changed by pete
InitiateCellEditIfSensible();
}
}
I'd also like to add my appreciation for this work, I have been looking for something as neat as this for some years.
Pete Story
|
|
|
|
|
Heyah!
I know C++ but I'm new in MFC programming, and your control is the thing i've been lookin' for. I ' d like to know what should i do to add some funtion that would enable me settin BOLD text, or color text or color background but only in a specified line (row) of the contorl (not while tree control). Someone wrote that this is very simple but not for me...yet Plese help me...any tips....whatever....
|
|
|
|
|
//In CTreeListCtrl::DrawItems( CDC* pDC, CRect //rcClip ) add:
//font
CFont *pFontDC;
CFont fontDC, boldFontDC;
LOGFONT logfont;
CFont *pFont = GetFont();
pFont->GetLogFont( &logfont );
fontDC.CreateFontIndirect( &logfont );
pFontDC = pDC->SelectObject( &fontDC );
logfont.lfWeight = 700;
boldFontDC.CreateFontIndirect( &logfont );
if(iRow == (nFirstRow+5))
{
pDC->FillSolidRect( rcItem, RGB(40,210,100) );
pDC->SelectObject( &boldFontDC );
}
else
{
pDC->SelectObject( &fontDC );
...it was easy, sorry for bothering you....nice control by the way;)
}
|
|
|
|
|
i fill the treecontrol with about 700 entries. The debug version needs about 1 or 2 seconds, the release version needs about 16 seconds?!?!?
i figured out, that the release version is faster until 310 entries. Between 310 and 318 entries it is very slow. After that its getting fast again.
Has anyone an idea??
Best
Norbert
|
|
|
|
|
I got the answer by myself!
The insert operation of the treecontrol, calls after every insert <layout()> and <invalidate()>
I took this out and called this operations after the filling ist finished! That's it.
Best
Norbert
|
|
|
|
|