|
You can only set the content of a structure by referring to it by address (aka pointer/reference). So rather than adding the item as text to each tree node, you should create a structure item, populate it with the data, and save its address in the node.
|
|
|
|
|
Thank you for the answer.
I checked the methods to insertitem to treeview. (Quote: HTREEITEM InsertItem( LPTVINSERTSTRUCT lpInsertStruct );
HTREEITEM InsertItem(UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam, HTREEITEM hParent, HTREEITEM hInsertAfter ) etc..
So how can I save address of a variable in the node? Can u please share the code segment for the same or any link to the same.
|
|
|
|
|
|
Yes, I used the SetItemData() and GetItemData() methods with lparam. I am passing the (DWORD)<structure var="">. But the variables are of different data types. the value has to be changed for the selected variable. I have lots of fields in the struct and 8 structures are there in the tree. Compare and set values for each fields will be cumbersome. Can you give proper guidance.
thank you
|
|
|
|
|
Sorry, I don't understand what you are asking, or what you mean by "I am passing the (DWORD)". You should create your structures, populate them with the relevant data, and then take their address as a pointer, which you send in the lParam field. You then have direct access to each structure in the relevant tree node.
|
|
|
|
|
Sorry to post you incomplete question. I mean the address of the variable I am passing in the lParam.
But again in my GetDataItem() method, i have to typecast to the corresponding variable. is it?
for eg.
typedef struct address
{
CString houseName;
CString placeName;
int cnrtyCode;
char pinCode[6];
};
typedef struct node
{
CString Name;
int Age;
float Height;
address adrs;
};
this is my structure. and
HTREEITEM hItems, hRoot;
TVINSERTSTRUCT tvInsert;
pNode->Name = "Shibu";
pNode->adrs.cnrtyCode = 91;
pNode->adrs.houseName = "House No 23";
pNode->adrs.placeName = "Bnglr";
pNode->Height = 5.5;
pNode->Age = 28;
hRoot = m_tree.InsertItem(_T("Personal Data"), 0, 1);
tvInsert.hParent = hRoot;
tvInsert.hInsertAfter = NULL;
tvInsert.item.mask = TVIF_TEXT | TVIF_PARAM;
tvInsert.item.pszText = "Name";
hItems = m_tree.InsertItem(&tvInsert);
m_tree.SetItemData(hItems, DWORD(&pNode->Name));
.......
.....
tvInsert.item.pszText = "Age";
hItems = m_tree.InsertItem(&tvInsert);
m_tree.SetItemData(hItems, DWORD(&pNode->Age));
Now my requirement is when i select the treeitem, associated value has to be displayed in a label. Also i have to change the value (through text box entry ; one text box only) of the selected item. Each value ( name,age etc.) are of different data types.
first i tried by passing address of pNode. then how to check my selection (whether user selected name/age/..).
Please help me with a code portion.
|
|
|
|
|
I am not sure that I understand what you mean or what you are trying to do. Presumably you have some nodes that are addresses, so you should add some key as the nodename, and then a pointer to the address structure as the item data. And for the other nodes you have some other type. But I am having trouble visualising exactly why you are using a TreeView in this instance.
|
|
|
|
|
As my actual structure is pretty huge as I mentioned earlier, designing a form with label & textbox for each one is difficult. So I planned to use treeview to list the items and one text box to enter value.
my form is simple with 1 treeview, label and textbox.
in this case,my requirement is when i select the treeitem, associated value has to be displayed in a label and change the value through text box.
Hope you are clear with my struct.
|
|
|
|
|
That sounds quite straightforward, so I do not really understand what the problem is. If the user selects the "Name" node, then you display the name, and if it gets changed, save the new information from the textbox. But perhpas you should be looking more at your overall design.
|
|
|
|
|
Yes exactly. So this design will not work for this requirement. is it?
any how thank you for the interest and help provided.
|
|
|
|
|
I was wondering what is the best way to set constanta in C/C++. Using a header file with all constants set as #defines? Kind of like:
#define pi (3.1416f)
#define gravity_m_div_sqrt_secs (9.81f)
Or, set as static members of a class?
#ifndef __COMMON__
#define __COMMON__
class Common{
public:
static float k_pi;
static float k_gravity_m_div_sqrt_secs;
};
#include "Common.h"
float Common::k_pi = 3.1416f;
float Common::k_gravity_m_div_sqrt_secs = 9.81f;
It think is better to set 'em as a class, because sometimes you need to access them in any part of the code. And if you modify any one of them, the compilation time will be faster. But then I think how much RAM will these constants will be use, so in that case #defines are useful.
I really want to know your opinion.
|
|
|
|
|
Waaaay... back in the 90s, the company's guru said to always use define s -- to save memory. We know better now.
|
|
|
|
|
That's a PRETTY good point. But at least you agree with me to set the define for each .cpp file and not all of them in one header file. One modification and BAM, at least 15 minutes to compile for one little change!
|
|
|
|
|
The converse point is also true. A typo in one place can lead to almost unfindable bugs.
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
I would go the second way, mostly for not polluting the global namespace. Also you should set the types to static const float, assuming they are not supposed to change during runtime. I like to name constants in all upper case, but that's just a personal preferrence.
The good thing about pessimism is, that you are always either right or pleasently surprised.
|
|
|
|
|
Message Closed
modified 17-Feb-15 4:55am.
|
|
|
|
|
Message Closed
modified 17-Feb-15 5:04am.
|
|
|
|
|
Don't use #define for constants. If you want to keep things tidy, use a dedicated namespace, and a separate definition.
namespace constants
{
extern const float pi;
}
#include "constants.h"
namespace constants
{
const float pi = 3.141593;
}
...
int i = 5;
float angle = constants::pi * i;
int* pi = &i;
...
This also demonstrates why using #defines will break your code
|
|
|
|
|
When using namespaces (in Visual Studio) you get the added benefit of IntelliSense helping you out.
I personally think it is overkill to put the definition in a cpp file as long as we are talking about simple constants.
Soren Madsen
"When you don't know what you're doing it's best to do it quickly" - Jase #DuckDynasty
|
|
|
|
|
SoMad wrote: I personally think it is overkill to put the definition in a cpp file as long as we are talking about simple constants.
I'd second that... plus if someone is tracking a value of a constant, it's getting hidden away a bit (unnecessarily) by putting it in a source file.
|
|
|
|
|
The benefit of having the definition in a cpp file is more apparent when the constant isn't a universal physical/mathematical one, but one that could conceivably change during development. Should this happen, there's no need to recompile all files that refer to it, which would be required if the definition is in the header file.
|
|
|
|
|
Although using the statics is a way to keep your namespace cleaner, the macros are used A LOT... and they allow your code to be compiled as C OR C++. If you use class/namespace enclosed statics you're pretty much C++ compliant only.
|
|
|
|
|
In my experience, very few projects have a requirement that they be compilable as both C and C++. Many libraries must be accessible from both C and C++, but a well-designed C-style interface will take care of that.
For example, instead of:
#define MAX_SIZE 42
write a function,
int GetMaxSize()
which returns the value of the constant from your library.
This has the further advantage of decoupling the library from the constant - any changes to MAX_SIZE won't require the client's code to be recompiled (possibly relinked, if we are talking about a static library).
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack.
--Winston Churchill
|
|
|
|
|
Well in my experience, there's A LOT of code that exists from the C days, so you still see macros a lot. And yes, most people use C style interfaces for libraries.
Important to note that the original question specified C AND C++. I was simply pointing out that namespace/class enclosed statics aren't C compliant.
Quote: I was wondering what is the best way to set constanta in C/C++
|
|
|
|
|
Perhaps I expressed myself poorly.
I was referring to the case where the library is written in C / C++ / <whatever>, but must be callable from a C-style interface (e.g. the MS-Windows SDK). I believe that it is poor practice to expose #defined constants in the library's header file, because it introduces tight coupling between the caller and the library - any change in the constant requires recompiling the client.
Having said that, I recognize that standard C practice is to define such constants, so that code such as below may be written:
header.h:
#define MAX_SIZE 42
...
code.c:
#include "header.h"
void foo(void)
{
int array[MAX_SIZE];
...
}
C99 and later support variable-length arrays. As developers transition to compilers supporting this feature, I suspect that the need for such constants may decrease.
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack.
--Winston Churchill
|
|
|
|