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