2350 lines
52 KiB
C
2350 lines
52 KiB
C
/*++
|
|
|
|
Copyright (c) 1993-1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
FileSel.c
|
|
|
|
Abstract:
|
|
|
|
Handles processing for the file selection listbox. This is a
|
|
hierarchical file/directory tree with checkboxes besides the files
|
|
and directories.
|
|
|
|
If the checkbox is checked then that file or directory will be
|
|
copied, otherwise it won't. There are some directories that are
|
|
excluded by default. These are directories on the NW server that
|
|
are known to contain binaries that are not needed on the NT side
|
|
(such as the NetWare administration tools).
|
|
|
|
Author:
|
|
|
|
Arthur Hanson (arth) 10-Feb-1994
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "globals.h"
|
|
|
|
#include "hierfile.h"
|
|
#include "nwconv.h"
|
|
#include "convapi.h"
|
|
#include "ntnetapi.h"
|
|
#include "nwnetapi.h"
|
|
#include "columnlb.h"
|
|
#include "statbox.h"
|
|
#include "userdlg.h"
|
|
|
|
#include <math.h> // For pow function
|
|
|
|
#define X_BORDER 10
|
|
#define Y_BORDER 10
|
|
#define SPLITTER_WIDTH 3
|
|
#define BUTTON_Y_BORDER 6
|
|
#define BUTTON_X_BORDER 10
|
|
|
|
static int List1Width;
|
|
static int Splitter_Left;
|
|
static int Splitter_Bottom;
|
|
static HCURSOR CursorSplitter;
|
|
static HWND hwndList2 = 0;
|
|
static HWND hwndList1 = 0;
|
|
|
|
static SHARE_BUFFER *CurrentShare;
|
|
static SOURCE_SERVER_BUFFER *SServ;
|
|
static BOOL HiddenFiles = FALSE;
|
|
static BOOL SystemFiles = FALSE;
|
|
static DIR_BUFFER *oDir = NULL;
|
|
|
|
static ULONG TotalFileSize = 0;
|
|
static LPARAM mouseHit = 0;
|
|
static WORD LastFocus = 0;
|
|
static HWND ListFocus = NULL;
|
|
|
|
static ULONG TCount;
|
|
|
|
static WNDPROC _wpOrigWndProc;
|
|
static WNDPROC _wpOrigWndProc2;
|
|
|
|
|
|
HEIRDRAWSTRUCT HierDrawStruct;
|
|
BOOL SysDir = FALSE;
|
|
|
|
#define ROWS 2
|
|
#define COLS 2
|
|
|
|
// define a scratch buffer for quickly building up dir/file lists
|
|
#define DEF_NUM_RECS 50
|
|
#define DEF_REC_DELTA 25
|
|
static UINT BufferSize = 0;
|
|
static WIN32_FIND_DATA *ffd = NULL;
|
|
|
|
|
|
/*+-------------------------------------------------------------------------+
|
|
| Routines for Directory/File Trees |
|
|
+-------------------------------------------------------------------------+*/
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
FILE_PATH_BUFFER *
|
|
FilePathInit()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
FILE_PATH_BUFFER *fpBuf = NULL;
|
|
|
|
fpBuf = AllocMemory(sizeof(FILE_PATH_BUFFER));
|
|
if (fpBuf == NULL)
|
|
return NULL;
|
|
|
|
memset(fpBuf, 0, sizeof(FILE_PATH_BUFFER));
|
|
return fpBuf;
|
|
|
|
} // FilePathInit
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
FilePathServerSet(
|
|
FILE_PATH_BUFFER *fpBuf,
|
|
LPTSTR Server
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
fpBuf->Server = Server;
|
|
|
|
if (fpBuf->Server == NULL)
|
|
return;
|
|
|
|
wsprintf(fpBuf->FullPath, TEXT("\\\\%s\\"), Server);
|
|
|
|
} // FilePathServerSet
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
FilePathShareSet(
|
|
FILE_PATH_BUFFER *fpBuf,
|
|
LPTSTR Share
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
fpBuf->Share = Share;
|
|
if ((fpBuf->Server == NULL) || (fpBuf->Share == NULL))
|
|
return;
|
|
|
|
wsprintf(fpBuf->FullPath, TEXT("\\\\%s\\%s"), fpBuf->Server, Share);
|
|
fpBuf->Path = &fpBuf->FullPath[lstrlen(fpBuf->FullPath)];
|
|
|
|
} // FilePathShareSet
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
FilePathPathSet(
|
|
FILE_PATH_BUFFER *fpBuf,
|
|
LPTSTR Path
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
if ((fpBuf->Server == NULL) || (fpBuf->Share == NULL))
|
|
return;
|
|
|
|
*fpBuf->Path = TEXT('\0');
|
|
if (Path == NULL)
|
|
return;
|
|
|
|
lstrcat(fpBuf->FullPath, Path);
|
|
|
|
} // FilePathPathSet
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
TreeDelete(
|
|
DIR_BUFFER *Dir
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Walks an in-memory directory tree and free's up all the memory associated
|
|
with it and all child nodes.
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DIR_BUFFER *DList;
|
|
ULONG i;
|
|
|
|
if (Dir == NULL)
|
|
return;
|
|
|
|
if (Dir->DirList) {
|
|
DList = Dir->DirList->DirBuffer;
|
|
for (i = 0; i < Dir->DirList->Count; i++)
|
|
TreeDelete(&DList[i]);
|
|
|
|
FreeMemory(Dir->DirList);
|
|
}
|
|
|
|
if (Dir->FileList)
|
|
FreeMemory(Dir->FileList);
|
|
|
|
} // TreeDelete
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
TreePrune(
|
|
DIR_BUFFER *Dir
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Prunes a tree down by removing un-needed nodes. If a node is marked
|
|
as CONVERT_ALL or CONVERT_NONE then we don't need any of the child
|
|
leaves as we know these will be the same. Only CONVERT_PARTIAL
|
|
needs to be saved.
|
|
|
|
This is used so we only copy/save the minimum needed.
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
BYTE Convert;
|
|
DIR_BUFFER *DList;
|
|
ULONG i;
|
|
|
|
if (Dir == NULL)
|
|
return;
|
|
|
|
// First visit all of the children sub-dirs and prune them. Next:
|
|
// if partial convert then we can't delete this node, else we can
|
|
// clean up all the children - we leave it to the parent node to
|
|
// delete the current node.
|
|
Convert = Dir->Convert;
|
|
if (Dir->DirList) {
|
|
DList = Dir->DirList->DirBuffer;
|
|
for (i = 0; i < Dir->DirList->Count; i++)
|
|
TreePrune(&DList[i]);
|
|
|
|
if (Convert == CONVERT_PARTIAL)
|
|
return;
|
|
|
|
if (Dir->Special && (Convert == CONVERT_ALL))
|
|
return;
|
|
|
|
for (i = 0; i < Dir->DirList->Count; i++)
|
|
TreeDelete(&DList[i]);
|
|
|
|
Dir->DirList = NULL;
|
|
}
|
|
|
|
if (Convert == CONVERT_PARTIAL)
|
|
return;
|
|
|
|
if (Dir->FileList)
|
|
FreeMemory(Dir->FileList);
|
|
|
|
Dir->FileList = NULL;
|
|
|
|
} // TreePrune
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
_TreeCountR(
|
|
DIR_BUFFER *Dir
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Count all the files under a sub-dir. This recuses down all the child
|
|
nodes.
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
BYTE Convert;
|
|
DIR_BUFFER *DList;
|
|
ULONG i;
|
|
|
|
if ((Dir == NULL) || (!Dir->Convert))
|
|
return;
|
|
|
|
Convert = Dir->Convert;
|
|
if (Dir->DirList) {
|
|
DList = Dir->DirList->DirBuffer;
|
|
for (i = 0; i < Dir->DirList->Count; i++)
|
|
_TreeCountR(&DList[i]);
|
|
|
|
}
|
|
|
|
if (Dir->FileList)
|
|
for (i = 0; i < Dir->FileList->Count; i++)
|
|
if (Dir->FileList->FileBuffer[i].Convert)
|
|
TCount++;
|
|
|
|
} // _TreeCountR
|
|
|
|
|
|
ULONG TreeCount(DIR_BUFFER *Dir) {
|
|
TCount = 0;
|
|
if (Dir == NULL)
|
|
return TCount;
|
|
|
|
_TreeCountR(Dir);
|
|
return TCount;
|
|
|
|
} // TreeCount
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
_TreeCopyR(
|
|
DIR_BUFFER *Dir
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Duplicates a directory/File tree structure in memory.
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DIR_LIST *DList;
|
|
DIR_BUFFER *DBuff;
|
|
FILE_LIST *FList;
|
|
FILE_BUFFER *FBuff;
|
|
ULONG Size;
|
|
ULONG i;
|
|
|
|
if (Dir == NULL)
|
|
return;
|
|
|
|
if (Dir->FileList) {
|
|
// Create clone of file list
|
|
Size = sizeof(FILE_LIST) + (sizeof(FILE_BUFFER) * Dir->FileList->Count);
|
|
FList = AllocMemory(Size);
|
|
|
|
if (FList != NULL)
|
|
memcpy(FList, Dir->FileList, Size);
|
|
|
|
// Copied it, now fixup the internal pointers.
|
|
FList->parent = Dir;
|
|
|
|
FBuff = FList->FileBuffer;
|
|
for (i = 0; i < FList->Count; i++)
|
|
FBuff[i].parent = FList;
|
|
|
|
// Now replace pointer with cloned tree
|
|
Dir->FileList = FList;
|
|
}
|
|
|
|
if (Dir->DirList) {
|
|
// Create clone of Dir List
|
|
Size = sizeof(DIR_LIST) + (sizeof(DIR_BUFFER) * Dir->DirList->Count);
|
|
DList = AllocMemory(Size);
|
|
|
|
if (DList != NULL)
|
|
memcpy(DList, Dir->DirList, Size);
|
|
|
|
// Copied it, now fixup the internal pointers.
|
|
DList->parent = Dir;
|
|
|
|
DBuff = DList->DirBuffer;
|
|
for (i = 0; i < DList->Count; i++)
|
|
DBuff[i].parent = DList;
|
|
|
|
// Now replace pointer with cloned tree
|
|
Dir->DirList = DList;
|
|
|
|
// Now recurse into children and fix them up
|
|
for (i = 0; i < DList->Count; i++)
|
|
_TreeCopyR(&DBuff[i]);
|
|
|
|
}
|
|
|
|
} // _TreeCopyR
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
DIR_BUFFER *
|
|
TreeCopy(
|
|
DIR_BUFFER *Dir
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DIR_BUFFER *nDir = NULL;
|
|
|
|
if (Dir == NULL)
|
|
return NULL;
|
|
|
|
nDir = AllocMemory(sizeof(DIR_BUFFER));
|
|
if (nDir != NULL) {
|
|
memcpy(nDir, Dir, sizeof(DIR_BUFFER));
|
|
_TreeCopyR(nDir);
|
|
}
|
|
|
|
return nDir;
|
|
|
|
} // TreeCopy
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
int __cdecl
|
|
FileBufferCompare(
|
|
const VOID *arg1,
|
|
const VOID *arg2
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
WIN32_FIND_DATA *Farg1, *Farg2;
|
|
|
|
Farg1 = (WIN32_FIND_DATA *) arg1;
|
|
Farg2 = (WIN32_FIND_DATA *) arg2;
|
|
|
|
// This works as the first item of the structure is the string
|
|
return lstrcmpi( Farg1->cFileName, Farg2->cFileName);
|
|
|
|
} // FileBufferCompare
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
DirAdjustConvert(
|
|
DIR_BUFFER *Dir
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Need to adjust convert flag (none, full, partial) down the tree to the
|
|
root.
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
BOOL Partial = FALSE;
|
|
ULONG ChildCount = 0;
|
|
ULONG ChildSelected = 0;
|
|
DIR_LIST *DirList = NULL;
|
|
FILE_LIST *FileList = NULL;
|
|
ULONG i;
|
|
|
|
if (Dir == NULL)
|
|
return;
|
|
|
|
// if no files or dirs don't try to re-adjust current setting.
|
|
if ((Dir->DirList == NULL) && (Dir->FileList == NULL))
|
|
goto DirAdjRecurse;
|
|
|
|
// Scan the children directories to see what is to be converted.
|
|
DirList = Dir->DirList;
|
|
if (DirList != NULL) {
|
|
ChildCount += DirList->Count;
|
|
for (i = 0; i < DirList->Count; i++)
|
|
if (DirList->DirBuffer[i].Convert == CONVERT_PARTIAL)
|
|
Partial = TRUE;
|
|
else
|
|
ChildSelected += DirList->DirBuffer[i].Convert;
|
|
}
|
|
|
|
// if any of the children were partial convert then it is easy, as
|
|
// we are partial convert as well.
|
|
if (Partial) {
|
|
Dir->Convert = CONVERT_PARTIAL;
|
|
goto DirAdjRecurse;
|
|
}
|
|
|
|
|
|
// Scan the children files to see what is to be converted.
|
|
FileList = Dir->FileList;
|
|
if (FileList != NULL) {
|
|
ChildCount += FileList->Count;
|
|
for (i = 0; i < FileList->Count; i++)
|
|
ChildSelected += FileList->FileBuffer[i].Convert;
|
|
}
|
|
|
|
if (ChildSelected == ChildCount)
|
|
Dir->Convert = CONVERT_ALL;
|
|
else
|
|
if (ChildSelected == 0)
|
|
Dir->Convert = CONVERT_NONE;
|
|
else
|
|
Dir->Convert = CONVERT_PARTIAL;
|
|
|
|
DirAdjRecurse:
|
|
DirList = Dir->parent;
|
|
if (DirList != NULL)
|
|
DirAdjustConvert(DirList->parent);
|
|
|
|
} // DirAdjustConvert
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
DirAdjustConvertChildren(
|
|
DIR_BUFFER *Dir,
|
|
BYTE Convert
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DIR_LIST *DirList = NULL;
|
|
FILE_LIST *FileList = NULL;
|
|
ULONG i;
|
|
|
|
if (Dir == NULL)
|
|
return;
|
|
|
|
Dir->Convert = Convert;
|
|
|
|
// Scan the children files
|
|
FileList = Dir->FileList;
|
|
if (FileList != NULL)
|
|
for (i = 0; i < FileList->Count; i++)
|
|
FileList->FileBuffer[i].Convert = Convert;
|
|
|
|
// Scan the children directories
|
|
DirList = Dir->DirList;
|
|
if (DirList != NULL)
|
|
for (i = 0; i < DirList->Count; i++)
|
|
DirAdjustConvertChildren(&DirList->DirBuffer[i], Convert);
|
|
|
|
} // DirAdjustConvertChildren
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
BOOL
|
|
SubdirRestrict(
|
|
LPTSTR Path,
|
|
LPTSTR Subdir
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG i = 0;
|
|
LPTSTR RestrictPath[5];
|
|
CONVERT_OPTIONS * ConvertOptions;
|
|
|
|
// if the user has specified the 'transfer netware specific info'
|
|
// option the we should transfer the mail directory by default...
|
|
ConvertOptions = (CONVERT_OPTIONS *)CurrentConvertList->ConvertOptions;
|
|
|
|
if (ConvertOptions->NetWareInfo)
|
|
RestrictPath[i++] = Lids(IDS_S_3);
|
|
|
|
RestrictPath[i++] = Lids(IDS_S_2);
|
|
RestrictPath[i++] = Lids(IDS_S_4);
|
|
RestrictPath[i++] = Lids(IDS_S_5);
|
|
RestrictPath[i++] = NULL;
|
|
|
|
i = 0;
|
|
while(RestrictPath[i] != NULL) {
|
|
if (!lstrcmpi(RestrictPath[i], Subdir))
|
|
return TRUE;
|
|
|
|
i++;
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
} // SubdirRestrict
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
FillDirInit()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
if (ffd == NULL) {
|
|
ffd = AllocMemory(sizeof(WIN32_FIND_DATA) * DEF_NUM_RECS);
|
|
BufferSize = DEF_NUM_RECS;
|
|
}
|
|
|
|
} // FillDirInit
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
FillDir(
|
|
UINT Level,
|
|
LPTSTR Path,
|
|
DIR_BUFFER *Dir,
|
|
BOOL DoDirs
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Given a DIR_BUFFER, enumerate the files and sub-dirs under it and
|
|
attach them (one level-deep only).
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
static TCHAR NewPath[MAX_UNC_PATH + 1];
|
|
DIR_LIST *DirList = NULL;
|
|
DIR_LIST *OldDirList = NULL;
|
|
DIR_BUFFER *DBuff;
|
|
|
|
FILE_LIST *FileList = NULL;
|
|
FILE_LIST *OldFileList = NULL;
|
|
FILE_BUFFER *FBuff;
|
|
|
|
HANDLE fHandle = NULL;
|
|
ULONG DirCount = 0;
|
|
ULONG FileCount = 0;
|
|
ULONG Count = 0;
|
|
BOOL ret = TRUE;
|
|
ULONG i;
|
|
BYTE Convert;
|
|
BOOL ConvFlag;
|
|
|
|
FixPathSlash(NewPath, Path);
|
|
lstrcat(NewPath, TEXT("*.*"));
|
|
|
|
#ifdef DEBUG
|
|
dprintf(TEXT("Working on dir: %u %s\r\n"), Level, Path);
|
|
#endif
|
|
|
|
Panel_Line(7, TEXT("%s"), Path);
|
|
fHandle = FindFirstFile(NewPath, &ffd[Count]);
|
|
|
|
ret = (fHandle != INVALID_HANDLE_VALUE);
|
|
|
|
// loop filling in the temp buffer - figure out how many dirs and files
|
|
// we have to remember - and build up a temporary buffer of them
|
|
while (ret) {
|
|
|
|
if (ffd[Count].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
ConvFlag = TRUE;
|
|
|
|
if (!((lstrcmp(ffd[Count].cFileName, TEXT("."))) && (lstrcmp(ffd[Count].cFileName, TEXT("..")))))
|
|
ConvFlag = FALSE;
|
|
|
|
if (!HiddenFiles && (ffd[Count].dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
|
|
ConvFlag = FALSE;
|
|
|
|
if (!SystemFiles && (ffd[Count].dwFileAttributes & FILE_ATTRIBUTE_SYSTEM))
|
|
ConvFlag = FALSE;
|
|
|
|
// Use the cAlternateFileName as a flag whether to convert
|
|
if (ConvFlag) {
|
|
ffd[Count].cAlternateFileName[0] = 1;
|
|
DirCount++;
|
|
} else
|
|
ffd[Count].cAlternateFileName[0] = 0;
|
|
|
|
} else {
|
|
ConvFlag = TRUE;
|
|
|
|
if (!HiddenFiles && (ffd[Count].dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
|
|
ConvFlag = FALSE;
|
|
|
|
if (!SystemFiles && (ffd[Count].dwFileAttributes & FILE_ATTRIBUTE_SYSTEM))
|
|
ConvFlag = FALSE;
|
|
|
|
if (ConvFlag) {
|
|
ffd[Count].cAlternateFileName[0] = 1;
|
|
FileCount++;
|
|
} else
|
|
ffd[Count].cAlternateFileName[0] = 0;
|
|
|
|
}
|
|
|
|
Count++;
|
|
|
|
// check if we are going to run out of space in our buffer - if so
|
|
// allocate more space
|
|
if (Count >= BufferSize) {
|
|
BufferSize += DEF_REC_DELTA;
|
|
ffd = ReallocMemory(ffd, sizeof(WIN32_FIND_DATA) * BufferSize);
|
|
}
|
|
|
|
if (ffd == NULL) {
|
|
FindClose(fHandle);
|
|
return;
|
|
} else
|
|
ret = FindNextFile(fHandle, &ffd[Count]);
|
|
|
|
}
|
|
|
|
FindClose(fHandle);
|
|
|
|
#ifdef DEBUG
|
|
dprintf(TEXT(" Num Dirs / Files: %li %li\r\n"), DirCount, FileCount);
|
|
#endif
|
|
|
|
// Temp buffer is all filled in at this point. Sort it first
|
|
if (Count != 0)
|
|
qsort((void *) ffd, (size_t) Count, sizeof(WIN32_FIND_DATA), FileBufferCompare);
|
|
|
|
// Now create the actual list structures
|
|
if (DoDirs && DirCount)
|
|
DirList = AllocMemory(sizeof(DIR_LIST) + (sizeof(DIR_BUFFER) * DirCount));
|
|
|
|
if (FileCount)
|
|
FileList = AllocMemory(sizeof(FILE_LIST) + (sizeof(FILE_BUFFER) * FileCount));
|
|
|
|
// if there is no dirlist and there is an old one, clean up the old-one.
|
|
if (DoDirs && (DirList == NULL) && (Dir->DirList != NULL)) {
|
|
// save off file list so it isn't nuked
|
|
OldFileList = (FILE_LIST *) Dir->FileList;
|
|
Dir->FileList = NULL;
|
|
TreeDelete(Dir);
|
|
Dir->DirList = NULL;
|
|
|
|
// Now restore file list
|
|
Dir->FileList = OldFileList;
|
|
}
|
|
|
|
// same for file list.
|
|
if ((FileList == NULL) && (Dir->FileList != NULL)) {
|
|
FreeMemory(Dir->FileList);
|
|
Dir->FileList = NULL;
|
|
}
|
|
|
|
// If nothing to copy, or couldn't alloc memory then no reason to continue
|
|
// further...
|
|
if ((DirList == NULL) && (FileList == NULL))
|
|
return;
|
|
|
|
if (Dir->Convert == CONVERT_PARTIAL)
|
|
Convert = CONVERT_ALL;
|
|
else
|
|
Convert = Dir->Convert;
|
|
|
|
if (DoDirs && (DirList != NULL)) {
|
|
DirList->Count = DirCount;
|
|
DirList->Level = Level;
|
|
DirList->parent = Dir;
|
|
DirList->DirBuffer[DirCount - 1].Last = TRUE;
|
|
}
|
|
|
|
if (FileList != NULL) {
|
|
FileList->Count = FileCount;
|
|
FileList->parent = Dir;
|
|
}
|
|
|
|
// transfer the temp buffers to our list structures
|
|
DirCount = FileCount = 0;
|
|
for (i = 0; i < Count; i++) {
|
|
if (ffd[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
// Directories
|
|
if (DoDirs) {
|
|
// Check our Flag
|
|
if (ffd[i].cAlternateFileName[0] == 1) {
|
|
DBuff = &DirList->DirBuffer[DirCount];
|
|
DBuff->Attributes = ffd[i].dwFileAttributes;
|
|
lstrcpy(DBuff->Name, ffd[i].cFileName);
|
|
DBuff->parent = DirList;
|
|
|
|
// Check against the subdirs we don't want to convert by default
|
|
// if the user has already toggled that these should be converted,
|
|
// then the copy of the old info below will fix it back up.
|
|
if (SysDir && (Level == 1) && SubdirRestrict(Path, DBuff->Name)) {
|
|
DBuff->Convert = CONVERT_NONE;
|
|
DBuff->Special = TRUE;
|
|
} else
|
|
DBuff->Convert = Convert;
|
|
|
|
DirCount++;
|
|
}
|
|
}
|
|
} else {
|
|
// Files
|
|
Panel_Line(8, TEXT("%s"), ffd[i].cFileName);
|
|
|
|
// Check our Flag
|
|
if (ffd[i].cAlternateFileName[0] == 1) {
|
|
FBuff = &FileList->FileBuffer[FileCount];
|
|
FBuff->Attributes = ffd[i].dwFileAttributes;
|
|
lstrcpy(FBuff->Name, ffd[i].cFileName);
|
|
FBuff->parent = FileList;
|
|
FBuff->Convert = Convert;
|
|
FBuff->Size = ffd[i].nFileSizeLow;
|
|
|
|
TotalFileSize += ffd[i].nFileSizeLow;
|
|
Panel_Line(9, TEXT("%s"), lToStr(TotalFileSize));
|
|
FileCount++;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Now have the new lists filled in. If there was an old list then we must
|
|
// now merge ... can we say pain in the #$$
|
|
if (DoDirs) {
|
|
OldDirList = (DIR_LIST *) Dir->DirList;
|
|
Dir->DirList = DirList;
|
|
}
|
|
|
|
OldFileList = (FILE_LIST *) Dir->FileList;
|
|
Dir->FileList = FileList;
|
|
|
|
// Check the directories
|
|
if (DoDirs && (OldDirList != NULL) && (DirList != NULL)) {
|
|
int cmp;
|
|
|
|
DirCount = 0;
|
|
i = 0;
|
|
|
|
while (i < OldDirList->Count) {
|
|
do {
|
|
cmp = lstrcmpi(OldDirList->DirBuffer[i].Name, DirList->DirBuffer[DirCount].Name);
|
|
|
|
// a match so copy old data into new...
|
|
if (!cmp) {
|
|
DBuff = &DirList->DirBuffer[DirCount];
|
|
DBuff->Convert = OldDirList->DirBuffer[i].Convert;
|
|
DBuff->DirList = OldDirList->DirBuffer[i].DirList;
|
|
DBuff->FileList = OldDirList->DirBuffer[i].FileList;
|
|
|
|
// Now point these back to the new structures
|
|
if (DBuff->DirList)
|
|
DBuff->DirList->parent = DBuff;
|
|
|
|
if (DBuff->FileList)
|
|
DBuff->FileList->parent = DBuff;
|
|
}
|
|
|
|
// keep incrementing new dir list until we go past old server
|
|
// list, then must skip out and increment old server list
|
|
DirCount++;
|
|
} while ((DirCount < DirList->Count) && (cmp > 0));
|
|
|
|
if (DirCount >= DirList->Count)
|
|
break;
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
// Same stuff for the files
|
|
if ((OldFileList != NULL) && (FileList != NULL)) {
|
|
int cmp;
|
|
|
|
FileCount = 0;
|
|
i = 0;
|
|
|
|
while (i < OldFileList->Count) {
|
|
do {
|
|
cmp = lstrcmpi(OldFileList->FileBuffer[i].Name, FileList->FileBuffer[FileCount].Name);
|
|
|
|
// a match so copy old data into new...
|
|
if (!cmp)
|
|
FileList->FileBuffer[FileCount].Convert = OldFileList->FileBuffer[i].Convert;
|
|
|
|
FileCount++;
|
|
} while ((FileCount < FileList->Count) && (cmp > 0));
|
|
|
|
if (FileCount >= FileList->Count)
|
|
break;
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
// Clean up any old lists
|
|
if (OldDirList != NULL)
|
|
FreeMemory(OldDirList);
|
|
|
|
if (OldFileList != NULL)
|
|
FreeMemory(OldFileList);
|
|
|
|
DirAdjustConvert(Dir);
|
|
|
|
} // FillDir
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
_TreeFillRecurse(
|
|
UINT Level,
|
|
LPTSTR Path,
|
|
DIR_BUFFER *Dir
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
TCHAR NewPath[MAX_UNC_PATH + 1];
|
|
DIR_LIST *DirList = NULL;
|
|
ULONG i;
|
|
|
|
FillDir(Level, Path, Dir, TRUE);
|
|
DirList = Dir->DirList;
|
|
|
|
if (DirList != NULL)
|
|
for (i = 0; i < DirList->Count; i++) {
|
|
|
|
if (Panel_Cancel())
|
|
return;
|
|
|
|
if (DirList->DirBuffer[i].Convert) {
|
|
wsprintf(NewPath, TEXT("%s\\%s"), Path, DirList->DirBuffer[i].Name);
|
|
_TreeFillRecurse(Level + 1, NewPath, &DirList->DirBuffer[i]);
|
|
}
|
|
}
|
|
|
|
} // _TreeFillRecurse
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
TreeFillRecurse(
|
|
UINT Level,
|
|
LPTSTR Path,
|
|
DIR_BUFFER *Dir
|
|
)
|
|
{
|
|
TotalFileSize = 0;
|
|
FillDirInit();
|
|
_TreeFillRecurse(Level, Path, Dir);
|
|
} // TreeFillRecurse
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
ULONG
|
|
TotalFileSizeGet()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
return TotalFileSize;
|
|
} // TotalFileSizeGet
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
TreeRecurseCurrentShareSet(
|
|
SHARE_BUFFER *CShare
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
CurrentShare = CShare;
|
|
|
|
SysDir = FALSE;
|
|
if (!CShare)
|
|
return;
|
|
|
|
if (!lstrcmpi(CShare->Name, Lids(IDS_S_6)))
|
|
SysDir = TRUE;
|
|
|
|
return;
|
|
|
|
} // TreeRecurseCurrentShareSet
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
TreeRootInit(
|
|
SHARE_BUFFER *CShare,
|
|
LPTSTR NewPath
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
TreeRecurseCurrentShareSet(CShare);
|
|
|
|
if (CShare->Root)
|
|
return;
|
|
|
|
CShare->Root = AllocMemory(sizeof(DIR_BUFFER));
|
|
lstrcpy(CShare->Root->Name, NewPath);
|
|
CShare->Root->Last = TRUE;
|
|
CShare->Root->Attributes = FILE_ATTRIBUTE_DIRECTORY;
|
|
|
|
CShare->Root->DirList = NULL;
|
|
CShare->Root->FileList = NULL;
|
|
CShare->Root->parent = NULL;
|
|
|
|
// have to set this to preserve user selection of special excluded dirs...
|
|
if (SysDir)
|
|
CShare->Root->Special = TRUE;
|
|
|
|
CShare->Root->Convert = CONVERT_ALL;
|
|
|
|
FillDir(1, CShare->Root->Name, CShare->Root, TRUE);
|
|
DirAdjustConvert(CShare->Root);
|
|
|
|
} // TreeRootInit
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
ControlsResize(
|
|
HWND hDlg,
|
|
int Height,
|
|
int Width
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
HWND hCtrl;
|
|
int nHeight, nWidth, BtnWidth, BtnHeight;
|
|
RECT rc;
|
|
|
|
hCtrl = GetDlgItem(hDlg, IDOK);
|
|
GetWindowRect(hCtrl, &rc);
|
|
BtnWidth = (rc.right - rc.left);
|
|
BtnHeight = (rc.bottom - rc.top);
|
|
|
|
// Get size of first listbox and figure height as it is same for both
|
|
hCtrl = GetDlgItem(hDlg, IDC_LIST1);
|
|
GetWindowRect(hCtrl, &rc);
|
|
List1Width = (rc.right - rc.left);
|
|
nHeight = Height - Y_BORDER - BtnHeight - (2 * BUTTON_Y_BORDER); // subtract out borders
|
|
Splitter_Bottom = nHeight + Y_BORDER;
|
|
Splitter_Left = List1Width + X_BORDER;
|
|
|
|
// First Listbox never changes width on Window resize
|
|
MoveWindow(hCtrl, X_BORDER, Y_BORDER, List1Width, nHeight, TRUE);
|
|
GetWindowRect(hCtrl, &rc);
|
|
nHeight = (rc.bottom - rc.top);
|
|
|
|
// Second Listbox has width based on first and new size of Window.
|
|
if (Width > (2 * X_BORDER) + SPLITTER_WIDTH)
|
|
nWidth = Width - ( 2 * X_BORDER) - SPLITTER_WIDTH;
|
|
else
|
|
nWidth = 1;
|
|
|
|
// Now must take off from first listbox
|
|
if (nWidth > List1Width)
|
|
nWidth -= List1Width;
|
|
else
|
|
nWidth = 1;
|
|
|
|
hCtrl = GetDlgItem(hDlg, IDC_LIST2);
|
|
MoveWindow(hCtrl, X_BORDER + List1Width + SPLITTER_WIDTH, Y_BORDER, nWidth, nHeight, TRUE);
|
|
|
|
// Figure out where to put the buttons
|
|
nWidth = (Width / 2) - (((3 * BtnWidth) + (2 * BUTTON_X_BORDER)) / 2);
|
|
nHeight = Height - BtnHeight - BUTTON_Y_BORDER;
|
|
hCtrl = GetDlgItem(hDlg, IDOK);
|
|
MoveWindow(hCtrl, nWidth, nHeight, BtnWidth, BtnHeight, TRUE);
|
|
nWidth += BtnWidth + BUTTON_X_BORDER;
|
|
|
|
hCtrl = GetDlgItem(hDlg, IDCANCEL);
|
|
MoveWindow(hCtrl, nWidth, nHeight, BtnWidth, BtnHeight, TRUE);
|
|
nWidth += BtnWidth + BUTTON_X_BORDER;
|
|
|
|
hCtrl = GetDlgItem(hDlg, IDHELP);
|
|
MoveWindow(hCtrl, nWidth, nHeight, BtnWidth, BtnHeight, TRUE);
|
|
|
|
} // ControlsResize
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
FileSelect_OnDrawItem(
|
|
HWND hwnd,
|
|
DRAWITEMSTRUCT FAR* lpDrawItem
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
TCHAR szText[MAX_PATH + 1];
|
|
DWORD dwData;
|
|
int nLevel = 0;
|
|
int nTempLevel;
|
|
int nRow = 0;
|
|
int nColumn = 0;
|
|
int chkColumn = 0;
|
|
DWORD dwConnectLevel = 0;
|
|
DWORD dwMask;
|
|
DIR_BUFFER *Dir, *Dir2;
|
|
FILE_BUFFER *File;
|
|
DIR_LIST *DirList, *DirList2;
|
|
BOOL FileBox = FALSE;
|
|
|
|
dwData = lpDrawItem->itemData;
|
|
if (dwData == 0)
|
|
return;
|
|
|
|
if ((lpDrawItem->CtlID != IDC_LIST1) && (lpDrawItem->CtlID != IDC_LIST2))
|
|
return;
|
|
|
|
if (lpDrawItem->CtlID == IDC_LIST2)
|
|
FileBox = TRUE;
|
|
|
|
// Select the correct icon, open folder, closed folder, or document.
|
|
|
|
if (FileBox) {
|
|
File = (FILE_BUFFER *) dwData;
|
|
lstrcpy(szText, File->Name);
|
|
nRow = 1;
|
|
chkColumn = File->Convert;
|
|
} else {
|
|
|
|
Dir2 = Dir = (DIR_BUFFER *) dwData;
|
|
lstrcpy(szText, Dir->Name);
|
|
chkColumn = Dir->Convert;
|
|
DirList2 = DirList = (DIR_LIST *) Dir->parent;
|
|
|
|
if (DirList != NULL)
|
|
nLevel = DirList->Level;
|
|
|
|
// Is it open ?
|
|
if ( HierFile_IsOpened(&HierDrawStruct, dwData) )
|
|
nColumn = 1;
|
|
else
|
|
nColumn = 0;
|
|
|
|
// Connect level figures out what connecting lines should be drawn
|
|
// - stored as a bitmask.
|
|
if (nLevel == 0)
|
|
dwConnectLevel = 0;
|
|
else {
|
|
nTempLevel = nLevel - 1;
|
|
|
|
// First bit to set
|
|
dwMask = (DWORD) pow(2, nLevel - 1);
|
|
|
|
// Now go through and figure out what else to set...
|
|
while (nTempLevel >= 0) {
|
|
// Check if last child at this level...
|
|
if (!Dir2->Last)
|
|
dwConnectLevel |= dwMask;
|
|
|
|
// figure out next parent...
|
|
Dir2 = DirList2->parent;
|
|
DirList2 = Dir2->parent;
|
|
|
|
// move mask bit over, and up a level.
|
|
dwMask /= 2;
|
|
|
|
// move up one level.
|
|
nTempLevel--;
|
|
}
|
|
}
|
|
}
|
|
|
|
// All set to call drawing function.
|
|
HierFile_OnDrawItem(hwnd, lpDrawItem, nLevel, dwConnectLevel, szText,
|
|
nRow, nColumn, chkColumn, &HierDrawStruct);
|
|
|
|
return;
|
|
|
|
} // FileSelect_OnDrawItem
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
RecursePath(
|
|
LPTSTR Path,
|
|
DIR_BUFFER *Dir
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DIR_LIST *DirList;
|
|
ULONG i;
|
|
|
|
DirList = (DIR_LIST *) Dir->parent;
|
|
|
|
if (DirList != NULL)
|
|
RecursePath(Path, (DIR_BUFFER *) DirList->parent);
|
|
|
|
i = lstrlen(Path);
|
|
if (i)
|
|
if (Path[i-1] != TEXT('\\'))
|
|
lstrcat(Path, TEXT("\\"));
|
|
|
|
lstrcat(Path, Dir->Name);
|
|
} // RecursePath
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
CloseList(
|
|
HWND hWndList,
|
|
DIR_BUFFER *Dir,
|
|
WORD wItemNum
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD dwIncr;
|
|
DWORD Count;
|
|
DIR_LIST *DirList;
|
|
|
|
HierFile_CloseItem(&HierDrawStruct, (DWORD) Dir);
|
|
DirList = (DIR_LIST *) Dir->DirList;
|
|
|
|
if (DirList != NULL) {
|
|
Count = DirList->Count;
|
|
|
|
// Remove the child items. Close any children that are open on the way.
|
|
// wItem can stay constant - we are moveing stuff up in the listbox as we are deleting.
|
|
wItemNum++;
|
|
dwIncr = SendMessage(hWndList, LB_GETITEMDATA, wItemNum, 0L);
|
|
|
|
while (Count) {
|
|
// Is this child open ?
|
|
if ( HierFile_IsOpened(&HierDrawStruct, dwIncr) ) {
|
|
CloseList(hWndList, (DIR_BUFFER *) dwIncr, wItemNum);
|
|
}
|
|
|
|
SendMessage(hWndList, LB_DELETESTRING, wItemNum, 0L);
|
|
dwIncr = SendMessage(hWndList, LB_GETITEMDATA, wItemNum, 0L);
|
|
Count--;
|
|
}
|
|
|
|
}
|
|
|
|
} // CloseList
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
FileSelect_ActionItem(
|
|
HWND hWndList,
|
|
DWORD dwData,
|
|
WORD wItemNum
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
static TCHAR NewPath[MAX_PATH + 1];
|
|
DWORD Count = 0;
|
|
DIR_BUFFER *Dir;
|
|
DIR_LIST *DirList;
|
|
FILE_LIST *FileList;
|
|
ULONG i;
|
|
|
|
if (!dwData)
|
|
return;
|
|
|
|
// Is it open ?
|
|
if ( HierFile_IsOpened(&HierDrawStruct, dwData) ) {
|
|
|
|
// It's open ... Close it
|
|
Dir = (DIR_BUFFER *) dwData;
|
|
DirList = (DIR_LIST *) Dir->DirList;
|
|
CloseList(hWndList, Dir, wItemNum);
|
|
} else {
|
|
|
|
// It's closed ... Open it
|
|
HierFile_OpenItem(&HierDrawStruct, dwData);
|
|
|
|
SendMessage(hWndList, WM_SETREDRAW, FALSE, 0L); // Disable redrawing.
|
|
|
|
CursorHourGlass();
|
|
|
|
Dir = (DIR_BUFFER *) dwData;
|
|
#ifdef DEBUG
|
|
dprintf(TEXT("Opening dir: %s\r\n"), Dir->Name);
|
|
#endif
|
|
|
|
DirList = (DIR_LIST *) Dir->parent;
|
|
if (DirList == NULL)
|
|
FillDir(1, Dir->Name, Dir, TRUE);
|
|
else {
|
|
// recurse backwards to create full path
|
|
lstrcpy(NewPath, TEXT(""));
|
|
RecursePath(NewPath, Dir);
|
|
FillDir(DirList->Level + 1, NewPath, Dir, TRUE);
|
|
}
|
|
|
|
DirList = NULL;
|
|
|
|
// Check if we have visited this node, if not allocate and fill it in.
|
|
if (Dir->DirList != NULL) {
|
|
DirList = (DIR_LIST *) Dir->DirList;
|
|
Count = DirList->Count;
|
|
|
|
for (i = 0; i < DirList->Count; i++) {
|
|
SendMessage(hWndList, LB_INSERTSTRING, (WPARAM) wItemNum + i + 1, (LPARAM) &DirList->DirBuffer[i]);
|
|
}
|
|
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if (Dir->FileList == NULL)
|
|
dprintf(TEXT("FileList NULL\r\n"));
|
|
#endif
|
|
|
|
if (Dir->FileList != NULL) {
|
|
FileList = (FILE_LIST *) Dir->FileList;
|
|
|
|
#ifdef DEBUG
|
|
dprintf(TEXT("FileList Count: %li\r\n"), FileList->Count);
|
|
#endif
|
|
SendMessage(hwndList2, LB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0L);
|
|
for (i = 0; i < FileList->Count; i++) {
|
|
SendMessage(hwndList2, LB_ADDSTRING, (WPARAM) 0, (LPARAM) &FileList->FileBuffer[i]);
|
|
}
|
|
|
|
}
|
|
|
|
// Make sure as many child items as possible are showing
|
|
HierFile_ShowKids(&HierDrawStruct, hWndList, (WORD) wItemNum, (WORD) Count );
|
|
|
|
CursorNormal();
|
|
}
|
|
|
|
SendMessage(hWndList, WM_SETREDRAW, TRUE, 0L); // Enable redrawing.
|
|
InvalidateRect(hWndList, NULL, TRUE); // Force redraw
|
|
|
|
} // FileSelect_ActionItem
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
TreeOpenRecurse(
|
|
DIR_BUFFER *Dir,
|
|
WORD *wItemNum
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DIR_LIST *DirList = NULL;
|
|
ULONG i;
|
|
|
|
// if it's closed, open it
|
|
if ( !HierFile_IsOpened(&HierDrawStruct, (DWORD) Dir) )
|
|
FileSelect_ActionItem(hwndList1, (DWORD) Dir, *wItemNum);
|
|
|
|
DirList = Dir->DirList;
|
|
if (DirList != NULL) {
|
|
|
|
for (i = 0; i < DirList->Count; i++) {
|
|
(*wItemNum)++;
|
|
// Now recurse down the children
|
|
TreeOpenRecurse(&DirList->DirBuffer[i], wItemNum);
|
|
}
|
|
}
|
|
|
|
} // TreeOpenRecurse
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
FileSelect_UpdateFiles(
|
|
HWND hDlg
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
static TCHAR NewPath[MAX_PATH + 1];
|
|
WORD wItemNum;
|
|
DWORD dwData;
|
|
HWND hCtrl;
|
|
ULONG i;
|
|
FILE_LIST *FileList;
|
|
DIR_BUFFER *Dir;
|
|
DIR_LIST *DirList;
|
|
|
|
hCtrl = GetDlgItem(hDlg, IDC_LIST1);
|
|
wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L);
|
|
|
|
if (wItemNum == (WORD) LB_ERR)
|
|
wItemNum = LastFocus;
|
|
|
|
// Check first listbox and resynch the directory information so that we
|
|
// pick up the current file list.
|
|
LastFocus = wItemNum;
|
|
dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L);
|
|
|
|
if ((dwData == (DWORD) LB_ERR) || (dwData == 0))
|
|
return;
|
|
|
|
Dir = (DIR_BUFFER *) dwData;
|
|
#ifdef DEBUG
|
|
dprintf(TEXT("Opening dir: %lX %s\r\n"), Dir->parent, Dir->Name);
|
|
#endif
|
|
|
|
DirList = (DIR_LIST *) Dir->parent;
|
|
if (DirList == NULL)
|
|
FillDir(1, Dir->Name, Dir, FALSE);
|
|
else {
|
|
// recurse backwards to create full path
|
|
lstrcpy(NewPath, TEXT(""));
|
|
RecursePath(NewPath, Dir);
|
|
FillDir(DirList->Level + 1, NewPath, Dir, FALSE);
|
|
}
|
|
|
|
// Since Dir pointer was changed need to update listbox pointer
|
|
SendMessage(hCtrl, LB_SETITEMDATA, wItemNum, (LPARAM) Dir);
|
|
|
|
// We have not re-synched the directory so we have the correct file info
|
|
// now reset the file listbox and fill it with the new file-list.
|
|
SendMessage(hwndList2, LB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0L);
|
|
|
|
if (Dir->FileList != NULL) {
|
|
FileList = (FILE_LIST *) Dir->FileList;
|
|
|
|
#ifdef DEBUG
|
|
dprintf(TEXT("FileList Count: %li\r\n"), FileList->Count);
|
|
#endif
|
|
for (i = 0; i < FileList->Count; i++)
|
|
SendMessage(hwndList2, LB_ADDSTRING, (WPARAM) 0, (LPARAM) &FileList->FileBuffer[i]);
|
|
|
|
}
|
|
|
|
} // FileSelect_UpdateFiles
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
FileSelect_OnCommand(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
static TCHAR NewPath[MAX_PATH + 1];
|
|
int wmId, wmEvent;
|
|
WORD wItemNum;
|
|
DWORD dwData;
|
|
HWND hCtrl;
|
|
DIR_LIST *DirList;
|
|
FILE_LIST *FileList;
|
|
DIR_BUFFER *Dir;
|
|
int nLevel = 0;
|
|
|
|
wmId = LOWORD(wParam);
|
|
wmEvent = HIWORD(wParam);
|
|
|
|
switch (wmId) {
|
|
|
|
case IDOK:
|
|
// If we are on either of the listboxes, then use the Enter key to
|
|
// activate the selected item
|
|
if (ListFocus == hwndList1) {
|
|
hCtrl = GetDlgItem(hDlg, IDC_LIST1);
|
|
wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L);
|
|
dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L);
|
|
|
|
if ((wItemNum == (WORD) LB_ERR) || (dwData == LB_ERR) || (dwData == 0))
|
|
break;
|
|
|
|
FileSelect_ActionItem(hCtrl, dwData, wItemNum);
|
|
} else {
|
|
CurrentShare->HiddenFiles = HiddenFiles;
|
|
CurrentShare->SystemFiles = SystemFiles;
|
|
|
|
// Delete our copy of the tree and prune the tree down to minimum
|
|
// storage space
|
|
TreeDelete(oDir);
|
|
TreePrune(CurrentShare->Root);
|
|
|
|
EndDialog(hDlg, 0);
|
|
}
|
|
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
|
|
// Disable listboxes since we are deleting their item data
|
|
SendDlgItemMessage(hDlg, IDC_LIST1, WM_SETREDRAW, FALSE, 0L);
|
|
SendDlgItemMessage(hDlg, IDC_LIST2, WM_SETREDRAW, FALSE, 0L);
|
|
|
|
// Get back our old tree
|
|
if (CurrentShare->Root != NULL)
|
|
TreeDelete(CurrentShare->Root);
|
|
CurrentShare->Root = oDir;
|
|
|
|
EndDialog(hDlg, 0);
|
|
break;
|
|
|
|
case IDHELP:
|
|
WinHelp(hDlg, HELP_FILE, HELP_CONTEXT, (DWORD) IDC_HELP_FTRANS);
|
|
break;
|
|
|
|
case IDM_EXP_ONE:
|
|
// expand the current node
|
|
hCtrl = GetDlgItem(hDlg, IDC_LIST1);
|
|
wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L);
|
|
dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L);
|
|
|
|
if ((wItemNum == (WORD) LB_ERR) || (dwData == LB_ERR) || (dwData == 0))
|
|
break;
|
|
|
|
if ( !HierFile_IsOpened(&HierDrawStruct, dwData) )
|
|
FileSelect_ActionItem(hCtrl, dwData, wItemNum);
|
|
|
|
break;
|
|
|
|
case IDM_EXP_ALL:
|
|
// Open all children from the root
|
|
wItemNum = 0;
|
|
hCtrl = GetDlgItem(hDlg, IDC_LIST1);
|
|
goto ExpandTree;
|
|
|
|
case IDM_EXP_BRANCH:
|
|
// Traverse down the branch, opening up all children
|
|
hCtrl = GetDlgItem(hDlg, IDC_LIST1);
|
|
wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L);
|
|
|
|
ExpandTree:
|
|
dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L);
|
|
if ((wItemNum == (WORD) LB_ERR) || (dwData == LB_ERR) || (dwData == 0))
|
|
break;
|
|
|
|
Dir = (DIR_BUFFER *) dwData;
|
|
CursorHourGlass();
|
|
|
|
TreeOpenRecurse(Dir, &wItemNum);
|
|
|
|
CursorNormal();
|
|
|
|
// Force redraw
|
|
InvalidateRect(hwndList1, NULL, TRUE);
|
|
break;
|
|
|
|
case IDM_COLLAPSE:
|
|
// Close the current branch
|
|
hCtrl = GetDlgItem(hDlg, IDC_LIST1);
|
|
wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L);
|
|
dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L);
|
|
|
|
if ((wItemNum == (WORD) LB_ERR) || (dwData == LB_ERR) || (dwData == 0))
|
|
break;
|
|
|
|
if ( HierFile_IsOpened(&HierDrawStruct, dwData) )
|
|
FileSelect_ActionItem(hCtrl, dwData, wItemNum);
|
|
|
|
break;
|
|
|
|
// Not used currently
|
|
case IDM_VIEW_BOTH:
|
|
case IDM_VIEW_TREE:
|
|
case IDM_VIEW_DIR:
|
|
break;
|
|
|
|
case IDM_HIDDEN:
|
|
HiddenFiles = !HiddenFiles;
|
|
CheckMenuItem((HMENU) wParam, IDM_HIDDEN, HiddenFiles ? MF_CHECKED : MF_UNCHECKED);
|
|
PostMessage(hDlg, WM_COMMAND, ID_REDRAWLIST, 0L);
|
|
break;
|
|
|
|
case IDM_SYSTEM:
|
|
SystemFiles = !SystemFiles;
|
|
CheckMenuItem((HMENU) wParam, IDM_SYSTEM, SystemFiles ? MF_CHECKED : MF_UNCHECKED);
|
|
PostMessage(hDlg, WM_COMMAND, ID_REDRAWLIST, 0L);
|
|
break;
|
|
|
|
case ID_REDRAWLIST:
|
|
FileSelect_UpdateFiles(hDlg);
|
|
break;
|
|
|
|
case IDC_LIST1:
|
|
|
|
switch (wmEvent) {
|
|
case LBN_SETFOCUS:
|
|
ListFocus = hwndList1;
|
|
break;
|
|
|
|
case LBN_KILLFOCUS:
|
|
ListFocus = NULL;
|
|
break;
|
|
|
|
case LBN_DBLCLK:
|
|
// Disregard the DBLCLK message if it is inside a checkbox.
|
|
hCtrl = GetDlgItem(hDlg, IDC_LIST1);
|
|
|
|
// First figure out where checkbox is located in listbox
|
|
wItemNum = (WORD) SendMessage(hCtrl, LB_GETCURSEL, 0, 0L);
|
|
dwData = (DWORD) SendMessage(hCtrl, LB_GETITEMDATA, wItemNum, 0L);
|
|
|
|
if ((wItemNum == (WORD) LB_ERR) || (dwData == LB_ERR) || (dwData == 0))
|
|
break;
|
|
|
|
Dir = (DIR_BUFFER *) dwData;
|
|
DirList = (DIR_LIST *) Dir->parent;
|
|
|
|
if (DirList != NULL)
|
|
nLevel = DirList->Level;
|
|
|
|
if (!HierFile_InCheck(nLevel, LOWORD(mouseHit), &HierDrawStruct)) {
|
|
CursorHourGlass();
|
|
FileSelect_ActionItem(hCtrl, dwData, wItemNum);
|
|
CursorNormal();
|
|
}
|
|
|
|
break;
|
|
|
|
case LBN_SELCHANGE:
|
|
FileSelect_UpdateFiles(hDlg);
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ID_UPDATELIST:
|
|
hCtrl = GetDlgItem(hDlg, IDC_LIST1);
|
|
if (CurrentShare->Root == NULL) {
|
|
wsprintf(NewPath, TEXT("\\\\%s\\%s\\"), SServ->Name, CurrentShare->Name);
|
|
|
|
#ifdef DEBUG
|
|
// lstrcpy(NewPath, TEXT("c:\\"));
|
|
dprintf(TEXT("Root Path: %s\n"), NewPath);
|
|
#endif
|
|
TreeRootInit(CurrentShare, NewPath);
|
|
}
|
|
|
|
PostMessage(hCtrl, LB_SETCURSEL, (WPARAM) 0, 0L);
|
|
LastFocus = 0;
|
|
|
|
DirList = (DIR_LIST *) CurrentShare->Root->DirList;
|
|
FileList = (FILE_LIST *) CurrentShare->Root->FileList;
|
|
|
|
wItemNum = (WORD) SendMessage(hCtrl, LB_ADDSTRING, (WPARAM) 0, (LPARAM) CurrentShare->Root);
|
|
PostMessage(hDlg, WM_COMMAND, ID_REDRAWLIST, 0L);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} // FileSelect_OnCommand
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
LRESULT CALLBACK
|
|
FileSelectSubClassProc(
|
|
HWND hWnd,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Handles key processing for the hierarchical listbox. Specifically
|
|
the up/down arrow keys and the letter keys.
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LRESULT lResult = 0;
|
|
BOOL fCallOrigProc = TRUE;
|
|
WORD wItemNum, wNewNum;
|
|
DWORD dwData;
|
|
DIR_BUFFER *Dir;
|
|
DIR_LIST *DirList;
|
|
FILE_BUFFER *File;
|
|
int nLevel = 0;
|
|
int lHeight, ListHeight, PageCount;
|
|
|
|
RECT rc;
|
|
|
|
switch (message) {
|
|
case WM_LBUTTONDOWN:
|
|
// Send message to check if button-down is within our checkbox
|
|
wItemNum = (WORD) SendMessage(hWnd, LB_GETCURSEL, 0, 0L);
|
|
|
|
// Save the location off so we can check it during a DBLCLK message
|
|
// to see if we are inside a checkbox.
|
|
mouseHit = lParam;
|
|
|
|
// Post the message so the current selection is correct
|
|
PostMessage(hWnd, WM_COMMAND, ID_CHECKCHECK, lParam);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
// Code for handling checkbox clicking
|
|
if (wParam == ID_CHECKCHECK) {
|
|
// First figure out where checkbox is located in listbox
|
|
wItemNum = (WORD) SendMessage(hWnd, LB_GETCURSEL, 0, 0L);
|
|
dwData = (DWORD) SendMessage(hWnd, LB_GETITEMDATA, wItemNum, 0L);
|
|
|
|
if (wItemNum == (WORD) LB_ERR)
|
|
break;
|
|
|
|
if (hWnd == hwndList2) {
|
|
File = (FILE_BUFFER *) dwData;
|
|
|
|
if (HierFile_InCheck(nLevel, LOWORD(lParam), &HierDrawStruct)) {
|
|
if (File->Convert == CONVERT_NONE)
|
|
File->Convert = CONVERT_ALL;
|
|
else
|
|
File->Convert = CONVERT_NONE;
|
|
|
|
DirAdjustConvert(File->parent->parent);
|
|
}
|
|
|
|
} else {
|
|
Dir = (DIR_BUFFER *) dwData;
|
|
DirList = (DIR_LIST *) Dir->parent;
|
|
|
|
if (DirList != NULL)
|
|
nLevel = DirList->Level;
|
|
|
|
if (HierFile_InCheck(nLevel, LOWORD(lParam), &HierDrawStruct)) {
|
|
if (Dir->Convert == CONVERT_NONE)
|
|
DirAdjustConvertChildren(Dir, CONVERT_ALL);
|
|
else
|
|
DirAdjustConvertChildren(Dir, CONVERT_NONE);
|
|
|
|
DirAdjustConvert(Dir);
|
|
}
|
|
}
|
|
|
|
// Now check if button click was within checkbox boundaries...
|
|
if (HierFile_InCheck(nLevel, LOWORD(lParam), &HierDrawStruct)) {
|
|
|
|
// We have set the checkbox state correctly on the current item,
|
|
// and propageted this up and down the tree as necessary, now
|
|
// update the screen to reflect these changes.
|
|
InvalidateRect(hWnd, NULL, TRUE); // Force redraw
|
|
|
|
// if this is the directory listbox then also need to redraw
|
|
// the file listbox
|
|
if (hWnd == hwndList1)
|
|
InvalidateRect(hwndList2, NULL, TRUE);
|
|
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_KEYDOWN:
|
|
wItemNum = (WORD) SendMessage(hWnd, LB_GETCURSEL, 0, 0L);
|
|
if (wItemNum != (WORD) LB_ERR)
|
|
dwData = (DWORD) SendMessage(hWnd, LB_GETITEMDATA, wItemNum, 0L);
|
|
else {
|
|
wItemNum = 0;
|
|
dwData = (DWORD) SendMessage(hWnd, LB_GETITEMDATA, wItemNum, 0L);
|
|
}
|
|
|
|
if ((wItemNum == (WORD) LB_ERR) || (dwData == LB_ERR) || (dwData == 0))
|
|
break;
|
|
|
|
fCallOrigProc = FALSE;
|
|
|
|
switch (LOWORD(wParam)) {
|
|
|
|
case VK_PRIOR:
|
|
// Need to figure out the number of items to page. This
|
|
// would be the listbox height divided by the height of
|
|
// a listbox item
|
|
lHeight = SendMessage(hWnd, LB_GETITEMHEIGHT, 0, 0L);
|
|
GetWindowRect(hWnd, &rc);
|
|
ListHeight = (rc.bottom - rc.top);
|
|
|
|
if (ListHeight)
|
|
PageCount = ListHeight / lHeight;
|
|
else
|
|
PageCount = 0;
|
|
|
|
// See if we page past the top - if so adjust it.
|
|
if (wItemNum > PageCount)
|
|
wNewNum = wItemNum - PageCount;
|
|
else
|
|
wNewNum = 0;
|
|
|
|
PostMessage(hWnd, LB_SETCURSEL, (WPARAM) wNewNum, 0L);
|
|
|
|
if (hWnd == hwndList1)
|
|
PostMessage(GetParent(hWnd), WM_COMMAND, ID_REDRAWLIST, 0L);
|
|
|
|
break;
|
|
|
|
case VK_NEXT:
|
|
// Need to figure out the number of items to page. This
|
|
// would be the listbox height divided by the height of
|
|
// a listbox item
|
|
lHeight = SendMessage(hWnd, LB_GETITEMHEIGHT, 0, 0L);
|
|
GetWindowRect(hWnd, &rc);
|
|
ListHeight = (rc.bottom - rc.top);
|
|
|
|
if (ListHeight)
|
|
PageCount = ListHeight / lHeight;
|
|
else
|
|
PageCount = 0;
|
|
|
|
// Figure out if we page past the end - if so adjust it
|
|
wItemNum = wItemNum + PageCount;
|
|
wNewNum = (WORD) SendMessage(hWnd, LB_GETCOUNT, (WPARAM) 0, 0L);
|
|
|
|
if (wItemNum < wNewNum)
|
|
PostMessage(hWnd, LB_SETCURSEL, (WPARAM) wItemNum, 0L);
|
|
else
|
|
PostMessage(hWnd, LB_SETCURSEL, (WPARAM) (wNewNum - 1), 0L);
|
|
|
|
if (hWnd == hwndList1)
|
|
PostMessage(GetParent(hWnd), WM_COMMAND, ID_REDRAWLIST, 0L);
|
|
|
|
break;
|
|
|
|
case VK_END:
|
|
wItemNum = (WORD) SendMessage(hWnd, LB_GETCOUNT, (WPARAM) 0, 0L);
|
|
|
|
if (wItemNum != (WORD) LB_ERR)
|
|
PostMessage(hWnd, LB_SETCURSEL, (WPARAM) (wItemNum - 1), 0L);
|
|
|
|
if (hWnd == hwndList1)
|
|
PostMessage(GetParent(hWnd), WM_COMMAND, ID_REDRAWLIST, 0L);
|
|
|
|
break;
|
|
|
|
case VK_HOME:
|
|
PostMessage(hWnd, LB_SETCURSEL, (WPARAM) 0, 0L);
|
|
|
|
if (hWnd == hwndList1)
|
|
PostMessage(GetParent(hWnd), WM_COMMAND, ID_REDRAWLIST, 0L);
|
|
|
|
break;
|
|
|
|
case VK_UP:
|
|
if (wItemNum > 0) {
|
|
wItemNum--;
|
|
PostMessage(hWnd, LB_SETCURSEL, (WPARAM) wItemNum, 0L);
|
|
|
|
if (hWnd == hwndList1)
|
|
PostMessage(GetParent(hWnd), WM_COMMAND, ID_REDRAWLIST, 0L);
|
|
|
|
}
|
|
break;
|
|
|
|
case VK_DOWN:
|
|
wItemNum++;
|
|
PostMessage(hWnd, LB_SETCURSEL, (WPARAM) wItemNum, 0L);
|
|
|
|
if (hWnd == hwndList1)
|
|
PostMessage(GetParent(hWnd), WM_COMMAND, ID_REDRAWLIST, 0L);
|
|
|
|
break;
|
|
|
|
case VK_F1:
|
|
fCallOrigProc = TRUE;
|
|
break;
|
|
|
|
case VK_SPACE:
|
|
// First figure out where checkbox is located in listbox
|
|
wItemNum = (WORD) SendMessage(hWnd, LB_GETCURSEL, 0, 0L);
|
|
dwData = (DWORD) SendMessage(hWnd, LB_GETITEMDATA, wItemNum, 0L);
|
|
|
|
if (wItemNum == (WORD) LB_ERR)
|
|
break;
|
|
|
|
if (hWnd == hwndList2) {
|
|
File = (FILE_BUFFER *) dwData;
|
|
|
|
if (File->Convert == CONVERT_NONE)
|
|
File->Convert = CONVERT_ALL;
|
|
else
|
|
File->Convert = CONVERT_NONE;
|
|
|
|
DirAdjustConvert(File->parent->parent);
|
|
} else {
|
|
Dir = (DIR_BUFFER *) dwData;
|
|
DirList = (DIR_LIST *) Dir->parent;
|
|
|
|
if (DirList != NULL)
|
|
nLevel = DirList->Level;
|
|
|
|
if (Dir->Convert == CONVERT_NONE)
|
|
DirAdjustConvertChildren(Dir, CONVERT_ALL);
|
|
else
|
|
DirAdjustConvertChildren(Dir, CONVERT_NONE);
|
|
|
|
DirAdjustConvert(Dir);
|
|
}
|
|
|
|
// We have set the checkbox state correctly on the current item,
|
|
// and propageted this up and down the tree as necessary, now
|
|
// update the screen to reflect these changes.
|
|
InvalidateRect(hWnd, NULL, TRUE); // Force redraw
|
|
|
|
// if this is the directory listbox then also need to redraw
|
|
// the file listbox
|
|
if (hWnd == hwndList1)
|
|
InvalidateRect(hwndList2, NULL, TRUE);
|
|
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (fCallOrigProc)
|
|
if (hWnd == hwndList2)
|
|
lResult = CallWindowProc(_wpOrigWndProc2, hWnd, message, wParam, lParam);
|
|
else
|
|
lResult = CallWindowProc(_wpOrigWndProc, hWnd, message, wParam, lParam);
|
|
|
|
return (lResult);
|
|
|
|
} // FileSelectSubClassProc
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
LRESULT CALLBACK
|
|
DlgFileSelect(
|
|
HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
int xPos;
|
|
int yPos;
|
|
BOOL InRange;
|
|
RECT rc;
|
|
HWND hCtrl;
|
|
|
|
switch (message) {
|
|
case WM_INITDIALOG:
|
|
// Copy the tree
|
|
oDir = CurrentShare->Root;
|
|
CurrentShare->Root = TreeCopy(oDir);
|
|
|
|
// Center the dialog over the application window
|
|
CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
|
|
GetClientRect(hDlg, &rc);
|
|
ControlsResize(hDlg, (rc.bottom - rc.top), (rc.right - rc.left));
|
|
|
|
// subclass listbox handler
|
|
hCtrl = GetDlgItem(hDlg, IDC_LIST1);
|
|
_wpOrigWndProc = SubclassWindow(hCtrl, FileSelectSubClassProc);
|
|
hCtrl = GetDlgItem(hDlg, IDC_LIST2);
|
|
_wpOrigWndProc2 = SubclassWindow(hCtrl, FileSelectSubClassProc);
|
|
|
|
FillDirInit();
|
|
|
|
hwndList2 = hCtrl = GetDlgItem(hDlg, IDC_LIST2);
|
|
hwndList1 = GetDlgItem(hDlg, IDC_LIST1);
|
|
|
|
// Fill listbox and set selection (is assumed there is always a selection)...
|
|
PostMessage(hDlg, WM_COMMAND, ID_UPDATELIST, 0L);
|
|
return (TRUE);
|
|
|
|
case WM_INITMENU:
|
|
if (GetMenu(hDlg) != (HMENU) wParam)
|
|
break;
|
|
|
|
CheckMenuItem((HMENU) wParam, IDM_HIDDEN, HiddenFiles ? MF_CHECKED : MF_UNCHECKED);
|
|
CheckMenuItem((HMENU) wParam, IDM_SYSTEM, SystemFiles ? MF_CHECKED : MF_UNCHECKED);
|
|
break;
|
|
|
|
case WM_SIZE:
|
|
ControlsResize(hDlg, HIWORD(lParam), LOWORD(lParam));
|
|
break;
|
|
|
|
case WM_SETFONT:
|
|
// Set the text height
|
|
HierFile_DrawSetTextHeight(GetDlgItem(hDlg, IDC_LIST1), (HFONT)wParam, &HierDrawStruct);
|
|
break;
|
|
|
|
case WM_DRAWITEM:
|
|
FileSelect_OnDrawItem(hDlg, (DRAWITEMSTRUCT FAR*)(lParam));
|
|
return TRUE;
|
|
|
|
case WM_MEASUREITEM:
|
|
HierFile_OnMeasureItem(hDlg, (MEASUREITEMSTRUCT FAR*)(lParam), &HierDrawStruct);
|
|
return TRUE;
|
|
|
|
case WM_MOUSEMOVE: {
|
|
xPos = LOWORD(lParam);
|
|
yPos = HIWORD(lParam);
|
|
|
|
InRange = TRUE;
|
|
|
|
// Check if it is correct Y-coordinate
|
|
if ((yPos <= Y_BORDER) || (yPos >= Splitter_Bottom))
|
|
InRange = FALSE;
|
|
|
|
// Now Check X-coordinate
|
|
if ((xPos < Splitter_Left) || (xPos > (Splitter_Left + X_BORDER)))
|
|
InRange = FALSE;
|
|
|
|
// Is within range of splitter, so handle it...
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
FileSelect_OnCommand(hDlg, wParam, lParam);
|
|
break;
|
|
}
|
|
|
|
return (FALSE); // Didn't process the message
|
|
|
|
lParam;
|
|
} // DlgFileSelect
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
FileSelect_Do(
|
|
HWND hDlg,
|
|
SOURCE_SERVER_BUFFER *SourceServ,
|
|
SHARE_BUFFER *CShare
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DLGPROC lpfnDlg;
|
|
|
|
TreeRecurseCurrentShareSet(CShare);
|
|
SServ = SourceServ;
|
|
|
|
HiddenFiles = CurrentShare->HiddenFiles;
|
|
SystemFiles = CurrentShare->SystemFiles;
|
|
|
|
// Init the Hier Draw stuff - Need to do this here so we have a value
|
|
// for WM_MEASUREITEM which is sent before the WM_INITDIALOG message
|
|
HierFile_DrawInit(hInst, IDR_FILEICONS, IDR_CHECKICONS, ROWS, COLS, TRUE, &HierDrawStruct, TRUE );
|
|
|
|
lpfnDlg = MakeProcInstance((DLGPROC)DlgFileSelect, hInst);
|
|
DialogBox(hInst, TEXT("FileSelect"), hDlg, lpfnDlg) ;
|
|
FreeProcInstance(lpfnDlg);
|
|
|
|
HierFile_DrawTerm(&HierDrawStruct);
|
|
|
|
} // FileSelect_Do
|