#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0500
///////////////////////////////////////////////////////////////////////////////////////
//
//
// TreeList Control For Win32
// Create by Eitan Michaelson 4/2011 , Noyasoft@gmail.com
//
//
///////////////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include "Container.h"
#include "Resource.h"
#pragma warning(disable : 4996) // CRT Secure - off (VC 8)
///////////////////////////////////////////////////////////////////////////////////////
//
// Section : Defines
//
///////////////////////////////////////////////////////////////////////////////////////
#define COLOR_WHITE RGB(255,255,255)
#define COLOR_GREEN RGB(0,255,0)
#define COLOR_RED RGB(255,0,0)
///////////////////////////////////////////////////////////////////////////////////////
//
// Section : Statics
//
///////////////////////////////////////////////////////////////////////////////////////
// This module is just a usage sample so I didn't bother with being thread safe
// Statics are OK here
// Handles array for 4 instances
static TREELIST_HANDLE TreeListHandle[4] = {0,0,0,0};
// Position for each instance on the parent window
static RECT TreeListRect[4] = {{010,010,300,150 },{310,010,610,150 }, {010,160,300,300 }, {310,160,610,300 }};
// Flags for each instance
static DWORD TreeListFlags[4] = {TREELIST_DRAW_EDGE, TREELIST_DRAW_EDGE | TREELIST_ANCHOR_RIGHT, TREELIST_DRAW_EDGE | TREELIST_ANCHOR_BOTTOM, TREELIST_DRAW_EDGE | TREELIST_ANCHOR_BOTTOM | TREELIST_ANCHOR_RIGHT | TREELIST_NORMAL_EDITBOX};
////////////////////////////////////////////////////////////////////////////////////
//
// Function: Container_ValidateEditRequest
// Description:
// Parameters:
// TreeListHandle a Handle to the control that was changed
// pAnyPtr: the pointer that was set for the edited node
// NewData: What was typed by the user
// Override: a string to be pushed back to the node
// insted of the original "NewData" (optional)
// Return: BOOL: If this edit request is valid or not
// Logic: This is only a sample!
//
////////////////////////////////////////////////////////////////////////////////////
static BOOL _stdcall Container_ValidateEditRequest(const TREELIST_HANDLE TreeListHandle,const void *pAnyPtr, const char *NewData,char *Override)
{
// Process the edit request here
// Example : get the pointer back:
// ------------------------------
// if(pAnyPtr)
// MessageBox(NULL,(char*)pAnyPtr,"Got the pointer..",MB_OK);
// Example: Force changing the cell data
// -------------------------------
// sprintf(Override,"%d",atol(NewData)); // Convert the user string to a number ("089" -> "89") and send it back to the API
return TRUE; // 'FALSE' Will prevent the edit request
}
////////////////////////////////////////////////////////////////////////////////////
//
// Function: Container_TreeListAddItem
// Description: Wrapper around TreeListNodeAdd ,
// a helper function to create a setup like the VC6 debugger TreeView box.
// Parameters: TREELIST_HANDLE a treelist handle
// Column info
// Note: last parameter is using a 'printf' like style
// Note: the length of "Name" and "Value" should be less then TREELIST_MAX_STRING !
// Return: NODE_HANDLE
//
////////////////////////////////////////////////////////////////////////////////////
static NODE_HANDLE Container_TreeListAddItem(TREELIST_HANDLE ListTreeHandle, NODE_HANDLE ParentHandle,BOOL Editable, long Color, void *pAnyPtr, char *Name,char *Value,...)
{
va_list args;
int InputLebgth = 0;
char ValBuffer[1024] = {0};
TreeListNodeData NodeItems[2]; // Only Value and Name columns so we will need an array of 2 nodes
// Retrieve the variable arguments
va_start( args, Value );
vsprintf( ValBuffer, Value, args );
va_end(args);
memset(&NodeItems,0,sizeof(NodeItems));
// Column 0 : Not editable, no back pointer
strncpy(NodeItems[0].Data,Name,TREELIST_MAX_STRING);
NodeItems[0].Editable = FALSE;
NodeItems[0].pExternalPtr = 0;
// Column 1 - Value
strncpy(NodeItems[1].Data,ValBuffer,TREELIST_MAX_STRING);
NodeItems[1].Editable = Editable;
NodeItems[1].Numeric = FALSE;
NodeItems[1].AltertedTextColor = RGB(0,22,67);
NodeItems[1].Colored = TRUE;
NodeItems[1].BackgroundColor = Color;
NodeItems[1].pExternalPtr = pAnyPtr;
// Call the API to add the data to the tree and return the node handle
return(TreeListAddNode(ListTreeHandle,ParentHandle,(TreeListNodeData*)(NodeItems),1));
}
////////////////////////////////////////////////////////////////////////////////////
//
// Function: Container_BuildColumns
// Description: Build the columns
// Parameters:void
// Return:void
//
////////////////////////////////////////////////////////////////////////////////////
static void Container_BuildColumns(TREELIST_HANDLE ListTreeHandle,int PreFix)
{
// Add columns, for the purpose of demonstration we will add additional column in each instance
int iCount = 0;
int iWidth = 300;
char ColText[32] = {0};
iWidth = iWidth - (300/(PreFix+1));
for(iCount = 0; iCount < (PreFix);iCount++)
{
sprintf(ColText,"Column %d",iCount);
TreeListAddColumn(ListTreeHandle,ColText, iWidth/PreFix);
}
// Name of column Width
// ---------------------------------
TreeListAddColumn(ListTreeHandle,"Value", TREELIST_LAST_COLUMN); // Note 'TREELIST_LAST_COLUMN' should be set for the last column.
}
////////////////////////////////////////////////////////////////////////////////////
//
// Function: Container_BuildTree
// Description: Uses the wrppper (Container_TreeListAddItem) to build the tree
// Parameters:NODE_HANDLE a treelist handle
// Return:void
//
////////////////////////////////////////////////////////////////////////////////////
static void Container_BuildTree(TREELIST_HANDLE ListTreeHandle,int PreFix)
{
NODE_HANDLE Root,ChildA,ChildB,ChildC,GChildA,GChildB,GChildC,GChildD,GGChildA,GGChildB;
char RootText[32] = {0};
char TimeText[32] = {0};
_strtime( TimeText );
sprintf(RootText,"Cell # %d",PreFix);
// Insert some nodes
// -------------------------------------------------------------------------------------------------------------------------------------
// Parent Can Edit? Color? Back Ptr Col#0 Data Col#1 Data ('printf' format)
Root = Container_TreeListAddItem (ListTreeHandle, NULL, FALSE, COLOR_WHITE, 0, RootText, "{...}" );
ChildA = Container_TreeListAddItem (ListTreeHandle, Root, FALSE, COLOR_WHITE, 0, "Child A", "0x%x",rand () );
ChildB = Container_TreeListAddItem (ListTreeHandle, Root, FALSE, COLOR_WHITE, 0, "Child B", "{...}" );
ChildC = Container_TreeListAddItem (ListTreeHandle, Root, TRUE, COLOR_GREEN, 0, "Child C", "Handle: 0x%x",ListTreeHandle );
GChildA = Container_TreeListAddItem (ListTreeHandle, ChildC, TRUE, COLOR_WHITE, 0, "Grandchild A", "Ticks: %d",GetTickCount() );
GChildB = Container_TreeListAddItem (ListTreeHandle, ChildC, TRUE, COLOR_WHITE, 0, "Grandchild B", "%s",TimeText );
GChildC = Container_TreeListAddItem (ListTreeHandle, ChildC, TRUE, COLOR_RED, 0, "Grandchild C", "My root# is %d",PreFix );
GChildD = Container_TreeListAddItem (ListTreeHandle, ChildB, FALSE, COLOR_WHITE, 0, "Grandchild D", "{...}" );
GGChildA = Container_TreeListAddItem (ListTreeHandle, GChildD, TRUE, COLOR_WHITE, 0, "Grand-Grandchild A", "Created By Eitan Michaelson" );
GGChildB = Container_TreeListAddItem (ListTreeHandle, GChildD, FALSE, COLOR_WHITE, 0, "Grand-Grandchild B", "2011 Noyasoft@gmail.com" );
}
////////////////////////////////////////////////////////////////////////////////////
//
// Function: Container_BuildTreeLists
// Description: Create few instances of the control on the parent window
// Parameters:void
// Return:void
//
////////////////////////////////////////////////////////////////////////////////////
static void Container_BuildTreeLists(HWND hWndDlg)
{
int iCount = 0;
int iTotal = 0;
int iTreeNum = 0;
srand ((unsigned int)time(NULL));
for(iTreeNum = 0;iTreeNum < 4;iTreeNum++)
{
TreeListHandle[iTreeNum] = TreeListCreate(GetModuleHandle(NULL) ,hWndDlg,&TreeListRect[iTreeNum],TreeListFlags[iTreeNum] ,&Container_ValidateEditRequest);
if(TreeListHandle[iTreeNum])
{
Container_BuildColumns(TreeListHandle[iTreeNum],iTreeNum);
for(iCount;iCount <= (iTotal + 25);iCount++)
Container_BuildTree(TreeListHandle[iTreeNum],iCount);
iTotal += iCount;
}
}
}
////////////////////////////////////////////////////////////////////////////////////
//
// Function: Container_KillTreeLists
// Description: Destroy all the control instances we've created
// Parameters:void
// Return:void
//
////////////////////////////////////////////////////////////////////////////////////
static void Container_KillTreeLists(void)
{
int iTreeNum = 0;
for(iTreeNum = 0;iTreeNum < 4;iTreeNum++)
{
if(TreeListHandle[iTreeNum])
TreeListDestroy(TreeListHandle[iTreeNum]); // Kill and free the control data
}
}
////////////////////////////////////////////////////////////////////////////////////
//
// Function: WinWndProc
// Description: The dialog proc
// Parameters:
// Return:
// Logic:
//
////////////////////////////////////////////////////////////////////////////////////
INT_PTR CALLBACK WinWndProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
char Title[32] = {0};
switch (Msg)
{
case WM_INITDIALOG : // This is a good place to init the control
{
// Set the windows's title
sprintf(Title,"TreeList Control Sample (%s)",TREELIST_APIVERSION);
SetWindowText(hWndDlg,Title);
// Attach the controls
Container_BuildTreeLists(hWndDlg);
return TRUE;
}
case WM_CLOSE:
{
// Remove the controls
Container_KillTreeLists();
EndDialog(hWndDlg, IDOK);
return TRUE;;
}
}
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////////
//
// Function: WinMain
// Description: The mother of all windows
// Parameters:
// Return:
// Logic:
//
////////////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
// Start The Main Dialog
DialogBox(hInstance , MAKEINTRESOURCE(IDD_DIALOG_MAIN),NULL, WinWndProc);
return 0;
}