📄 dirdialog.cpp
字号:
len == 3 && ss[1] == ':' && ss[2] == '\\' ) { // Definitely not a createable directory pp->CheckDir(ss); } else { // Check if it's an existing directory CFileStatus fs; DWORD attr = GetFileAttributes(ss); if (attr == 0xFFFFFFFF) { // Directory not found but maybe it's an invalid drive _TCHAR rootdir[4] = _T("?:\\"); rootdir[0] = ss[0]; if (len == 1 || (len > 1 && ss[1] != ':') || GetDriveType(rootdir) > DRIVE_NO_ROOT_DIR) { // Appears to be a valid drive (or relative path) CString mess(ss); mess += _T("\nThis folder does not exist.\n\nDo you want to create it?"); if (AfxMessageBox(mess, MB_YESNO) == IDYES) { PSTR pstrPath = ToMultiByte(ss + _T("\\")); if (!::MakeSureDirectoryPathExists(pstrPath)) { switch (GetDriveType(rootdir)) { case DRIVE_CDROM: AfxMessageBox(_T("You cannot create this folder\nas the CD ROM medium is read-only.")); break; case DRIVE_REMOVABLE: AfxMessageBox(_T("You cannot create this folder.\nThe medium may be write-protected.")); break; case DRIVE_REMOTE: AfxMessageBox(_T("You do not have permission to create\nthis folder on the network.")); break; default: AfxMessageBox(_T("You do not have permission or\notherwise cannot create this folder.")); break; } return; } delete[] pstrPath; } else return; } } pp->CheckDir(ss); // Make sure the directory name ends with backslash so user can type sub-drectory name GetWindowText(ss); if (ss[ss.GetLength()-1] != '\\') { ss += "\\"; SetWindowText(ss); } SetSel(ss.GetLength(), -1); } SetFocus(); // Make sure caret stays in this edit control } else { CEdit::OnChar(nChar, nRepCnt, nFlags); // Get the text and check whether it is a valid directory CString ss; // Current text in the edit control GetWindowText(ss); int len = ss.GetLength(); int start, end; // Current selection GetSel(start, end); if (ss.Compare(_T("\\\\")) == 0) { // Don't check \\ else we get a message about "\\" being an invalid filename ; } else if (ss.Compare(_T("\\")) == 0) { // Show root directory pp->CheckDir(ss); } else if (len == 3 && ss[1] == ':' && ss[2] == '\\') { // Check that it's a valid drive if (GetDriveType(ss) > DRIVE_NO_ROOT_DIR) { pp->CheckDir(ss); } } else if (len > 0 && ss[len-1] == '\\') { // Check that it's a valid directory // xxx does not handle "\\anwar\" DWORD attr = GetFileAttributes(ss); if (attr != 0xFFFFFFFF && (attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { pp->CheckDir(ss); } } else if (start == len && nChar != '\b') { // Try to do completion of the directory name CFileFind ff; // Used to find directory names that start with ss int count = 0; // Number of matching directory names CString strMatch; // The last directory found that matches BOOL bContinue = ff.FindFile(ss + "*"); while (bContinue) { // At least one match - check them all bContinue = ff.FindNextFile(); if (ff.IsDirectory()) { // Found a matching directory ++count; strMatch = ff.GetFileName(); } } // If there was exactly one matching directory use it if (count == 1) { int ii; // The file open dialog changes all uppercase names to lower case with an initial // capital (eg WINDOWS displays as Windows). We do the same so things look nicer. for (ii = 0; ii < strMatch.GetLength(); ++ii) { // Don't change if it contains spaces or lowercase letters if (isspace(strMatch[ii]) || islower(strMatch[ii])) break; } ASSERT(ii <= strMatch.GetLength()); if (!strMatch.IsEmpty() && ii == strMatch.GetLength()) { CString temp = strMatch.Mid(1); temp.MakeLower(); strMatch = strMatch.Left(1) + temp; } // Get the bit of the directory name that the user has not yet typed int lb_len; // Length of last bit (after \ or :) lb_len = ss.ReverseFind('\\'); if (lb_len == -1) lb_len = ss.ReverseFind('/'); if (lb_len == -1) lb_len = ss.ReverseFind(':'); if (lb_len == -1) lb_len = ss.GetLength(); else lb_len = ss.GetLength() - (lb_len+1); // Check if the last char is the same case as the same char in the matched name if (!ss.IsEmpty() && lb_len > 0 && strMatch[lb_len-1] != ss[ss.GetLength()-1]) { // The user used different case to that of the corresponding character in // the matched directory so change the matched name to be the user's case. if (isupper(ss[ss.GetLength()-1])) strMatch.MakeUpper(); else strMatch.MakeLower(); }#ifdef _DEBUG CString temp = strMatch.Left(lb_len); ASSERT(temp.CompareNoCase(ss.Right(lb_len)) == 0);#endif end += strMatch.GetLength() - lb_len; SetWindowText(ss + strMatch.Mid(lb_len)); SetSel(start, end); } // else if (count > 1) pop-up some sort of selection list??? } SetFocus(); // Make sure caret stays in this edit control }}void RxDirEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { CEdit::OnKeyDown(nChar, nRepCnt, nFlags); if (nChar != VK_DELETE) return; RxDlgWnd *pp; // Parent = the dialog itself VERIFY(pp = (RxDlgWnd *)GetParent()); // Get the current text and check whether it is a valid directory CString ss; GetWindowText(ss); int len = ss.GetLength(); if (ss.Compare(_T("\\\\")) == 0) { // Don't check \\ else we get a message about "\\" being an invalid filename ; } else if (ss.Compare(_T("\\")) == 0) { // Show root directory pp->CheckDir(ss); } else if (len == 3 && ss[1] == ':' && ss[2] == '\\') { // Check that it's a valid drive if (GetDriveType(ss) > DRIVE_NO_ROOT_DIR) { pp->CheckDir(ss); } } else if (len > 0 && ss[len-1] == '\\') { // Check that it's a valid directory DWORD attr = GetFileAttributes(ss); if (attr != 0xFFFFFFFF && (attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { pp->CheckDir(ss); } } SetFocus(); // Make sure caret stays in this edit control}UINT RxDirEdit::OnGetDlgCode() { // Get all keys so that we see CR return CEdit::OnGetDlgCode() | DLGC_WANTALLKEYS;}// --- class RxDirEdit ---// class RxDirDialogRxDirDialog::RxDirDialog(LPCTSTR initial, LPCTSTR filter, CWnd* pParentWnd) : CFileDialog(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST, NULL, pParentWnd), m_strPath(initial){ // Note: m_strFilter is a member variable so it doesn't disappear because // it is used later internally by the file open dialog (via m_ofn.lpstrFilter). if (filter != NULL)// m_strFilter = CString(_T("Show Folders Only|.|")) + filter; m_strFilter = filter; else m_strFilter = _T("Show Folders Only|.|All Files (*.*)|*.*||"); m_strFilter.Replace('|', '\0'); m_ofn.lpstrFilter = m_strFilter; m_ofn.lpstrInitialDir = initial; m_ofn.lpstrTitle = _T("Select Folder");}void RxDirDialog::OnInitDone(){ CRect rct; // Used to move/resize controls CWnd *pp; // Parent = the dialog window itself VERIFY(pp = GetParent()); ASSERT(pp->GetDlgItem(stc3) != NULL); pp->GetDlgItem(stc3)->SetWindowText(_T("Folder:")); // Create a new RxDlgWnd so we can catch dialog control notifications VERIFY(m_DlgWnd.SubclassWindow(pp->m_hWnd)); // Create a new edit control where edt1 now is ASSERT(pp->GetDlgItem(edt1) != NULL); pp->GetDlgItem(edt1)->GetWindowRect(rct); //Get edt1 rectangle pp->ScreenToClient(rct); VERIFY(m_Edit.Create(WS_TABSTOP | WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL, rct, pp, IDC_DIR)); if (m_ofn.lpstrInitialDir != NULL) m_Edit.SetWindowText(m_ofn.lpstrInitialDir); m_Edit.SetFont(pp->GetDlgItem(edt1)->GetFont()); m_Edit.ModifyStyleEx(0, WS_EX_CLIENTEDGE, SWP_DRAWFRAME); m_Edit.SetWindowPos(pp->GetDlgItem(stc3), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);// m_Edit.SetSel(0, strlen(m_ofn.lpstrInitialDir)); CWnd *pCancel = pp->GetDlgItem(IDCANCEL); ASSERT(pCancel != NULL); // Create a new button where the OK button now is ASSERT(pp->GetDlgItem(IDOK) != NULL); pp->GetDlgItem(IDOK)->GetWindowRect(rct); //Get OK button rectangle pp->ScreenToClient(rct); m_Open.Create(_T("Open"), WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, rct, pp, IDC_OPEN); m_Open.SetFont(pp->GetDlgItem(IDOK)->GetFont()); m_Open.SetWindowPos(&m_Edit, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); pCancel->SetWindowPos(&m_Open, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); // Change default push button pp->GetDlgItem(IDOK)->ModifyStyle(BS_DEFPUSHBUTTON, 0); pp->SendMessage(DM_SETDEFID, IDC_OPEN);#ifdef DIRDIALOG_TESTING // Move controls (rather than hide them) for testing // Increase size of dialog pp->GetWindowRect(rct); pp->SetWindowPos(NULL, 0, 0, rct.Width(), rct.Height() + 70, SWP_NOZORDER | SWP_NOMOVE); // Move the replaced controls down ASSERT(pp->GetDlgItem(IDOK) != NULL); pp->GetDlgItem(IDOK)->GetWindowRect(rct); pp->ScreenToClient(rct); pp->GetDlgItem(IDOK)->SetWindowPos(NULL, rct.left, rct.top+70, 0, 0, SWP_NOZORDER | SWP_NOSIZE); ASSERT(pp->GetDlgItem(edt1) != NULL); pp->GetDlgItem(edt1)->GetWindowRect(rct); pp->ScreenToClient(rct); pp->GetDlgItem(edt1)->SetWindowPos(NULL, rct.left, rct.top+70, 0, 0, SWP_NOZORDER | SWP_NOSIZE);#else // Hide the controls we don't want the user to use HideControl(IDOK); HideControl(edt1);#endif CFileDialog::OnInitDone();}void RxDirDialog::OnFolderChange(){ CWnd *pp; // Parent window = the dialog itself VERIFY(pp = GetParent()); ASSERT(::IsWindow(pp->m_hWnd)); ASSERT(pp->GetDlgItem(IDC_DIR) != NULL); m_strPath = GetFolderPath(); int len = m_strPath.GetLength(); if (len > 0 && m_strPath[len-1] != '\\') { m_strPath += "\\"; ++len; } pp->GetDlgItem(IDC_DIR)->SetWindowText(m_strPath); m_Edit.SetSel(len, len); CFileDialog::OnFolderChange(); m_Edit.SetFocus();}void RxDlgWnd::OnSize(UINT nType,int cx,int cy) { CWnd::OnSize(nType, cx, cy); CRect rct; // Used to move/resize controls ASSERT(GetDlgItem(edt1) != NULL); GetDlgItem(edt1)->GetWindowRect(rct); //file://Get edt1 rectangle ScreenToClient(rct); GetDlgItem(IDC_DIR)->SetWindowPos(GetDlgItem(stc3), 0, 0, rct.Width(), rct.Height(), SWP_NOMOVE); ASSERT(GetDlgItem(IDOK) != NULL); GetDlgItem(IDOK)->GetWindowRect(rct); //file://Get OK button rectangle ScreenToClient(rct); GetDlgItem(IDC_OPEN)->SetWindowPos(GetDlgItem(IDC_DIR), rct.left, rct.top, 0,0, SWP_NOSIZE); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -