CFileDialog 의 갈고리 함수 로 대화 상자 의 다 중 선택 DoModal 문 제 를 해결 합 니 다.

며칠 전 리더 가 저 에 게 한 가지 질문 을 했 습 니 다.바로 CFileDialog 류 를 사용 하여 다 중 선택 할 때 선택 한 파일 버퍼 를 설정 하 는 것 이 얼마나 적당 한 지 모 르 겠 습 니 다.DoModal 을 작 게 설정 하면 실패 로 돌아 갑 니 다.CommDlgExtended Error 함 수 를 통 해 오류 코드 를 FNERR 로 가 져 옵 니 다.BUFFERTOOSMALL(즉 버퍼 가 너무 작 음)설정 이 크 고 메모리 가 낭비 되 었 습 니 다.(우 리 는 한 번 에 몇 백 개의 파일 을 선택해 야 하 는데,정말 얼마나 설정 이 적당 한 지 모르겠다.      나 는 나의 생각 에 대해 이야기 했다:CFileDialog 의 데이터 멤버 mofn 의 한 데이터 구성원 은 갈고리 함수 포인터 입 니 다.이 함 수 를 설정 하면 CFileDialog 와 관련 된 정 보 를 찾 을 수 있 습 니 다.예 를 들 어 사용자 가 경 로 를 바 꾸 었 다 는 정 보 를 얻 은 다음 에 현재 경로 의 파일 개 수 를 얻 고 이 를 근거 로 버퍼 의 크기 를 설정 할 수 있 습 니 다.지도 자 는 나의 생각 을 잘 알 지 못 한다.그 는 인터넷 에서 검색 하고 방법 을 찾 았 다.바로 CFileDialog 류 를 파생 시 키 는 방법 으로 하 는 것 이다.구체 적 으로 다음 과 같다.
     Multiple Selection in a File Dialog
    위의 링크 에서 언급 한 방법 은 확실히 실행 할 수 있다.하지만 나 도 내 방법 이 가능 하 다 고 믿는다.퇴근 후에 인터넷 으로 검색 해 보 니 마이크로소프트 홈 페이지 에 이 문제 에 대한 해결 방법 이 있 습 니 다.링크 는 다음 과 같 습 니 다.
Windows 에서 FNER 를 어떻게 처리 합 니까?BUFFERTOOSMALL  
     이 링크 가 제공 하 는 코드 는 Win 32 프로그램 에 적합 하고 MFC 프로그램 에 적합 하지 않 습 니 다.그리고 제 가 Win 32 프로그램 을 만들어 서 이 예 를 테스트 하 는 코드 를 만 들 었 을 때 문 제 를 발 견 했 습 니 다.선택 한 파일 이 너무 많 을 때 할당 해 야 할 버퍼 가 많 을 때 링크 의 HeapAlloc 함 수 를 사용 하면 오류 가 발생 할 수 있 습 니 다.오 류 는 다음 과 같 습 니 다.
 
     따라서 링크 에 메모리 와 방출 된 메모 리 를 할당 하 는 HeapAlloc 와 HeapFree 함 수 를 각각 C++의 new 와 delete 연산 자로 교체 해 야 합 니 다.
      마이크로소프트 홈 페이지 에서 제공 하 는 방법 을 바탕 으로 나 는 MFC 프로그램 에 사용 하 는 방법 을 모색 했다.구체 적 인 코드 는 다음 과 같다
 
//
UINT_PTR CALLBACK MyOFNHookProc( HWND hdlg, // handle to child dialog box
UINT uiMsg, // message identifier
WPARAM wParam, // message parameter
LPARAM lParam // message parameter
)
{
int nResult = FALSE;
if (hdlg == NULL)
return 0;
#ifdef _DEBUG
// from "_AfxCommDlgProc()" of the file "dlgcomm.cpp"
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
if (pThreadState->m_pAlternateWndInit != NULL)
pThreadState->m_pAlternateWndInit = NULL;
#endif
switch(uiMsg)
{
case WM_NOTIFY:
{
LPOFNOTIFY pOfn = (LPOFNOTIFY)lParam;
switch(pOfn->hdr.code)
{
case CDN_SELCHANGE:
{
TCHAR dummy_buffer;
// Get the required size for the 'files' buffer
HWND hOwner = GetParent(hdlg);
HWND hParent = GetParent(hOwner);
UINT nfiles = CommDlg_OpenSave_GetSpec(hOwner, &dummy_buffer, 1);
// Get the required size for the 'folder' buffer
int cbLength = CommDlg_OpenSave_GetSpec(GetParent(hdlg), NULL, 0);
cbLength += _MAX_PATH;
if(cbLength>(pOfn->lpOFN)->nMaxFile)
{
delete (pOfn->lpOFN)->lpstrFile;
(pOfn->lpOFN)->lpstrFile = new TCHAR[cbLength];
ZeroMemory((pOfn->lpOFN)->lpstrFile,cbLength);
(pOfn->lpOFN)->nMaxFile = cbLength;
}
nResult = TRUE;
break;
}
default:
break;
}
break;
}
default:
break;
}
return nResult;
}
#define NAMEBUF 1024
//
void CMultiSelectDlg::OnButton1()
{
m_listbox.ResetContent();
m_static.SetWindowText(_T("0 files selected"));
TCHAR szFilters[]= _T("MyType Files (*.doc)|*.doc||");
// Create an Open dialog; the default file name extension is ".doc".
CFileDialog fileDlg(TRUE, _T("doc"), _T("*.doc"),
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT, szFilters);
fileDlg.m_ofn.lpstrFile=new TCHAR[NAMEBUF]; // lpstrFile
memset(fileDlg.m_ofn.lpstrFile,0,NAMEBUF); //
fileDlg.m_ofn.nMaxFile = NAMEBUF; // nMaxFile
fileDlg.m_ofn.lpfnHook = (LPOFNHOOKPROC)MyOFNHookProc;
INT_PTR ret = fileDlg.DoModal();
if (ret == IDOK)
{
int width = 0;
CString str;
CDC *pDC = m_listbox.GetDC();
int saved = pDC->SaveDC();
pDC->SelectObject(GetFont());
UINT count = 0;
POSITION pos = fileDlg.GetStartPosition();
while (pos)
{
str = fileDlg.GetNextPathName(pos);
m_listbox.AddString(str);
CSize size(0, 0);
size = pDC->GetTextExtent(str);
width = width > size.cx ? width : size.cx;
++count;
}
pDC->RestoreDC(saved);
ReleaseDC(pDC);
m_listbox.SetHorizontalExtent(width + 5);
str.Format(_T("%u files selected"), count);
m_static.SetWindowText(str);
}
DWORD dwCode = CommDlgExtendedError();
if (FNERR_BUFFERTOOSMALL==dwCode)
{
AfxMessageBox(_T(" !"));
}
delete []fileDlg.m_ofn.lpstrFile;
fileDlg.m_ofn.lpstrFile = NULL;
}
    또한 갈고리 함 수 를 사용 하 는 심각 한 단점 은 프로그램 이 유 니 코드 문자 집합 을 사용 하여 컴 파일 해 야 한 다 는 것 이다.다 중 바이트 문자 집합 컴 파일 러 를 사용 하여 실행 한 후 FNERBUFFERTOOSMALL 의 오류.제 테스트 환경 은 VS C+2005+sp1,Win XP+sp3,유 니 코드 문자 집합 입 니 다.

좋은 웹페이지 즐겨찾기