. 프로젝트 새로 고침

DGFileProc 함수는 더 이상 수정할 것이 없고 새로 고침 기능을 위해 두 개의 유틸리티 함수만 더 수정하도록 하자. 새로 고침 기능은 디스크에 새로운 파일이 작성되었다거나 필터를 변경할 때 파일창을 다시 읽어온다. 이 두 사건 모두 프로젝트의 구성 파일 목록에는 영향을 주지 않는다. 프로젝트의 구성이 변경될 때는 프로젝트 대화상자에서 수정된 프로젝트 노드만 업데이트하며 필터는 로컬디스크에만 적용되기 때문이다.

하지만 한 가지 예외가 있는데 프로젝트에 포함된 폴더 링크는 이 두 사건에 모두 영향을 받기 때문에 새로 고침에 의해 프로젝트 노드에도 변화가 있을 수 있다. 그래서 파일창을 초기화하는 InitTree 함수에서 프로젝트 노드는 좀 다른 방식으로 다시 읽어야 한다. 다음과 같이 이 함수를 수정하도록 하자.

 

void InitTree()

{

     TVINSERTSTRUCT TI;

     TVITEM TV;

     HTREEITEM Node;

     TCHAR c;

     TCHAR Caption[MAX_PATH];

     UINT DriveType;

 

    for (;;) {

        Node=TreeView_GetRoot(hFileTree);

        if (Node==NULL) {

           break;

        }

        TV.mask=TVIF_IMAGE;

        TV.hItem=Node;

        TreeView_GetItem(hFileTree,&TV);

        if (TV.iImage != DGI_DRIVE) {

           break;

        }

        TreeView_DeleteItem(hFileTree,Node);

    }

 

     TI.hParent=0;

    Node=TVI_FIRST;

     TI.item.mask=TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;

     TI.item.iImage=DGI_DRIVE;

     TI.item.iSelectedImage=DGI_DRIVESEL;

     for (c=‘C’;c<=‘Z’;c++) {

          wsprintf(Caption,"%c:\\",c);

          DriveType=GetDriveType(Caption);

          if (DriveType==DRIVE_FIXED || DriveType==DRIVE_REMOTE) {

              wsprintf(Caption,"%c 드라이브",c);

              TI.item.pszText=Caption;

           TI.hInsertAfter=Node;

              Node=TreeView_InsertItem(hFileTree,&TI);

 

              TV.mask=TVIF_CHILDREN;

              TV.hItem=Node;

              TV.cChildren=1;

              TreeView_SetItem(hFileTree,&TV);

          }

     }

 

    for (;;) {

        Node=TreeView_GetNextSibling(hFileTree,Node);

        if (Node==NULL) {

           break;

        }

        TV.mask=TVIF_IMAGE | TVIF_PARAM;

        TV.hItem=Node;

        TreeView_GetItem(hFileTree,&TV);

        if (TV.iImage != DGI_PROJECT) {

           break;

        }

        lstrcpy(Caption,(TCHAR *)TV.lParam);

        LoadProject(Caption,TRUE);

    }

}

 

이 함수는 파일창에 로컬 드라이브와 네트워크 연결 드라이브 노드를 생성한다. 어차피 모든 드라이브를 다시 조사하므로 일단 모든 노드를 삭제하고 노드를 다시 추가했다. 그러나 이미 열린 프로젝트 노드는 삭제하지 말아야 한다. 모든 노드를 다 삭제해버리면 어떤 프로젝트가 열려 있었는지 알 수가 없게 된다. 그래서 이 함수 선두에서는 로컬 드라이브 노드만 모두 삭제하고 프로젝트 노드는 그대로 두었다. 또한 조사되는 드라이브를 무조건 제일 끝 노드에 추가하는 것이 아니라 프로젝트 노드보다는 위에 있도록 해야 한다.

로컬 드라이브 노드를 새로 읽은 후 프로젝트 노드 전체도 다시 업데이트하는데 이때는 모든 프로젝트 노드에 대해 LoadProject를 호출하되 bUpdate 인수를 TRUE로 전달하면 된다. 프로젝트의 폴더 링크가 디스크의 현재 상황과 필터 조건에 따라 다시 읽혀질 것이다. 파일창의 현재 노드를 조사하는 GetCurrentFolder 함수는 다음과 같이 수정한다.

 

void GetCurrentFolder(TCHAR *Path)

{

     TVITEM TV;

     HTREEITEM Node;

    HTREEITEM hRoot,Node2;

 

     Node=TreeView_GetSelection(hFileTree);

     if (Node==NULL) {

          lstrcpy(Path,"");

          return;

     }

 

    for (hRoot=Node;Node2=TreeView_GetParent(hFileTree,hRoot);hRoot=Node2);

    TV.mask=TVIF_IMAGE | TVIF_TEXT;

    TV.hItem=hRoot;

    TV.pszText=Path;

    TV.cchTextMax=MAX_PATH;

    TreeView_GetItem(hFileTree,&TV);

    if (TV.iImage == DGI_PROJECT) {

        return;

    }

 

    TV.mask=TVIF_IMAGE;

     TV.hItem=Node;

     TreeView_GetItem(hFileTree,&TV);

     if (TV.iImage == DGI_FILE) {

          Node=TreeView_GetParent(hFileTree,Node);

     }

 

     GetNodePath(Node,Path);

}

 

GetNodePath 함수를 호출하여 현재 선택된 노드의 절대경로를 조사하는데 프로젝트에 대해서도 이 코드를 그대로 적용하면 프로젝트 노드를 기억하는 것이 아니라 프로젝트의 소속 파일이 가리키는 절대경로를 기억하게 된다. 프로젝트에 소속된 C:\Data\A.txt 노드에서 이 함수를 호출한 후 다시 GotoFolderInTree 함수로 원래 자리를 찾아 가면 프로젝트 노드를 찾아가는 것이 아니라 C 드라이브의 Data 폴더로 가게 될 것이다.

현재 노드가 프로젝트에 소속된 노드라면 경로를 프로젝트 이름으로 조사하도록 하였다. 이 이름으로부터 마지막 경로를 찾아가는 GotoFolderInTree 함수는 다음과 같이 수정된다.

 

void GotoFolderInTree(TCHAR *Path)

{

     ....

     if (lstrlen(Path)==0) {

          return;

     }

 

    if (strchr(Path,’:’)==NULL) {

        Node=TreeView_GetRoot(hFileTree);

        while (Node) {

           TV.mask=TVIF_IMAGE | TVIF_TEXT;

           TV.hItem=Node;

           TV.pszText=Text;

           TV.cchTextMax=MAX_PATH;

           TreeView_GetItem(hFileTree,&TV);

           if (TV.iImage==DGI_PROJECT && lstrcmpi(Text,Path)==0) {

               break;

           }

           Node=TreeView_GetNextSibling(hFileTree,Node);

        }

    } else {

          Node=TreeView_GetRoot(hFileTree);

          p=Path;

          for (;;) {

              ....

          }

    }

 

     if (Node) {

          TreeView_Select(hFileTree,Node,TVGN_CARET);

          TreeView_EnsureVisible(hFileTree,Node);

     }

}

 

마지막 경로가 절대경로가 아니라면 로컬 드라이브가 아니므로 트리 뷰에 있는 프로젝트 중에 이름이 일치하는 노드를 찾아간다. 프로젝트의 어떤 파일을 가리키고 있는가까지 기억할 수 있다면 좋겠지만 그렇게까지는 하지 않았고 최후 포커스가 있는 프로젝트의 루트까지만 찾아가도록 하였다.