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 }