00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 #include "stdafx.h"
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 #include <Dlgs.h>           
00146 #include <imagehlp.h>       
00147 
00148 #include "vgui_dir_dialog.h"      
00149 #include <vcl_cstring.h>
00150 #include <vcl_cctype.h>
00151 
00152 
00153 #ifdef _DEBUG
00154 #define new DEBUG_NEW
00155 #undef THIS_FILE
00156 static char THIS_FILE[] = __FILE__;
00157 #endif
00158 
00159 #define IDC_DIR 181         // New edit control for entering the directory name
00160 #define IDC_OPEN 182        // New "Open" button
00161 
00162 
00163 BEGIN_MESSAGE_MAP(CDlgWnd, CWnd)
00164         ON_BN_CLICKED(IDC_OPEN, OnOpen)
00165 END_MESSAGE_MAP()
00166 
00167 
00168 void CDlgWnd::OnOpen()
00169 {
00170     
00171     CString ss;
00172     CEdit *pEdit = (CEdit *)GetDlgItem(IDC_DIR);
00173     ASSERT(pEdit != NULL);
00174     pEdit->GetWindowText(ss);
00175     int len = ss.GetLength();
00176 
00177     if (len == 2 && ss[0] == '\\' && ss[1] == '\\')
00178     {
00179         AfxMessageBox(ss + _T("\nThis is not a valid folder."));
00180         pEdit->SetFocus();
00181         return;
00182     }
00183     else if (len == 0 || len == 1 && ss[0] == '\\')
00184     {
00185         
00186         ;
00187     }
00188     else if ((len == 2 && ss[1] == ':') ||
00189              (len == 3 && ss[1] == ':' && ss[2] == '\\') )
00190     {
00191         _TCHAR rootdir[4] = _T("?:\\");
00192         rootdir[0] = ss[0];
00193 
00194         if (GetDriveType(rootdir) <= DRIVE_NO_ROOT_DIR)
00195         {
00196             AfxMessageBox(ss + _T("\nThe drive is invalid."));
00197             pEdit->SetFocus();
00198             return;
00199         }
00200     }
00201     else
00202     {
00203         
00204         if (ss[len-1] == '\\')
00205             ss = ss.Left(--len);
00206         DWORD attr = GetFileAttributes(ss);
00207         if (attr == 0xFFFFFFFF)
00208         {
00209             const char *ss2;
00210 
00211             
00212             _TCHAR rootdir[4] = _T("?:\\");
00213             rootdir[0] = ss[0];
00214 
00215             if (len > 1 && ss[1] == ':' && GetDriveType(rootdir) <= DRIVE_NO_ROOT_DIR)
00216             {
00217                 AfxMessageBox(ss + _T("\nThe drive is invalid."));
00218                 pEdit->SetFocus();
00219                 return;
00220             }
00221             else if (len >= 2 && ss[0] == '\\' && ss[1] == '\\' &&
00222                      ( (ss2 = vcl_strchr((const char *)ss+2, '\\')) == NULL || vcl_strchr(ss2+1, '\\') == NULL) )
00223             {
00224                 AfxMessageBox(ss + _T("\nThis is not a valid folder."));
00225                 pEdit->SetFocus();
00226                 return;
00227             }
00228             else
00229             {
00230                 
00231                 CString mess(ss);
00232                 mess += _T("\nThis folder does not exist.\n\nDo you want to create it?");
00233                 if (AfxMessageBox(mess, MB_YESNO) == IDYES)
00234                 {
00235                     
00236                     
00237                     
00238                     if (!::MakeSureDirectoryPathExists(ss + _T("\\")))
00239                     {
00240                         switch (GetDriveType(rootdir))
00241                         {
00242                           case DRIVE_CDROM:
00243                             AfxMessageBox(_T("You cannot create this folder\n"
00244                                           "as the CD ROM medium is read-only."));
00245                             break;
00246                           case DRIVE_REMOVABLE:
00247                             AfxMessageBox(_T("You cannot create this folder.\n"
00248                                           "The medium may be write-protected."));
00249                             break;
00250                           case DRIVE_REMOTE:
00251                             AfxMessageBox(_T("You do not have permission to create\n"
00252                                           "this folder on the network."));
00253                             break;
00254                           default:
00255                             AfxMessageBox(_T("You do not have permission\n"
00256                                           "to create this folder."));
00257                             break;
00258                         }
00259                         pEdit->SetFocus();
00260                         return;         
00261                     }
00262                     
00263                 }
00264                 else
00265                 {
00266                     pEdit->SetFocus();
00267                     return;             
00268                 }
00269             }
00270         }
00271         else if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0)
00272         {
00273            
00274             
00275             
00276         }
00277     }
00278 
00279     
00280     CheckDir(ss);
00281 
00282     ::EndDialog(m_hWnd, IDOK);
00283 }
00284 
00285 
00286 
00287 
00288 
00289 
00290 void CDlgWnd::CheckDir(const CString &ss)
00291 {
00292     
00293     CEdit *pOld = (CEdit *)GetDlgItem(edt1);
00294     ASSERT(pOld != NULL);
00295     pOld->SetWindowText(ss);
00296 
00297     
00298     CString strSaved;                       
00299     int start, end;                         
00300     CEdit *pEdit = (CEdit *)GetDlgItem(IDC_DIR);
00301     ASSERT(pEdit != NULL);
00302     pEdit->GetWindowText(strSaved);
00303     pEdit->GetSel(start, end);
00304 
00305     CWnd *pOK = GetDlgItem(IDOK);
00306     pOK->SendMessage(WM_LBUTTONDOWN);
00307     pOK->SendMessage(WM_LBUTTONUP);
00308 
00309     CString strNew;
00310     pEdit->GetWindowText(strNew);
00311 
00312     
00313     
00314     
00315     
00316     
00317     
00318     
00319     if (strSaved.IsEmpty() || strSaved[0] == '.' ||
00320         strNew.CompareNoCase(strSaved) == 0 || strNew.CompareNoCase(strSaved + '\\') == 0)
00321     {
00322         pEdit->SetSel(strNew.GetLength(), -1);
00323     }
00324     else
00325     {
00326         
00327         pEdit->SetWindowText(strSaved);
00328         pEdit->SetSel(start, end);
00329     }
00330 }
00331 
00332 
00333 
00334 BEGIN_MESSAGE_MAP(CDirEdit, CEdit)
00335     ON_WM_CHAR()
00336     ON_WM_KEYDOWN()
00337     ON_WM_GETDLGCODE()
00338 END_MESSAGE_MAP()
00339 
00340 void CDirEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
00341 {
00342     CDlgWnd *pp;                           
00343     VERIFY(pp = (CDlgWnd *)GetParent());
00344 
00345     if (nChar == '\t')
00346     {
00347         
00348         
00349         
00350         CWnd *pWnd = pp->GetDlgItem(IDC_OPEN);
00351         ASSERT(pWnd != NULL);
00352         pWnd->SetFocus();                       
00353     }
00354     else if (nChar == '\r' || nChar == '\n')
00355     {
00356         
00357         
00358         
00359         
00360         
00361         
00362         
00363 
00364         CString ss;
00365         GetWindowText(ss);
00366         int len = ss.GetLength();
00367 
00368         
00369         if (vcl_strcmp(ss,"\\") != 0 && vcl_strcmp(ss,"\\\\") != 0 && vcl_strcmp((const char *)ss+1,":\\") != 0 &&
00370             len > 0 && ss[len-1] == '\\' )
00371         {
00372             ss = ss.Left(--len);
00373         }
00374 
00375         if (len == 0 ||
00376             len == 1 && ss[0] == '\\' ||
00377             len >= 2 && ss[0] == '\\' && ss[1] == '\\' && vcl_strchr((const char *)ss+2, '\\') == NULL ||
00378             len == 2 && ss[1] == ':' ||
00379             len == 3 && ss[1] == ':' && ss[2] == '\\' )
00380         {
00381             
00382             pp->CheckDir(ss);
00383         }
00384         else
00385         {
00386             
00387             CFileStatus fs;
00388 
00389             DWORD attr = GetFileAttributes(ss);
00390             if (attr == 0xFFFFFFFF)
00391             {
00392                 
00393                 _TCHAR rootdir[4] = _T("?:\\");
00394                 rootdir[0] = ss[0];
00395 
00396                 if (len == 1 || (len > 1 && ss[1] != ':') ||
00397                     GetDriveType(rootdir) > DRIVE_NO_ROOT_DIR)
00398                 {
00399                     
00400                     CString mess(ss);
00401                     mess += _T("\nThis folder does not exist.\n\nDo you want to create it?");
00402                     if (AfxMessageBox(mess, MB_YESNO) == IDYES)
00403                     {
00404                         if (!::MakeSureDirectoryPathExists(ss + _T("\\")))
00405                         {
00406                             switch (GetDriveType(rootdir))
00407                             {
00408                               case DRIVE_CDROM:
00409                                 AfxMessageBox(_T("You cannot create this folder\n"
00410                                               "as the CD ROM medium is read-only."));
00411                                 break;
00412                               case DRIVE_REMOVABLE:
00413                                 AfxMessageBox(_T("You cannot create this folder.\n"
00414                                               "The medium may be write-protected."));
00415                                 break;
00416                               case DRIVE_REMOTE:
00417                                 AfxMessageBox(_T("You do not have permission to create\n"
00418                                               "this folder on the network."));
00419                                 break;
00420                               default:
00421                                 AfxMessageBox(_T("You do not have permission or\n"
00422                                               "otherwise cannot create this folder."));
00423                                 break;
00424                             }
00425                             return;
00426                         }
00427                     }
00428                     else
00429                         return;
00430                 }
00431             }
00432             pp->CheckDir(ss);
00433             
00434             GetWindowText(ss);
00435             if (ss[ss.GetLength()-1] != '\\')
00436             {
00437                 ss += "\\";
00438                 SetWindowText(ss);
00439             }
00440             SetSel(ss.GetLength(), -1);
00441         }
00442         SetFocus();                         
00443     }
00444     else
00445     {
00446         CEdit::OnChar(nChar, nRepCnt, nFlags);
00447 
00448         
00449         CString ss;                         
00450         GetWindowText(ss);
00451 
00452         int len = ss.GetLength();
00453         int start, end;                     
00454         GetSel(start, end);
00455 
00456         if (ss.Compare(_T("\\\\")) == 0)
00457         {
00458             
00459             ;
00460         }
00461         else if (ss.Compare(_T("\\")) == 0)
00462         {
00463             
00464             pp->CheckDir(ss);
00465         }
00466         else if (len == 3 && ss[1] == ':' && ss[2] == '\\')
00467         {
00468             
00469             if (GetDriveType(ss) > DRIVE_NO_ROOT_DIR)
00470             {
00471                 pp->CheckDir(ss);
00472             }
00473         }
00474         else if (len > 0 && ss[len-1] == '\\')
00475         {
00476             
00477             
00478             DWORD attr = GetFileAttributes(ss);
00479             if (attr != 0xFFFFFFFF && (attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
00480             {
00481                 pp->CheckDir(ss);
00482             }
00483         }
00484         else if (start == len && nChar != '\b')
00485         {
00486             
00487             CFileFind ff;                   
00488             int count = 0;                  
00489             CString strMatch;               
00490 
00491             BOOL bContinue = ff.FindFile(ss + "*");
00492 
00493             while (bContinue)
00494             {
00495                 
00496                 bContinue = ff.FindNextFile();
00497 
00498                 if (ff.IsDirectory())
00499                 {
00500                     
00501                     ++count;
00502                     strMatch = ff.GetFileName();
00503                 }
00504             }
00505 
00506             
00507             if (count == 1)
00508             {
00509                 int ii;
00510                 
00511                 
00512                 for (ii = 0; ii < strMatch.GetLength(); ++ii)
00513                 {
00514                     
00515                     if (vcl_isspace(strMatch[ii]) || vcl_islower(strMatch[ii]))
00516                         break;
00517                 }
00518 
00519                 ASSERT(ii <= strMatch.GetLength());
00520                 if (!strMatch.IsEmpty() && ii == strMatch.GetLength())
00521                 {
00522                     CString temp = strMatch.Mid(1);
00523                     temp.MakeLower();
00524                     strMatch = strMatch.Left(1) + temp;
00525                 }
00526 
00527                 
00528                 int lb_len;             
00529                 lb_len = ss.ReverseFind('\\');
00530                 if (lb_len == -1) lb_len = ss.ReverseFind('/');
00531                 if (lb_len == -1) lb_len = ss.ReverseFind(':');
00532                 if (lb_len == -1)
00533                     lb_len = ss.GetLength();
00534                 else
00535                     lb_len = ss.GetLength() - (lb_len+1);
00536 
00537                 
00538                 if (!ss.IsEmpty() && lb_len > 0 && strMatch[lb_len-1] != ss[ss.GetLength()-1])
00539                 {
00540                     
00541                     
00542                     if (vcl_isupper(ss[ss.GetLength()-1]))
00543                         strMatch.MakeUpper();
00544                     else
00545                         strMatch.MakeLower();
00546                 }
00547 
00548 #ifdef _DEBUG
00549                 CString temp = strMatch.Left(lb_len);
00550                 ASSERT(temp.CompareNoCase(ss.Right(lb_len)) == 0);
00551 #endif
00552                 end += strMatch.GetLength() - lb_len;
00553                 SetWindowText(ss + strMatch.Mid(lb_len));
00554                 SetSel(start, end);
00555             }
00556 
00557             
00558         }
00559         SetFocus();                         
00560     }
00561 }
00562 
00563 void CDirEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
00564 {
00565     CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
00566 
00567     if (nChar != VK_DELETE)
00568         return;
00569 
00570     CDlgWnd *pp;                           
00571     VERIFY(pp = (CDlgWnd *)GetParent());
00572 
00573     
00574     CString ss;
00575     GetWindowText(ss);
00576     int len = ss.GetLength();
00577 
00578     if (ss.Compare(_T("\\\\")) == 0)
00579     {
00580         
00581         ;
00582     }
00583     else if (ss.Compare(_T("\\")) == 0)
00584     {
00585         
00586         pp->CheckDir(ss);
00587     }
00588     else if (len == 3 && ss[1] == ':' && ss[2] == '\\')
00589     {
00590         
00591         if (GetDriveType(ss) > DRIVE_NO_ROOT_DIR)
00592         {
00593             pp->CheckDir(ss);
00594         }
00595     }
00596     else if (len > 0 && ss[len-1] == '\\')
00597     {
00598         
00599         DWORD attr = GetFileAttributes(ss);
00600         if (attr != 0xFFFFFFFF && (attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
00601         {
00602             pp->CheckDir(ss);
00603         }
00604     }
00605     SetFocus();                         
00606 }
00607 
00608 UINT CDirEdit::OnGetDlgCode()
00609 {
00610     
00611     return CEdit::OnGetDlgCode() | DLGC_WANTALLKEYS;
00612 }
00613 
00614 
00615 
00616 vgui_dir_dialog::vgui_dir_dialog(LPCTSTR initial, LPCTSTR filter, CWnd* pParentWnd)
00617 #if WINVER >= 0x0600
00618     : CFileDialog(TRUE, NULL, NULL,
00619                   OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST,
00620                   NULL, pParentWnd,0,0), 
00621 #else
00622     : CFileDialog(TRUE, NULL, NULL,
00623                   OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST,
00624                   NULL, pParentWnd),
00625 #endif
00626       m_strPath(initial)
00627 {
00628     
00629     
00630     if (filter != NULL)
00631       m_strFilter = filter + CString(_T("Show Folders Only|.||"));
00632     else
00633         m_strFilter = _T("All Files (*.*)|*.*||Show Folders Only|.|");
00634     m_strFilter.Replace('|', '\0');
00635     m_ofn.lpstrFilter = m_strFilter;
00636 
00637     m_ofn.lpstrInitialDir = initial;
00638 
00639     m_ofn.lpstrTitle = _T("Select Folder");
00640 
00641     m_ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
00642 }
00643 
00644 void vgui_dir_dialog::OnInitDone()
00645 {
00646     CRect rct;                          
00647     CWnd *pp;                           
00648     VERIFY(pp = GetParent());
00649 
00650     ASSERT(pp->GetDlgItem(stc3) != NULL);
00651     pp->GetDlgItem(stc3)->SetWindowText(_T("Folder:"));
00652 
00653     
00654     VERIFY(m_DlgWnd.SubclassWindow(pp->m_hWnd));
00655 
00656     
00657     CWnd *w = pp->GetDlgItem(edt1);
00658     ASSERT(pp->GetDlgItem(edt1) != NULL);
00659     pp->GetDlgItem(edt1)->GetWindowRect(rct); 
00660     pp->ScreenToClient(rct);
00661 
00662     VERIFY(m_Edit.Create(WS_TABSTOP | WS_VISIBLE | WS_CHILD,
00663                            rct, pp, IDC_DIR));
00664     if (m_ofn.lpstrInitialDir  != NULL)
00665         m_Edit.SetWindowText(m_ofn.lpstrInitialDir);
00666     m_Edit.SetFont(pp->GetDlgItem(edt1)->GetFont());
00667     m_Edit.ModifyStyleEx(0, WS_EX_CLIENTEDGE, SWP_DRAWFRAME);
00668     m_Edit.SetWindowPos(pp->GetDlgItem(stc3), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
00669 
00670 
00671     CWnd *pCancel = pp->GetDlgItem(IDCANCEL);
00672     ASSERT(pCancel != NULL);
00673 
00674     
00675     ASSERT(pp->GetDlgItem(IDOK) != NULL);
00676     pp->GetDlgItem(IDOK)->GetWindowRect(rct); 
00677     pp->ScreenToClient(rct);
00678 
00679     m_Open.Create(_T("Open"), WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
00680                   rct, pp, IDC_OPEN);
00681     m_Open.SetFont(pp->GetDlgItem(IDOK)->GetFont());
00682     m_Open.SetWindowPos(&m_Edit, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
00683 
00684     pCancel->SetWindowPos(&m_Open, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
00685 
00686     
00687     pp->GetDlgItem(IDOK)->ModifyStyle(BS_DEFPUSHBUTTON, 0);
00688     pp->SendMessage(DM_SETDEFID, IDC_OPEN);
00689 
00690 #ifdef DIRDIALOG_TESTING
00691     
00692 
00693     
00694     pp->GetWindowRect(rct);
00695     pp->SetWindowPos(NULL, 0, 0, rct.Width(), rct.Height() + 70, SWP_NOZORDER | SWP_NOMOVE);
00696 
00697     
00698     ASSERT(pp->GetDlgItem(IDOK) != NULL);
00699     pp->GetDlgItem(IDOK)->GetWindowRect(rct);
00700     pp->ScreenToClient(rct);
00701     pp->GetDlgItem(IDOK)->SetWindowPos(NULL, rct.left, rct.top+70,
00702                    0, 0, SWP_NOZORDER | SWP_NOSIZE);
00703 
00704     ASSERT(pp->GetDlgItem(edt1) != NULL);
00705     pp->GetDlgItem(edt1)->GetWindowRect(rct);
00706     pp->ScreenToClient(rct);
00707     pp->GetDlgItem(edt1)->SetWindowPos(NULL, rct.left, rct.top+70,
00708                    0, 0, SWP_NOZORDER | SWP_NOSIZE);
00709 
00710 #else
00711     
00712     HideControl(IDOK);
00713     HideControl(edt1);
00714 #endif
00715 
00716     CFileDialog::OnInitDone();
00717 }
00718 
00719 void vgui_dir_dialog::OnFolderChange()
00720 {
00721     CWnd *pp;                           
00722     VERIFY(pp = GetParent());
00723     pp = GetParent();
00724     ASSERT(::IsWindow(pp->m_hWnd));
00725 
00726     ASSERT(pp->GetDlgItem(IDC_DIR) != NULL);
00727     m_strPath = GetFolderPath();
00728     int len = m_strPath.GetLength();
00729     if (len > 0 && m_strPath[len-1] != '\\')
00730     {
00731         m_strPath += "\\";
00732         ++len;
00733     }
00734     pp->GetDlgItem(IDC_DIR)->SetWindowText(m_strPath);
00735     m_Edit.SetSel(len, len);
00736 
00737     CFileDialog::OnFolderChange();
00738 
00739     m_Edit.SetFocus();
00740 }
00741 
00742 BOOL vgui_dir_dialog::OnFileNameOK()
00743 {
00744     CWnd *pp; 
00745     VERIFY(pp = GetParent());
00746     ASSERT(::IsWindow(pp->m_hWnd));
00747 
00748     ASSERT(pp->GetDlgItem(IDC_DIR) != NULL);
00749 
00750     m_strPath = GetPathName();
00751     int len = m_strPath.GetLength();
00752 
00753     pp->GetDlgItem(IDC_DIR)->SetWindowText(m_strPath);
00754     m_Edit.SetSel(len, len);
00755 
00756     CFileDialog::OnFolderChange();
00757 
00758     m_Edit.SetFocus();
00759 
00760     return TRUE;
00761 }