reman3/Rayman_X/cpa/Appli/WinS2B/Tree.cpp

351 lines
10 KiB
C++

//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// FILE : Tree.cpp
// AUTHOR : Catalin Cocos
//__________________________________________________________________________________________________
#include "stdinc.h"
#include "app.h"
#include "Tree.h"
#include "resource.h"
WNDPROC TreeIWP;
WNDPROC ViewIWP;
void SetTreeItemChildren(TV_ITEM* pItem)
{
char fName[_MAX_PATH+10] = {0};
CSTPArray<CDirInfo> arCrtItems;
arCrtItems.SetGranularity(10);
for(HTREEITEM hItem = TreeView_GetChild(hWTree, pItem->hItem); hItem; hItem = TreeView_GetNextSibling( hWTree, hItem))
{
TV_ITEM ti = { TVIF_HANDLE|TVIF_PARAM, hItem };
TreeView_GetItem( hWTree, &ti);
BOOL NA;
arCrtItems.SAdd((CDirInfo*)ti.lParam, NA);
}
strcpy(fName, ((CDirInfo*)pItem->lParam)->FileName());
strcat(fName, "\\*.*");
WIN32_FIND_DATA fd;
HANDLE hSearch = FindFirstFile( fName, &fd );
for(BOOL Found = (hSearch != INVALID_HANDLE_VALUE); Found; Found = FindNextFile( hSearch, &fd))
if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && *fd.cFileName != '.')
{
strcpy(fName, ((CDirInfo*)pItem->lParam)->FileName());
strcat(fName, "\\");
strcat(fName, fd.cFileName );
CDirInfo* pDi = new CDirInfo(fName);
if(arCrtItems.Index(pDi)<0)
{
TV_INSERTSTRUCT tis =
{ pItem->hItem, TVI_SORT ,
{ TVIF_CHILDREN|TVIF_SELECTEDIMAGE|TVIF_IMAGE|TVIF_PARAM|TVIF_STATE|TVIF_TEXT,
NULL,((pItem->state & TVIS_STATEIMAGEMASK)>TI_STATE_FILES)? TI_STATE_LOCKED:TI_STATE_NONE,
TVIS_STATEIMAGEMASK, fd.cFileName, 0, 0, 1, I_CHILDRENCALLBACK, (LPARAM)pDi
}
};
TreeView_InsertItem(hWTree, &tis);
}
else
delete pDi;
}
if( hSearch != INVALID_HANDLE_VALUE ) FindClose( hSearch );
}
LRESULT CALLBACK TreeWndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
{
switch(msg)
{
case WM_COMMAND:
switch(LOWORD(wp))
{
case ID_SELECT_TOGGLE:
ToggleTreeItemState(TreeView_GetSelection( hwnd ), FALSE);
break;
case ID_RECURSE_TOGGLE:
ToggleTreeItemState(TreeView_GetSelection( hwnd ), TRUE);
break;
}
break;
case WM_LBUTTONDOWN:
{
TV_HITTESTINFO ht = {{ LOWORD(lp), HIWORD(lp)}};
TreeView_HitTest( hwnd, &ht );
if(ht.hItem && ht.flags == TVHT_ONITEMSTATEICON )
{
HTREEITEM hItem = ht.hItem;
ht.pt.x -= 11;
TreeView_HitTest( hwnd, &ht );
ToggleTreeItemState( hItem, ht.flags == TVHT_ONITEMSTATEICON);
}
}
break;
case WM_SETFOCUS: nFocusWnd = FOCUS_TREE; break;
case WM_DESTROY:
ClearTree();
break;
}
return CallWindowProc( (int(CALLBACK*)())TreeIWP, hwnd, msg, wp, lp);
}
void NotifyParents( HTREEITEM hiItem)
{
if(!hiItem) return;
int Set = 0;
TV_ITEM tip = { TVIF_HANDLE|TVIF_PARAM, hiItem };
TreeView_GetItem( hWTree, &tip);
if( ((CDirInfo*)tip.lParam)->GetSize() )
Set = 1;
else
for(HTREEITEM hItem = TreeView_GetChild(hWTree, hiItem); hItem; hItem = TreeView_GetNextSibling( hWTree, hItem))
{
TV_ITEM ti = { TVIF_HANDLE|TVIF_STATE|TVIF_PARAM, hItem, 0, ~0 };
TreeView_GetItem( hWTree, &ti);
if((ti.state & TVIS_OVERLAYMASK) ||
(ti.state & TVIS_STATEIMAGEMASK) == TI_STATE_FILES ||
(ti.state & TVIS_STATEIMAGEMASK) == TI_STATE_RECURSE)
{
Set = 1;
break;
}
}
TV_ITEM ti = { TVIF_HANDLE|TVIF_STATE, hiItem, INDEXTOOVERLAYMASK(Set), TVIS_OVERLAYMASK };
TreeView_SetItem( hWTree, &ti);
NotifyParents(TreeView_GetParent(hWTree, hiItem));
}
void NotifyChildren( HTREEITEM hiItem, HTREEITEM hParent )
{
if(hParent)
{
TV_ITEM ti = { TVIF_HANDLE|TVIF_STATE, hParent, 0, TVIS_STATEIMAGEMASK|TVIS_OVERLAYMASK };
TreeView_GetItem( hWTree, &ti);
ti.state &= TVIS_STATEIMAGEMASK;
if(ti.state > TI_STATE_FILES )
{
ti.state = TI_STATE_LOCKED;
TV_ITEM tip = { TVIF_HANDLE|TVIF_STATE|TVIF_PARAM, hiItem , 0 ,~0 };
TreeView_GetItem( hWTree, &tip);
((CDirInfo*)tip.lParam)->DeleteAll();
}
else
ti.state = TI_STATE_NONE;
ti.hItem = hiItem;
TreeView_SetItem( hWTree, &ti);
}
for(HTREEITEM hItem = TreeView_GetChild(hWTree, hiItem); hItem; hItem = TreeView_GetNextSibling( hWTree, hItem))
NotifyChildren( hItem, hiItem);
}
void UpdateView( UINT state, CDirInfo* pDi)
{
UINT st = (state == TI_STATE_NONE? LSTATE_UNCHECKED:LSTATE_LOCKED);
LV_ITEM iIt = { LVIF_STATE, 0, 0, st, LVIS_STATEIMAGEMASK };
for( iIt.iItem = ListView_GetItemCount(hWListView); iIt.iItem>=0; iIt.iItem-- )
ListView_SetItem(hWListView, &iIt);
}
void ToggleTreeItemState(HTREEITEM hItem, BOOL RecurseState )
{
if(!hItem) return;
BOOL RecurseStateChanged = FALSE;
TV_ITEM ti = { TVIF_HANDLE|TVIF_STATE|TVIF_PARAM, hItem, 0, TVIS_STATEIMAGEMASK };
TreeView_GetItem( hWTree, &ti);
BOOL Selected = ti.state & TVIS_SELECTED;
ti.state &= TVIS_STATEIMAGEMASK;
if( ( ti.state == TI_STATE_LOCKED) ||
(RecurseState && (ti.state == TI_STATE_NONE))) return;
switch( ti.state )
{
case TI_STATE_NONE: ti.state = TI_STATE_FILES; break;
case TI_STATE_FILES:
ti.state = ((RecurseStateChanged = RecurseState)? TI_STATE_RECURSE: TI_STATE_NONE);
break;
case TI_STATE_RECURSE:
RecurseStateChanged = TRUE;
ti.state = (RecurseState? TI_STATE_FILES: TI_STATE_NONE);
break;
}
if(ti.state > TI_STATE_NONE) ((CDirInfo*)ti.lParam)->DeleteAll();
//if(RecurseStateChanged) ti.stateMask |= TVIS_OVERLAYMASK;
TreeView_SetItem( hWTree, &ti);
if(Selected) UpdateView( ti.state & TVIS_STATEIMAGEMASK, (CDirInfo*)ti.lParam);
if(RecurseStateChanged) NotifyChildren(hItem);
// NotifyParents(TreeView_GetParent(hWTree, hItem));
NotifyParents(hItem );
}
void ClearTree()
{
TreeView_DeleteAllItems ( hWTree);
}
void InitTree()
{
ClearTree();
// create the drive items
char buffer[1001], DriveName[_MAX_PATH + 10];
CDirInfo * pInfo;
if(GetLogicalDriveStrings(1000, buffer))
for(char* name = buffer; *name; name += strlen(name) + 2)
if(GetDriveType(name) == DRIVE_FIXED)
{
GetVolumeInformation( name, DriveName, _MAX_PATH, NULL, NULL, NULL, NULL, NULL );
name[strlen(name)-1] = 0;
if(*DriveName) CharLower(DriveName+1);
strcat( DriveName, " (");
strcat( DriveName, name);
strcat( DriveName, ")");
pInfo = new CDirInfo(name);
TV_INSERTSTRUCT tis =
{ NULL , TVI_LAST ,
{ TVIF_CHILDREN|TVIF_SELECTEDIMAGE|TVIF_IMAGE|TVIF_PARAM|TVIF_STATE|TVIF_TEXT,
NULL,TI_STATE_NONE, TVIS_STATEIMAGEMASK,
DriveName, 0, 3, 3, I_CHILDRENCALLBACK, (LPARAM)pInfo
}
};
TreeView_InsertItem(hWTree, &tis);
}
else name[strlen(name)-1] = 0;
}
//------------------------------------ View -----------------------------------
void DisplayView( HTREEITEM hItem, CDirInfo* dirInfo )
{
ListView_DeleteAllItems(hWListView);
char fName[_MAX_PATH+10];
strcpy(fName, dirInfo->FileName());
strcat(fName, "\\*.*");
TV_ITEM ti = { TVIF_HANDLE|TVIF_STATE, hItem, 0, TVIS_STATEIMAGEMASK };
TreeView_GetItem( hWTree, &ti);
ti.state &= TVIS_STATEIMAGEMASK;
UINT state = (ti.state > TI_STATE_NONE? LSTATE_LOCKED: LSTATE_UNCHECKED);
WIN32_FIND_DATA fd;
HANDLE hSearch = FindFirstFile( fName, &fd );
for(BOOL Found = (hSearch != INVALID_HANDLE_VALUE); Found; Found = FindNextFile( hSearch, &fd))
if(!(fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_SYSTEM )) &&
CnvEng.IsFileKnown( fd.cFileName))
{
LV_ITEM a = {LVIF_TEXT|LVIF_STATE|LVIF_PARAM,ListView_GetItemCount(hWListView),0,
state,0, fd.cFileName, 0,0, (LPARAM) hItem };
ListView_InsertItem( hWListView, &a);
}
if( hSearch != INVALID_HANDLE_VALUE )
{
FindClose( hSearch );
LV_FINDINFO fi = {LVFI_STRING};
LV_ITEM tItem = { LVIF_STATE, 0, 0, LSTATE_CHECKED|LVIS_SELECTED, ~0 };
for(int i = dirInfo->GetUpperBound(); i>=0; i--)
{
fi.psz = (*dirInfo)[i]->FileName();
if((tItem.iItem = ListView_FindItem( hWListView, -1, &fi)) < 0)
dirInfo->DeleteAt(i);
else
ListView_SetItem(hWListView, &tItem);
}
if(ListView_GetItemCount(hWListView))
{
int idx = ListView_GetNextItem( hWListView, -1, LVNI_SELECTED );
LV_ITEM iItem = { LVIF_STATE, max(idx, 0), 0, LVIS_FOCUSED, LVIS_FOCUSED };
ListView_SetItem(hWListView, &iItem);
}
}
else dirInfo->DeleteAll();
}
void SetFile( LV_ITEM* ptestItem, CDirInfo* pDi )
{
ListView_SetItem( hWListView, ptestItem);
char name[_MAX_FNAME];
LV_ITEM testItem = { LVIF_TEXT, ptestItem->iItem, 0, 0, 0, name, _MAX_FNAME};
ListView_GetItem( hWListView, &testItem);
CFileName* pName = new CFileName(name);
if((ptestItem->state & LVIS_STATEIMAGEMASK) == LSTATE_CHECKED)
{
BOOL NA;
pDi->SAdd( pName, NA, FALSE);
if( NA ) delete pName;
}
else
{
int idx = pDi->Index( pName );
if( idx>=0 ) pDi-> DeleteAt( idx );
delete pName;
}
}
void SetViewItemState( int idx )
{
if( idx<0) return;
LV_ITEM testItem = { LVIF_STATE| LVIF_PARAM, idx, 0, 0, ~LVIS_FOCUSED };
ListView_GetItem( hWListView, &testItem);
if( testItem.state & LSTATE_LOCKED) return;
testItem.state ^= (LSTATE_UNCHECKED|LSTATE_CHECKED);
HTREEITEM hti = (HTREEITEM)testItem.lParam;
TV_ITEM ti = { TVIF_HANDLE|TVIF_STATE|TVIF_PARAM, hti, 0, ~0 };
TreeView_GetItem( hWTree, &ti);
CDirInfo* pDi = (CDirInfo*) ti.lParam;
if(testItem.state & LVIS_SELECTED)
{
int maxCnt = ListView_GetSelectedCount( hWListView );
int i = 0;
for( testItem.iItem = -1; i<maxCnt; i++ )
{
testItem.iItem = ListView_GetNextItem( hWListView, testItem.iItem, LVNI_SELECTED );
SetFile( &testItem, pDi );
}
}
else SetFile( &testItem, pDi );
NotifyParents(hti);
}
LRESULT CALLBACK ViewWndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
{
switch(msg)
{
case WM_SETFOCUS: nFocusWnd = FOCUS_LISTVIEW; break;
case WM_COMMAND:
switch(LOWORD(wp))
{
case ID_SELECT_TOGGLE:
SetViewItemState( ListView_GetNextItem( hwnd, -1, LVNI_FOCUSED ) );
return 0;
case ID_SELECT_ALL:
{
LV_ITEM testItem = { LVIF_STATE, 0, 0, LVIS_SELECTED, LVIS_SELECTED };
for(testItem.iItem = ListView_GetItemCount( hwnd )-1; testItem.iItem>=0; testItem.iItem--)
ListView_SetItem( hwnd, &testItem);
return 0;
}
}
break;
case WM_LBUTTONDOWN:
{
LV_HITTESTINFO ht = {{ LOWORD(lp), HIWORD(lp)}};
ListView_HitTest( hwnd, &ht);
if(ht.iItem >=0 && ht.flags == LVHT_ONITEMSTATEICON)
{
SetFocus( hwnd );
SetViewItemState( ht.iItem );
return 0;
}
}
break;
}
return CallWindowProc( (int(CALLBACK*)())ViewIWP, hwnd, msg, wp, lp);
}