. 찾아가기

파일에서 문자열을 검색하는 목적은 특정 문자열의 존재 여부를 확인하고자 하는 목적보다 그 문자열이 있는 파일을 열어서 편집하고자 하는 목적이 더 크다. 따라서 검색결과창은 검색 문자열을 가진 파일을 즉시 열어 줄 수 있는 서비스를 해야 하며 문자열이 있는 위치로 이동하면 더욱 좋다. 검색결과창에 이 기능을 작성해보자.

검색 결과는 리스트 뷰 컨트롤에 보고서 형태로 출력되어 있으므로 리스트 뷰 컨트롤의 더블클릭 통지 메시지에서 이를 처리하면 된다. DGOutputProc에 다음 통지 메시지를 처리하는 코드를 작성하도록 하자.

 

LRESULT CALLBACK DGOutputProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

{

     switch(iMessage) {

          ....

    case WM_NOTIFY:

        LPNMHDR hdr;

        LPNMLISTVIEW nlv;

        hdr=(LPNMHDR)lParam;

        nlv=(LPNMLISTVIEW)lParam;

        LPNMITEMACTIVATE nia;

 

        if (hdr->hwndFrom == hList) {

           switch (hdr->code) {

           case NM_DBLCLK:

               nia = (LPNMITEMACTIVATE)lParam;

               if (nia->iItem != -1) {

                   OpenFileFromOutput(nia->iItem);

               }

               return TRUE;

           }

        }

        break;

     }

     return(DefWindowProc(hWnd,iMessage,wParam,lParam));

}

 

더블클릭된 항목의 인덱스를 구하면 이 항목으로부터 검색된 파일과 검색 위치를 구할 수 있다. 검색결과로부터 인덱스를 전달받아 파일을 열어주는 함수를 작성한다.

 

void OpenFileFromOutput(int idx)

{

     TCHAR Text[MAX_PATH];

     TCHAR Path[MAX_PATH];

     int line,col;

     int toff;

     TCHAR *p;

     HWND hActive;

     SInfo *pSi;

 

     ListView_GetItemText(hList,idx,1,Text,MAX_PATH);

     if (FindFlag & AE_FIND_SHORTPATH) {

          wsprintf(Path,"%s\\%s",arFind[2].Get(0),Text);

     } else {

          lstrcpy(Path,Text);

     }

 

     p=strrchr(Path,’,’);

     col=atoi(p+1)-1;

     p=strrchr(Path,’(‘);

     line=atoi(p+1)-1;

     *p=0;

 

     if (OpenFromFile(Path)==FALSE) {

          return;

     }

     hActive=(HWND)SendMessage(g_hMDIClient,WM_MDIGETACTIVE,0,NULL);

     pSi=(SInfo *)GetWindowLong(hActive,0);

     pSi->Ae.GotoLine(line,col,1);

     toff=pSi->Ae.GetOffset();

     pSi->Ae.SetSelect(toff,toff+lstrlen(LastFIF),TRUE);

}

 

리스트 뷰의 두 번째 컬럼(1번째 컬럼)에는 검색된 파일의 경로와 위치가 문자열 형태로 저장되어 있는데 이 문자열을 해석하면 열어야 할 파일과 이동해야 할 위치를 정확하게 구할 수 있다. 파일의 경로를 구한 후 OpenFromFile 함수를 호출하여 파일을 열었다. OpenFromFile은 이미 열린 파일인 경우 포커스만 이동시켜 주며 MRU에도 등록한다.

파일을 연 후 line 줄의 col 칸으로 이동하고 검색 문자열을 선택하여 어떤 문자열이 검색되었는지 정확하게 보여준다. 이제 파일에 문자열을 검색한 후 검색결과를 더블클릭하면 즉시 파일을 열어 주고 검색 문자열이 있는 위치로 이동할 것이다. 이 기능은 비교적 잘 동작하지만 한 가지 버그가 있다.

만약 파일검색을 한 후 다른 편집기로 이 파일을 편집해버리면 검색결과로부터 검색된 위치를 제대로 찾아갈 수가 없다. 예를 들어 (10,20)의 위치에서 문자열을 찾았는데 이 파일이 편집되어 문자열의 위치가 (12,25)로 이동되어 버렸다면 검색결과창이 가지고 있는 (10,20) 이라는 위치는 무효가 된다. 뿐만 아니라 편집된 후 20컬럼이 한글의 경계에 걸치게 되면 프로그램이 죽을 수도 있다. 이 문제를 해결하려면 몇 개의 함수군이 더 필요하므로 일시적인 노운 버그로 남겨 놓도록 한다.