반응형
1.요약
Dialog Based 로 만든 프로그램의 메뉴에 '최근 사용한 파일 목록'을 만들어 봅시다.
2.본문
SDI/MDI 의 경우 Doc/View 구조에 의해서 MFC 가 '최근 사용한 파일'에 대한 리스트를 메뉴에 보여주는 기능을 제공하고 있습니다. 하지만, 이러한 방법은 SDI/MDI 의 경우에만 제공되고 있기 때문에 Dialog Based 프로그램에서는 정상적으로 작동하지 않습니다. 따라서 CMRUList 라는 클래스를 만들어서 그 기능을 구현해 보았습니다.
CMRUList 는 아래와 같은 함수들을 제공합니다.
// nFileNum 번째 위치한 메뉴의 Path 를 얻습니다.
CString GetFilePath(int nFileNum, BOOL *pbEnable = NULL); CString GetMenuPath(int nFileNum, BOOL *pbEnable = NULL);: 첫번째 함수는 실제 파일의 경로를 얻기 위한 함수이며, 두번째 함수는 메뉴에 Path 를 뿌려주기 위해서 인덱스를 포함한 경로를 얻기 위한 함수입니다.
// 특정 Path 를 메뉴에 넣습니다.
void AddFilePath(CString strFilePath);: 파일을 Open 하는 메소드에서 새로운 경로를 추가하기 위해서 사용합니다. 중복 처리나 순서에 대한 처리는 클래스 내부에서 수행합니다.
// MRU 리스트를 저장합니다.
void Save();: 현재 지정되어 있는 경로들을 저장합니다. (프로그램이 종료할때 사용하시면 됩니다.)
// 특정 위치의 Path 를 리스트에서 제거합니다.
void DeletePath(int nNum);: 이 함수는 실제로 파일을 Open 했을때 파일을 정상적으로 열지 못할경우 리스트에서 제거하기 위해서 사용합니다.
// 전체 Path의 갯수를 얻습니다.
int GetTotalPath();: 현재 등록되어 있는 Path 의 갯수를 얻습니다.
3.예제
// [ 최근 사용한 파일 목록 ] // |----> [ IDM_MRU_FILE1 ] // |----> [ IDM_MRU_FILE2 ] // |----> [ IDM_MRU_FILE3 ] // |----> [ IDM_MRU_FILE4 ] // 2. Dialog 의 header 파일에 아래의 함수를 추가합니다. afx_msg void OnUpdateRecentFile(CCmdUI* pCmdUI); afx_msg void OnRecentFile(int nID); // 3. CMRUList 의 객체를 선언합니다. public: CMRUList m_ctrMRUList; int m_nTotalMruMenu; // 전체 메뉴 갯수 // 4. Dialog 의 cpp 파일의 메세지 핸들러를 추가합니다. ON_COMMAND_RANGE(IDM_MRU_FILE1, IDM_MRU_FILE4, OnRecentFile) ON_UPDATE_COMMAND_UI_RANGE(IDM_MRU_FILE1, IDM_MRU_FILE4 , OnUpdateRecentFile) // 5. 생성자에서 현재 초기화된 메뉴의 갯수를 저장합니다. m_nTotalMruMenu = m_ctrMRUList.GetTotalPath(); // 6. 메뉴를 업데이트 하기 위한 핸들러를 구현합니다. void CTestDlg::OnUpdateRecentFile(CCmdUI* pCmdUI) { BOOL bEnable; // 새로 생긴 메뉴가 있다면 생성합니다. if (m_nTotalMruMenu != m_ctrMRUList.GetTotalPath()) { switch(m_nTotalMruMenu) { case 0: pCmdUI->m_pMenu->InsertMenu(IDM_MRU_FILE1, MF_BYCOMMAND|MF_STRING, IDM_MRU_FILE1); case 1: pCmdUI->m_pMenu->InsertMenu(IDM_MRU_FILE2, MF_BYCOMMAND|MF_STRING, IDM_MRU_FILE2); case 2: pCmdUI->m_pMenu->InsertMenu(IDM_MRU_FILE3, MF_BYCOMMAND|MF_STRING, IDM_MRU_FILE3); case 3: pCmdUI->m_pMenu->InsertMenu(IDM_MRU_FILE4, MF_BYCOMMAND|MF_STRING, IDM_MRU_FILE4); } m_nTotalMruMenu = m_ctrMRUList.GetTotalPath(); return; } // 메뉴의 Text를 업데이트 합니다. switch(pCmdUI->m_nID) { case IDM_MRU_FILE1: pCmdUI->SetText(m_ctrMRUList.GetMenuPath(0, &bEnable)); break; case IDM_MRU_FILE2: pCmdUI->SetText(m_ctrMRUList.GetMenuPath(1, &bEnable)); break; case IDM_MRU_FILE3: pCmdUI->SetText(m_ctrMRUList.GetMenuPath(2, &bEnable)); break; case IDM_MRU_FILE4: pCmdUI->SetText(m_ctrMRUList.GetMenuPath(3, &bEnable)); break; } // 현재 Path 가 지정되어 있지 않은 메뉴라면, 삭제합니다. if (bEnable == FALSE) pCmdUI->m_pMenu->RemoveMenu(pCmdUI->m_nID, MF_BYCOMMAND); else pCmdUI->Enable(TRUE); } // 7. 메뉴를 눌렀을때 발생하는 이벤트에 대해서 처리합니다. void CTestDlg::OnRecentFile(int nID) { CString strPath; int nIDNum; switch(nID) { case IDM_MRU_FILE1: nIDNum = 0; break; case IDM_MRU_FILE2: nIDNum = 1; break; case IDM_MRU_FILE3: nIDNum = 2; break; case IDM_MRU_FILE4: nIDNum = 3; break; } // strPath 에는 선택된 파일에 대한 경로가 들어있습니다. strPath = m_ctrMRUList.GetFilePath(nIDNum); }
4.참고
5.주의
처음에는 메뉴에 대한 Path가 없기 때문에, 모든 메뉴가 자동으로 삭제되도록 되어 있습니다. 따라서 처음으로 파일을 열어서 path를 추가하고자 하실때 ( AddFilePath() 호출할때..), 임의로 InsertMenu() 함수를 통해서 아래와 같은 방법으로 추가해 주셔야 합니다.
예)
C:\test.cpp if (m_ctrMRUList.GetTotalPath() == 1) { GetMenu()->GetSubMenu(0)->GetSubMenu(6)->InsertMenu( IDM_MRU_FILE1, MF_BYCOMMAND|MF_STRING, IDM_MRU_FILE1); m_nTotalMruMenu = 1; }
반응형
'C & C++ > MFC 컨트롤' 카테고리의 다른 글
[Tip] 트레이 아이콘 사라지는 버그 (0) | 2011.03.27 |
---|---|
[Tip] 윈도우에 Focus 가지 않게 하기 (0) | 2011.03.27 |
[Tip] 연결 프로그램 찾기 다이얼로그 띄우기 (0) | 2011.03.27 |
[Dialog] 단일문서(SDI),다중문서(MDI),대화 상자 기반(Dialog)의 초기 처리 (0) | 2011.03.27 |
[Dialog] 스플리터 윈도우 크기조절 (0) | 2011.03.27 |
댓글