From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/nw/convert/nwconv/filesel.c | 2349 +++++++++++++++++++++++++++++++++++ 1 file changed, 2349 insertions(+) create mode 100644 private/nw/convert/nwconv/filesel.c (limited to 'private/nw/convert/nwconv/filesel.c') diff --git a/private/nw/convert/nwconv/filesel.c b/private/nw/convert/nwconv/filesel.c new file mode 100644 index 000000000..8d8b8161a --- /dev/null +++ b/private/nw/convert/nwconv/filesel.c @@ -0,0 +1,2349 @@ +/*++ + +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 // 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 -- cgit v1.2.3