//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ // FILE : App.cpp // AUTHOR : Catalin Cocos //__________________________________________________________________________________________________ #include "stdinc.h" #include "app.h" #include "resource.h" #include "list.h" #include "Tree.h" #include "Process.h" CScr2bin CnvEng; // the file converter HWND hWApp; // the application main window HWND hWToolbar; // the toolbar HWND hWStatusbar; // the Statusbar HWND hWList; // the collection file list HWND hWTree; // the tree view HWND hWListView; // the list view HWND hWOut; // the output window HWND hWFilter; // the Filter list view int FILTER_WIDTH; HINSTANCE hInstance; // the current instance int ToolbarHeight; // the height of the toolbar int StatusHeight; // the height of the status bar char CrtCfg[MAX_PATH]; float SplitX = .3f; float SplitY = .2f; int nFocusWnd = 0; int SplitDrag = FALSE, SplitMode; enum { SD_VERTICAL = 0x01, SD_HORIZONTAL = 0x02, SD_FILTER = 0x04}; BOOL Active = TRUE; // operating: int OperatingMode = ID_MODE_NORMAL; BOOL volatile Processing = FALSE; int OperatingState = -1; BOOL ProcessingState = TRUE; BOOL FilterActive = FALSE; void OnIdle() { if(FilterActive != CnvEng.IsFilteringActive()) { FilterActive = !FilterActive; HMENU hMenu = GetSubMenu(GetMenu( hWApp ), 3); CheckMenuItem( hMenu, ID_MODE_FILTER, FilterActive? MF_CHECKED: MF_UNCHECKED); SendMessage( hWToolbar, TB_CHECKBUTTON, ID_MODE_FILTER, FilterActive? TRUE: FALSE); } if(Processing != ProcessingState) { ProcessingState = Processing; UINT state = (Processing? MF_GRAYED: MF_ENABLED); HMENU hMenu = GetSubMenu(GetMenu( hWApp ), 3); EnableMenuItem( hMenu, ID_MODE_NORMAL, state); EnableMenuItem( hMenu, ID_MODE_FORCED, state); EnableMenuItem( hMenu, ID_MODE_CLEAN, state); EnableMenuItem( hMenu, ID_MODE_FILTER, state); hMenu = GetSubMenu(GetMenu( hWApp ), 2); EnableMenuItem( hMenu, ID_ACTION_PROCESS_LISTS, state); EnableMenuItem( hMenu, ID_ACTION_PROCESS_SELECTION, state); EnableMenuItem( hMenu, ID_ACTION_PROCESS_ALL, state); EnableMenuItem( hMenu, ID_ACTION_PROCESS_CANCEL, Processing? MF_ENABLED: MF_GRAYED); state = (Processing? FALSE: TRUE); SendMessage( hWToolbar, TB_ENABLEBUTTON, ID_MODE_NORMAL, state); SendMessage( hWToolbar, TB_ENABLEBUTTON, ID_MODE_FORCED, state); SendMessage( hWToolbar, TB_ENABLEBUTTON, ID_MODE_CLEAN, state); SendMessage( hWToolbar, TB_ENABLEBUTTON, ID_MODE_FILTER, state); SendMessage( hWToolbar, TB_ENABLEBUTTON, ID_ACTION_PROCESS_LISTS, state); SendMessage( hWToolbar, TB_ENABLEBUTTON, ID_ACTION_PROCESS_SELECTION, state); SendMessage( hWToolbar, TB_ENABLEBUTTON, ID_ACTION_PROCESS_ALL, state); SendMessage( hWToolbar, TB_ENABLEBUTTON, ID_ACTION_PROCESS_CANCEL, !state); int listCount = ListView_GetItemCount( hWFilter ); LV_ITEM filterItem = { LVIF_STATE, 0, 0, (Processing && CnvEng.IsFilteringActive())? LSTATE_LOCKED: 0, LSTATE_LOCKED }; for(filterItem.iItem = 0; filterItem.iItemShow( NULL, NULL); return DefWindowProc(hwnd, msg, wp, lp); case WM_LBUTTONDOWN: { SplitDrag = TRUE; RECT r; GetClientRect( hWApp, &r); r.top += ToolbarHeight; r.bottom-=StatusHeight; if(SplitMode & SD_FILTER);// r.right -= 6; else r.left = FILTER_WIDTH + 4; MapWindowPoints( hwnd, NULL, (LPPOINT) &r, 2); SetCapture( hwnd ); ClipCursor( &r ); } break; case WM_LBUTTONUP: SplitDrag = FALSE; ReleaseCapture(); ClipCursor( NULL ); break; case WM_SIZING: { // main window size control RECT* lprc = (LPRECT) lp; if(lprc->right - lprc->left < MIN_CLIENTX ) if(wp == WMSZ_LEFT || wp == WMSZ_BOTTOMLEFT || wp == WMSZ_TOPLEFT) lprc->left -= MIN_CLIENTX + lprc->left - lprc->right; else lprc->right += MIN_CLIENTX + lprc->left - lprc->right; if(lprc->bottom - lprc->top < MIN_CLIENTY ) if(wp == WMSZ_TOP || wp == WMSZ_TOPLEFT || wp == WMSZ_TOPRIGHT) lprc->top -= MIN_CLIENTY + lprc->top - lprc->bottom; else lprc->bottom += MIN_CLIENTY + lprc->top - lprc->bottom; } break; case WM_SIZE: { // toolbar/statusbar repositioning SendMessage(hWStatusbar, WM_SIZE, wp, lp); SendMessage(hWToolbar, WM_SIZE, wp, lp); PositionChildwindows(); } break; case WM_CLOSE: if(!Processing) { SaveConfiguration(); // save the current configuration DestroyWindow( hwnd ); // default processing } else MessageBox( hwnd, "You cannot close the application while processing.\n\rPlease choose the Cancel Processing command before closing the application", "Script Converter", MB_ICONHAND|MB_OK); break; case WM_DESTROY: Active = FALSE; PostQuitMessage(0); break; case WM_NOTIFY: switch(((LPNMHDR)lp)->code) { case TTN_NEEDTEXT: { LPTOOLTIPTEXT lpttt; lpttt = (LPTOOLTIPTEXT) lp; lpttt->hinst = hInstance; switch ( lpttt->hdr.idFrom) { // set the needed tooltip text (for the toolbar) case ID_FILEOPEN: lpttt->lpszText = "Open a previously saved Configuration file (Ctrl+O) "; break; case ID_FILESAVE: lpttt->lpszText = "Save the current Configuration (Ctrl+S)"; break; case ID_FILESAVEAS: lpttt->lpszText = "Save the current Configuration using a new name (Shft+S)"; break; case ID_EDIT_INSERT_LIST: lpttt->lpszText = "Insert Collections"; break; case ID_EDIT_REMOVE_ALL_LISTS: lpttt->lpszText = "Clear Collection List"; break; case ID_EDIT_CLEARSEL: lpttt->lpszText = "Clear Selection"; break; case ID_EDIT_CLEARALL: lpttt->lpszText = "Clear all (both collections and selection)"; break; case ID_ACTION_PROCESS_LISTS: lpttt->lpszText = "Process Collection List (F7)"; break; case ID_ACTION_PROCESS_SELECTION: lpttt->lpszText = "Process current selection (Shft+F7)"; break; case ID_ACTION_PROCESS_ALL: lpttt->lpszText = "Process all (both collection list and selection) (Ctrl+F7)"; break; case ID_ACTION_PROCESS_CANCEL: lpttt->lpszText = "Cancel Processing (Esc)"; break; case ID_MODE_NORMAL: lpttt->lpszText = "Standard mode (process out-of-date files)"; break; case ID_MODE_FORCED: lpttt->lpszText = "Forced mode (forced conversion of all selected files)"; break; case ID_MODE_CLEAN: lpttt->lpszText = "Clean-up mode (delete the corresponding binary files)"; break; case ID_MODE_FILTER: lpttt->lpszText = "Toggle Filtered Processing"; break; default: return DefWindowProc(hwnd, msg, wp, lp); } } break; case TVN_SELCHANGED: if(Active) DisplayView( ((NM_TREEVIEW*)lp)->itemNew.hItem, (CDirInfo*)((NM_TREEVIEW*)lp)->itemNew.lParam ); break; case TVN_GETDISPINFO: { TV_DISPINFO *ptvdi = (TV_DISPINFO *)lp; char fName[_MAX_PATH+10]; strcpy(fName, ((CDirInfo*)ptvdi->item.lParam)->FileName()); strcat(fName, "\\*.*"); WIN32_FIND_DATA fd; ptvdi->item.cChildren = 0; HANDLE hSearch = FindFirstFile( fName, &fd ); for(BOOL Found = (hSearch != INVALID_HANDLE_VALUE); Found; Found = FindNextFile( hSearch, &fd)) if((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (fd.cFileName[0] != '.')) { ptvdi->item.cChildren = 1; break; } if( hSearch != INVALID_HANDLE_VALUE ) FindClose( hSearch ); } break; case TVN_DELETEITEM: delete (CDirInfo*)((NM_TREEVIEW*)lp)->itemOld.lParam; break; case TVN_ITEMEXPANDED: { NM_TREEVIEW* pnmtv = (NM_TREEVIEW *) lp; if(pnmtv->action == TVE_COLLAPSE) { HTREEITEM hItem, hPrevItem = NULL; for( hItem = TreeView_GetChild(hWTree, pnmtv->itemNew.hItem); hItem; ) { TV_ITEM ti = { TVIF_HANDLE|TVIF_STATE|TVIF_PARAM, hItem, 0, ~0 }; TreeView_GetItem( hWTree, &ti); if((ti.state & TVIS_EXPANDED) || (ti.state & TVIS_OVERLAYMASK) || ((ti.state & TVIS_STATEIMAGEMASK) == TI_STATE_FILES) || ((ti.state & TVIS_STATEIMAGEMASK) == TI_STATE_RECURSE) ||((CDirInfo*)ti.lParam)->GetSize()) { hItem = TreeView_GetNextSibling( hWTree, hPrevItem = hItem ); continue; } TreeView_DeleteItem( hWTree, hItem); hItem =(hPrevItem? TreeView_GetNextSibling( hWTree, hPrevItem ): TreeView_GetChild(hWTree, pnmtv->itemNew.hItem)); } } } break; case TVN_ITEMEXPANDING: if(((NM_TREEVIEW*)lp)->action == TVE_EXPAND) SetTreeItemChildren(&((NM_TREEVIEW*)lp)->itemNew); break; default: switch(((NMHDR*)lp)->idFrom) { case IDW_LIST: { NM_LISTVIEW* pList = (NM_LISTVIEW*) lp; if(IsWindowVisible(hWList) && pList->hdr.code == LVN_ITEMCHANGED && pList->uNewState & LVIS_FOCUSED ) PostMessage( hWList, WM_USER+10, pList->iItem, 0); } break; default: return DefWindowProc(hwnd, msg, wp, lp); } } break; case WM_ACTIVATE: if(LOWORD(wp) != WA_INACTIVE ) { //refresh the app; if( bRefresh ) { Active = FALSE; Refresh(); Active = TRUE; } bRefresh = TRUE; RestoreFocus(); } break; default:return DefWindowProc(hwnd, msg, wp, lp); } return 0; } void MakeToolbar( HWND hwnd ) { TBBUTTON but[] ={//{0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0}, // the buttons {29,ID_MODE_FILTER,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, {0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0}, {STD_FILEOPEN,ID_FILEOPEN,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, {STD_FILESAVE,ID_FILESAVE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, {15,ID_FILESAVEAS,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, {0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0}, {20,ID_EDIT_INSERT_LIST,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, {0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0}, {21,ID_EDIT_REMOVE_ALL_LISTS,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, {23,ID_EDIT_CLEARSEL,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, {24,ID_EDIT_CLEARALL,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, {0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0}, {17,ID_ACTION_PROCESS_LISTS,TBSTATE_ENABLED,TBSTYLE_CHECK,0,0}, {18,ID_ACTION_PROCESS_SELECTION,TBSTATE_ENABLED,TBSTYLE_CHECK,0,0}, {19,ID_ACTION_PROCESS_ALL,TBSTATE_ENABLED,TBSTYLE_CHECK,0,0}, {16,ID_ACTION_PROCESS_CANCEL,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, {0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0}, {25,ID_MODE_NORMAL,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, {26,ID_MODE_FORCED,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, {27,ID_MODE_CLEAN,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, }; hWToolbar= CreateToolbarEx(hwnd,WS_VISIBLE|WS_CHILD|TBSTYLE_TOOLTIPS,IDW_TOOLBAR,0, // create the toolbar hInstance,NULL,but,20,18,18,16,15,sizeof(TBBUTTON)); TBADDBITMAP bit={HINST_COMMCTRL,IDB_STD_SMALL_COLOR}; // standard button bitmats SendMessage(hWToolbar,TB_ADDBITMAP,16,(LPARAM)&bit); // add standard bitmaps bit.hInst = hInstance; bit.nID = IDB_TOOLBAR; // our button bitmaps SendMessage(hWToolbar,TB_ADDBITMAP,34,(LPARAM)&bit); // add our bitmaps } void PositionChildwindows() { RECT r; GetClientRect( hWApp, &r); r.right -= FILTER_WIDTH + 3; int xSplit = (int)(r.right*SplitX); int ySplit = (int)((r.bottom - ToolbarHeight - StatusHeight )*SplitY); MoveWindow( hWFilter, 0, ToolbarHeight, FILTER_WIDTH, r.bottom - ToolbarHeight - StatusHeight, TRUE ); MoveWindow( hWList, FILTER_WIDTH +3, ToolbarHeight, xSplit- 1, ySplit - 1, TRUE ); MoveWindow( hWOut, FILTER_WIDTH +3 + xSplit+2, ToolbarHeight, r.right - xSplit - 2, ySplit - 1, TRUE ); MoveWindow( hWTree, FILTER_WIDTH +3, ToolbarHeight + ySplit + 2, xSplit- 1, r.bottom- ToolbarHeight - StatusHeight - ySplit - 2, TRUE ); MoveWindow( hWListView, FILTER_WIDTH +3 + xSplit+2, ToolbarHeight + ySplit + 2, r.right - xSplit- 2, r.bottom- ToolbarHeight - StatusHeight - ySplit - 2, TRUE ); } void SaveTreeItemChildren(HANDLE cfgFile, HTREEITEM hParent, BOOL SaveLastExpanded = TRUE) { BOOL LastExpanded = FALSE; if(SaveLastExpanded) { LastExpanded = TRUE; TV_ITEM tie = {TVIF_STATE|TVIF_HANDLE, 0,0,TVIS_EXPANDED }; for(tie.hItem = TreeView_GetChild( hWTree, hParent); tie.hItem; tie.hItem = TreeView_GetNextSibling(hWTree, tie.hItem)) { TreeView_GetItem( hWTree, &tie ); if( tie.state & TVIS_EXPANDED) { LastExpanded = FALSE; break; } } } TV_ITEM ti = {TVIF_STATE|TVIF_HANDLE|TVIF_PARAM, hParent,0,0 }; TreeView_GetItem( hWTree, &ti ); if(!(ti.state & TVIS_EXPANDED)) SaveLastExpanded = FALSE; if(((CDirInfo*)ti.lParam)->GetSize() || ti.state & (TVIS_SELECTED|LVIS_FOCUSED) || ti.state & TVIS_EXPANDED && LastExpanded || (ti.state & TVIS_STATEIMAGEMASK) == TI_STATE_FILES || (ti.state & TVIS_STATEIMAGEMASK) == TI_STATE_RECURSE ) { // save this item CDirInfo* pDi = (CDirInfo*)ti.lParam; StoreFileName(cfgFile, (char*)pDi->FileName(), CrtCfg); // the relative path to the directory int Files = pDi->GetSize(); StoreItem( cfgFile, Files); // the number of selected files in the directory for(int i = 0; i< Files; i++ ) // the name of the files StoreItem( cfgFile,(char*)(*pDi)[i]->FileName()); if(!LastExpanded) ti.state &= ~TVIS_EXPANDED; StoreItem( cfgFile, ti.state ); } if(SaveLastExpanded || ti.state & TVIS_OVERLAYMASK) // save the children (the ones needed) for(HTREEITEM hChild = TreeView_GetChild( hWTree, hParent); hChild; hChild = TreeView_GetNextSibling(hWTree, hChild)) SaveTreeItemChildren( cfgFile, hChild, SaveLastExpanded); } void SaveConfiguration() { HCURSOR hOldCursor = SetCursor( LoadCursor(NULL, IDC_WAIT)); char* szIni = GetAppPathPlus( INIFILE ); // get configuration file name HANDLE iniFile = CreateFile(szIni,GENERIC_WRITE, 0,NULL,CREATE_ALWAYS,0,NULL); // open the defs file if( iniFile != INVALID_HANDLE_VALUE) { StoreFileName(iniFile, CrtCfg, szIni); CloseHandle(iniFile); } delete[] szIni; // we don't need it anymore HANDLE cfgFile = CreateFile(CrtCfg,GENERIC_WRITE, 0,NULL,CREATE_ALWAYS,0,NULL); // open the defs file if( cfgFile != INVALID_HANDLE_VALUE) { // save the configuration WINDOWPLACEMENT FramePos = { sizeof(WINDOWPLACEMENT) }; GetWindowPlacement( hWApp, &FramePos); StoreItem(cfgFile, FramePos); StoreItem(cfgFile, SplitX); StoreItem(cfgFile, SplitY); StoreItem(cfgFile, nFocusWnd); //save the collection list int listCount = ListView_GetItemCount( hWList ); StoreItem(cfgFile, listCount); LV_ITEM testItem = { LVIF_STATE|LVIF_PARAM, 0, 0, LVIS_SELECTED, ~0 }; for(testItem.iItem = 0; testItem.iItemSetSize(Files); char* szFileName; for(int i = 0; i< Files; i++ ) // the name of the files { LoadItem( cfgFile,szFileName); pDirInfo->SetAt( i, new CFileName(szFileName)); delete[] szFileName; } UINT state; LoadItem( cfgFile, state ); BOOL Drive = FALSE; if( szFolderName[strlen(szFolderName) -1] == ':') { // the directory is, in fact, a drive TV_ITEM it = { TVIF_HANDLE|TVIF_PARAM, 0 }; for( it.hItem = TreeView_GetRoot( hWTree ); it.hItem; it.hItem = TreeView_GetNextSibling(hWTree, it.hItem) ) { TreeView_GetItem( hWTree, &it); if(!strcmpi(szFolderName, ((CDirInfo*)(it.lParam))->FileName())) { Drive = TRUE; break; } } } WIN32_FIND_DATA fd; HANDLE hfind = INVALID_HANDLE_VALUE; if( Drive || (((hfind = FindFirstFile(szFolderName, &fd)) != INVALID_HANDLE_VALUE) && (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))) { // construct the tree item ConstructTreeItem( NULL, state, szFolderName, pDirInfo); } if(hfind != INVALID_HANDLE_VALUE) FindClose( hfind ); delete[] szFolderName; LoadFileName(cfgFile, szFolderName, CrtCfg ); } LoadItem( cfgFile, OperatingMode); char* szExt; LV_ITEM filterItem = { LVIF_STATE|LVIF_TEXT, 0, 0, 0, ~0 }; BOOL bFiltering = FALSE; CnvEng.SetFiltering( FALSE ); if(LoadItem(cfgFile, listCount)) { //load filter list for(int i = 0; iName(); if( ListView_FindItem( hWFilter, -1, &fi ) < 0) { filterItem.state = (pExt->IsEnabled()? LSTATE_CHECKED: LSTATE_UNCHECKED); filterItem.pszText = (char*)fi.psz; ListView_InsertItem( hWFilter, &filterItem); } } SetCursor( hOldCursor ); SetWindowText( hWStatusbar, "Ready"); return Maximized; } void ConstructTreeItem(HTREEITEM hParent, UINT state, char* szFolderName, CDirInfo* pDirInfo) { char* end = strchr(szFolderName, '\\'); if(end) *end = 0; HTREEITEM hMatch = NULL; char FolderName[_MAX_PATH]; TV_ITEM it = { TVIF_HANDLE|TVIF_TEXT|TVIF_PARAM, 0, 0, 0, FolderName, _MAX_PATH }; for( it.hItem = TreeView_GetChild( hWTree, hParent ); it.hItem; it.hItem = TreeView_GetNextSibling(hWTree, it.hItem) ) { TreeView_GetItem( hWTree, &it); if(!strcmpi(szFolderName, FolderName) || (szFolderName[strlen(szFolderName) -1] == ':' && !strcmpi(szFolderName, ((CDirInfo*)(it.lParam))->FileName()))) { //we have a match hMatch = it.hItem; // expand the item if necessary if( !end ) { // this is the target item delete (CDirInfo*) it.lParam; TV_ITEM set = { TVIF_HANDLE|TVIF_STATE|TVIF_PARAM, hMatch, state, ~(TVIS_EXPANDED|TVIS_EXPANDEDONCE|TVIS_EXPANDPARTIAL|TVIS_SELECTED|LVIS_FOCUSED)}; set.lParam = (LPARAM) pDirInfo; TreeView_SetItem(hWTree, &set); if(state & TVIS_SELECTED) TreeView_SelectItem(hWTree, hSelected = hMatch); } if(state & TVIS_EXPANDED) { TV_ITEM get = { TVIF_HANDLE|TVIF_STATE|TVIF_PARAM, hMatch, 0, ~0 }; TreeView_GetItem(hWTree, &get); int Exp = TreeView_Expand (hWTree, hMatch, TVE_EXPAND ); TreeView_GetItem(hWTree, &get); SetTreeItemChildren( &get ); } break; } } if(!hMatch) { TV_ITEM get = { TVIF_HANDLE|TVIF_STATE, hParent, 0, ~0 }; if(hParent && (hParent)) TreeView_GetItem(hWTree, &get); TV_INSERTSTRUCT tis = { hParent, TVI_SORT , { TVIF_CHILDREN|TVIF_SELECTEDIMAGE|TVIF_PARAM|TVIF_IMAGE|TVIF_STATE|TVIF_TEXT, NULL,((get.state & TVIS_STATEIMAGEMASK)>TI_STATE_FILES)? TI_STATE_LOCKED:TI_STATE_NONE, TVIS_STATEIMAGEMASK, szFolderName, 0, 0, 1, I_CHILDRENCALLBACK, 0 } }; // set the item's info if( end ) { // we didn't yet reached the item - we are inserting its predecessors int length = strlen(pDirInfo->FileName()) - lstrlen( end + 1 ) -1; char* name = (char*) memcpy( new char[length +1], pDirInfo->FileName(), length ); name[length] = 0; tis.item.lParam = (LPARAM) (new CDirInfo(name)); delete[] name; } else { // this is the item tis.item.state = state; tis.item.stateMask = ~0; tis.item.lParam = (LPARAM) pDirInfo; } hMatch = TreeView_InsertItem(hWTree, &tis); if( !end && state & TVIS_SELECTED) TreeView_SelectItem(hWTree, hSelected = hMatch); } if( end ) ConstructTreeItem( hMatch, state, end+1, pDirInfo); else { NotifyChildren(hMatch); NotifyParents(hMatch); } } void UpdateAppName() { char fname[2*_MAX_FNAME + 40] = APPNAME" ["; char drive[_MAX_PATH], dir[_MAX_PATH]; _splitpath( CrtCfg, drive, dir, fname+ strlen(APPNAME) +5, NULL); strcat( fname, "]"); SetWindowText(hWApp, fname); strcat(drive, dir); SetCurrentDirectory( drive ); } void RestoreFocus() { switch(nFocusWnd) { case FOCUS_OUT: SetFocus(hWOut); break; case FOCUS_TREE: SetFocus(hWTree); break; case FOCUS_LISTVIEW: SetFocus(hWListView); break; case FOCUS_FILTER: SetFocus(hWFilter); break; //case FOCUS_LIST: default: SetFocus(hWList); break; } } HTREEITEM RefreshTreeItemChildren(HTREEITEM hChild) { TV_ITEM it = { TVIF_HANDLE|TVIF_STATE|TVIF_PARAM, hChild }; TreeView_GetItem( hWTree, &it); const char* name = ((CDirInfo*)(it.lParam))->FileName(); //test the folder existence if( name[strlen(name)-1] != ':') { WIN32_FIND_DATA fd; HANDLE hfind = FindFirstFile(name, &fd); if((hfind == INVALID_HANDLE_VALUE) || !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { HTREEITEM hParent = TreeView_GetParent( hWTree, hChild); TreeView_DeleteItem( hWTree, hChild); if(hParent) NotifyParents(hParent); hChild = NULL; } if(hfind != INVALID_HANDLE_VALUE) FindClose( hfind ); } HTREEITEM hTgt, hPrev = NULL; if(hChild) { // the folder exists, we are verifying the existence of selected files CDirInfo* pDi = (CDirInfo*)it.lParam; char fName[_MAX_PATH+10]; BOOL ViewChanged = FALSE; WIN32_FIND_DATA fd; for(int i = pDi->GetUpperBound(); i>=0; i--) { strcpy(fName, name); strcat(fName,"\\"); strcat(fName, (*pDi)[i]->FileName()); HANDLE hSearch = FindFirstFile( fName, &fd ); if(hSearch == INVALID_HANDLE_VALUE || fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { pDi->DeleteAt(i); ViewChanged = TRUE; } if(hSearch != INVALID_HANDLE_VALUE) FindClose(hSearch); } if(ViewChanged) NotifyParents(hChild); if(ViewChanged && (it.state & TVIS_SELECTED )) DisplayView( hChild, (CDirInfo*)it.lParam); if(it.state & TVIS_SELECTED) { // add the eventually inserted files strcpy(fName, name); strcat(fName, "\\*.*"); UINT state = ((it.state & TVIS_STATEIMAGEMASK) > TI_STATE_NONE? LSTATE_LOCKED: LSTATE_UNCHECKED); HANDLE hSearch = FindFirstFile( fName, &fd ); for(BOOL Found = (hSearch != INVALID_HANDLE_VALUE); Found; Found = FindNextFile( hSearch, &fd)) if(!(fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_SYSTEM )) && CnvEng.IsFileKnown( fd.cFileName)) { LV_FINDINFO fi = {LVFI_STRING, fd.cFileName }; if( ListView_FindItem( hWListView, -1, &fi) < 0 ) { LV_ITEM a = {LVIF_TEXT|LVIF_STATE|LVIF_PARAM,ListView_GetItemCount(hWListView),0, state,0, fd.cFileName, 0,0, (LPARAM) hChild }; ListView_InsertItem( hWListView, &a); } } if(hSearch != INVALID_HANDLE_VALUE) FindClose(hSearch); } // test the childs existence for(hTgt = TreeView_GetChild(hWTree, hChild); hTgt; ) if(RefreshTreeItemChildren(hTgt)) { hPrev = hTgt; hTgt = TreeView_GetNextSibling(hWTree, hTgt); } else hTgt = (hPrev?TreeView_GetNextSibling(hWTree, hPrev):TreeView_GetChild(hWTree, hChild)); if(it.state & (TVIS_EXPANDED|TVIS_EXPANDEDONCE)) SetTreeItemChildren( &it ); } return hChild; } void Refresh() { // refresh the list { HANDLE hFile; int maxCnt = ListView_GetItemCount( hWList ); for( int i = maxCnt-1 ; i>=0; i-- ) { LV_ITEM it = {LVIF_PARAM, i, 0}; ListView_GetItem( hWList, &it); hFile = CreateFile( (char*)it.lParam,0,0,NULL,OPEN_EXISTING,0,NULL); // open the file if(hFile == INVALID_HANDLE_VALUE) { delete[] (char*)it.lParam; ListView_DeleteItem( hWList, i); } else CloseHandle(hFile); } if(IsWindowVisible(hWList)) PostMessage( hWList, WM_USER+10, ListView_GetNextItem( hWList, -1, LVNI_FOCUSED ), 0); } // refresh the tree for(HTREEITEM hChild = TreeView_GetRoot(hWTree); hChild; hChild = TreeView_GetNextSibling(hWTree, hChild)) RefreshTreeItemChildren(hChild); } void CleanTreeItemChildren(HTREEITEM hChild) { TV_ITEM ti = { TVIF_HANDLE|TVIF_STATE|TVIF_PARAM, hChild, 0, ~0 }; TreeView_GetItem( hWTree, &ti); ti.state &= ~(TVIS_STATEIMAGEMASK|TVIS_OVERLAYMASK); ti.state |= TI_STATE_NONE; ((CDirInfo*)ti.lParam)->DeleteAll(); TreeView_SetItem( hWTree, &ti); if(ti.state & TVIS_SELECTED) DisplayView( hChild, (CDirInfo*)ti.lParam); HTREEITEM hNext; if(!(ti.state&TVIS_EXPANDED)) while( hNext = TreeView_GetChild( hWTree, hChild)) TreeView_DeleteItem( hWTree, hNext); else for( hNext = TreeView_GetChild( hWTree, hChild); hNext; hNext = TreeView_GetNextSibling( hWTree, hNext)) CleanTreeItemChildren(hNext); } void CleanSelection() { for(HTREEITEM hChild = TreeView_GetRoot(hWTree); hChild; hChild = TreeView_GetNextSibling(hWTree, hChild)) CleanTreeItemChildren(hChild); }