Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

512 lines
18 KiB

  1. /*++
  2. Microsoft Windows
  3. Copyright (C) Microsoft Corporation, 1981 - 1999
  4. Module Name:
  5. irftpdlg.cpp
  6. Abstract:
  7. Author:
  8. Rahul Thombre (RahulTh) 4/30/1998
  9. Revision History:
  10. 4/30/1998 RahulTh
  11. Created this module.
  12. --*/
  13. // irftpDlg.cpp : implementation file
  14. //
  15. #include "precomp.hxx"
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. //the context sensitive help array
  22. const DWORD g_aHelpIDs_IDD_IRDA_DIALOG[]=
  23. {
  24. IDC_IR_DESC, IDH_DISABLEHELP, // Untitled: "You can send..." (Static)
  25. IDC_LOCATION_GROUP, IDH_DISABLEHELP, // Untitled: "Location" (Button)
  26. IDB_HELP_BUTTON, IDH_HELP_BUTTON, // Untitled: "Help" (Button)
  27. IDB_SEND_BUTTON, IDH_SEND_BUTTON, // Untitled: "Send" (Button)
  28. IDB_SETTINGS_BUTTON, IDH_SETTINGS_BUTTON, // Untitled: "Settings" (Button)
  29. IDB_CLOSE_BUTTON, IDH_CLOSE_BUTTON, // Untitled: "Close" (Button)
  30. IDC_ADD_DESC, IDH_DISABLEHELP, //the second line of text describing the ir dialog
  31. IDC_IR_ICON, IDH_DISABLEHELP, //the icon on the dialog
  32. 0, 0
  33. };
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CIrftpDlg dialog
  36. CIrftpDlg::CIrftpDlg( ) : CFileDialog(TRUE)
  37. {
  38. //{{AFX_DATA_INIT(CIrftpDlg)
  39. //}}AFX_DATA_INIT
  40. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  41. //get the location of the "My Documents" folder
  42. //this should be used as the initial dir.
  43. m_lpszInitialDir[0] = '\0'; //just in case SHGetSpecialFolderPath fails.
  44. SHGetSpecialFolderPath (NULL, m_lpszInitialDir, CSIDL_PERSONAL, FALSE);
  45. //if the above call fails, then the common file open dialog box will
  46. //default to the current directory.
  47. m_iFileNamesCharCount = 0;
  48. TCHAR szFile[] = TEXT("\0");
  49. m_ptl = NULL;
  50. m_pParentWnd = NULL;
  51. LoadString(g_hInstance, IDS_CAPTION, m_szCaption, MAX_PATH);
  52. LoadFilter();
  53. m_ofn.lStructSize = sizeof(OPENFILENAME);
  54. m_ofn.hInstance = g_hInstance;
  55. m_ofn.lpstrFilter = m_szFilter;
  56. m_ofn.nFilterIndex = 1;
  57. m_ofn.lpstrFile = m_lpstrFile;
  58. m_ofn.lpstrFile[0] = '\0';
  59. m_ofn.nMaxFile = MAX_PATH;
  60. m_ofn.lpstrInitialDir = m_lpszInitialDir;
  61. m_ofn.lpstrTitle = m_szCaption;
  62. m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_IRDA_DIALOG);
  63. m_ofn.Flags |= OFN_EXPLORER | OFN_ENABLETEMPLATE | OFN_ENABLEHOOK |
  64. OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT |
  65. OFN_PATHMUSTEXIST | OFN_NODEREFERENCELINKS;
  66. m_ofn.Flags &= (~ OFN_ENABLESIZING);
  67. }
  68. void CIrftpDlg::DoDataExchange(CDataExchange* pDX)
  69. {
  70. CDialog::DoDataExchange(pDX);
  71. //{{AFX_DATA_MAP(CIrftpDlg)
  72. DDX_Control(pDX, IDB_HELP_BUTTON, m_helpBtn);
  73. DDX_Control(pDX, IDB_SETTINGS_BUTTON, m_settingsBtn);
  74. DDX_Control(pDX, IDB_SEND_BUTTON, m_sendBtn);
  75. DDX_Control(pDX, IDB_CLOSE_BUTTON, m_closeBtn);
  76. DDX_Control(pDX, IDC_LOCATION_GROUP, m_locationGroup);
  77. DDX_Control(pDX, 1119, m_commFile);
  78. //}}AFX_DATA_MAP
  79. }
  80. BEGIN_MESSAGE_MAP(CIrftpDlg, CFileDialog)
  81. //{{AFX_MSG_MAP(CIrftpDlg)
  82. //ON_WM_PAINT() //uncomment this line only if the dialog has a bitmap instead of an icon that needs to be drawn transparently.
  83. ON_BN_CLICKED(IDB_HELP_BUTTON, OnHelpButton)
  84. ON_BN_CLICKED(IDB_CLOSE_BUTTON, OnCloseButton)
  85. ON_BN_CLICKED(IDB_SEND_BUTTON, OnSendButton)
  86. ON_BN_CLICKED(IDB_SETTINGS_BUTTON, OnSettingsButton)
  87. ON_MESSAGE (WM_HELP, OnHelp)
  88. ON_MESSAGE (WM_CONTEXTMENU, OnContextMenu)
  89. ON_WM_SYSCOMMAND()
  90. //}}AFX_MSG_MAP
  91. END_MESSAGE_MAP()
  92. /////////////////////////////////////////////////////////////////////////////
  93. // CIrftpDlg message handlers
  94. BOOL CIrftpDlg::OnInitDialog()
  95. {
  96. HWND hWndParent; //handle to the parent window,
  97. //viz.the common file dialog box created by explorer
  98. HRESULT hr = E_FAIL;
  99. CFileDialog::OnInitDialog();
  100. //save the pointer to the parent window
  101. m_pParentWnd = GetParent();
  102. hWndParent = m_pParentWnd->m_hWnd;
  103. //Add icons to the parent window
  104. //to see if we can get the Wireless Link icon on Alt-<Tab>
  105. m_pParentWnd->ModifyStyle (0, WS_SYSMENU | WS_CAPTION, SWP_NOSIZE | SWP_NOMOVE);
  106. //hide the Help, Open and Cancel buttons. We will use our own
  107. //this helps in having a better looking UI
  108. CommDlg_OpenSave_HideControl(hWndParent, pshHelp);
  109. CommDlg_OpenSave_HideControl(hWndParent, IDOK);
  110. CommDlg_OpenSave_HideControl(hWndParent, IDCANCEL);
  111. CommDlg_OpenSave_HideControl(hWndParent, stc2);
  112. CommDlg_OpenSave_HideControl(hWndParent, cmb1);
  113. //Initialize the taskbar list interface
  114. hr = CoInitialize(NULL);
  115. if (SUCCEEDED (hr))
  116. hr = CoCreateInstance(CLSID_TaskbarList,
  117. NULL,
  118. CLSCTX_INPROC_SERVER,
  119. IID_ITaskbarList,
  120. (LPVOID*)&m_ptl);
  121. if (SUCCEEDED(hr))
  122. {
  123. hr = m_ptl->HrInit();
  124. }
  125. else
  126. {
  127. m_ptl = NULL;
  128. }
  129. if (m_ptl)
  130. {
  131. if (SUCCEEDED(hr))
  132. m_ptl->AddTab(m_pParentWnd->m_hWnd);
  133. else
  134. {
  135. m_ptl->Release();
  136. m_ptl = NULL;
  137. }
  138. }
  139. // return TRUE unless you set the focus to a control
  140. return TRUE;
  141. }
  142. BOOL CIrftpDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  143. {
  144. LPOFNOTIFY lpofn = (LPOFNOTIFY)lParam;
  145. switch (lpofn->hdr.code)
  146. {
  147. case CDN_INITDONE:
  148. InitializeUI();
  149. break;
  150. case CDN_FOLDERCHANGE:
  151. //clear the edit box whenever the folder is changed
  152. //using both the controls because of the bug which gives the older
  153. //file dialog in some cases and the new file dialog in some others
  154. CommDlg_OpenSave_SetControlText(m_pParentWnd->m_hWnd, edt1, TEXT(""));
  155. CommDlg_OpenSave_SetControlText(m_pParentWnd->m_hWnd, cmb13, TEXT(""));
  156. break;
  157. case CDN_SELCHANGE:
  158. UpdateSelection();
  159. break;
  160. case CDN_FILEOK:
  161. UpdateSelection();
  162. OnSendButton();
  163. *pResult = 1;
  164. return TRUE;
  165. default:
  166. return CFileDialog::OnNotify(wParam, lParam, pResult);
  167. }
  168. return TRUE;
  169. }
  170. void CIrftpDlg::OnHelpButton ()
  171. {
  172. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  173. CString szHelpFile;
  174. szHelpFile.LoadString (IDS_HTML_HELPFILE);
  175. g_hwndHelp = HtmlHelp (m_pParentWnd->m_hWnd, (LPCTSTR) szHelpFile, HH_DISPLAY_TOPIC, 0);
  176. }
  177. void CIrftpDlg::OnCloseButton()
  178. {
  179. //owing to UI design issues, we chose to use our own Close button
  180. //rather than the explorer provided Cancel button in the common
  181. //file dialog box
  182. //m_pParentWnd->PostMessage(WM_QUIT);
  183. m_pParentWnd->PostMessage(WM_CLOSE);
  184. }
  185. //this function is invoked when the CDN_INITDONE message is received
  186. //this indicates that explorer has finished placing and resizing the
  187. //controls on the template.
  188. //this function resizes and moves some of the controls to make sure
  189. //that the common file dialog controls and the template controls do
  190. //not overlap
  191. void CIrftpDlg::InitializeUI()
  192. {
  193. //change the geometry of some of the controls so that the UI looks good
  194. //and there are no overlapping controls
  195. RECT rc;
  196. int newWidth, newHeight, xshift, yshift, btnTop, parentLeft, parentTop;
  197. CWnd* pParentWnd;
  198. CWnd* pDesktop;
  199. CWnd* pTemplateParentWnd;
  200. UINT commFlags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER;
  201. m_commFile.GetClientRect(&rc);
  202. newWidth = rc.right - rc.left + 20;
  203. newHeight = rc.bottom - rc.top + 20;
  204. //resize the Location group box so that the common file controls
  205. //are inscribed in it
  206. m_locationGroup.SetWindowPos(NULL, -1, -1, newWidth, newHeight,
  207. SWP_NOMOVE | commFlags);
  208. //shift the Send, Settings and Close buttons so that the last button
  209. //is aligned with the right edge of the group box controls.
  210. pTemplateParentWnd = m_locationGroup.GetParent();
  211. pParentWnd = GetParent();
  212. pParentWnd->GetWindowRect(&rc);
  213. parentLeft = rc.left;
  214. parentTop = rc.top;
  215. m_locationGroup.GetWindowRect(&rc);
  216. btnTop = rc.bottom - 10;
  217. ::MapWindowPoints(NULL , pTemplateParentWnd->m_hWnd , (LPPOINT) &rc , 2);
  218. xshift = rc.right;
  219. m_closeBtn.GetWindowRect(&rc);
  220. ::MapWindowPoints(NULL , pTemplateParentWnd->m_hWnd , (LPPOINT) &rc , 2);
  221. xshift -= rc.right;
  222. m_closeBtn.SetWindowPos(NULL, rc.left + xshift,
  223. btnTop - parentTop, -1, -1,
  224. SWP_NOSIZE | commFlags);
  225. m_sendBtn.GetWindowRect(&rc);
  226. ::MapWindowPoints(NULL , pTemplateParentWnd->m_hWnd , (LPPOINT) &rc , 2);
  227. m_sendBtn.SetWindowPos(NULL, rc.left + xshift,
  228. btnTop - parentTop, -1, -1,
  229. SWP_NOSIZE | commFlags);
  230. //move the help button so that its left edge aligns with the left
  231. //edge of the location group box.
  232. m_locationGroup.GetWindowRect (&rc);
  233. ::MapWindowPoints(NULL , pTemplateParentWnd->m_hWnd , (LPPOINT) &rc , 2);
  234. xshift = rc.left;
  235. m_helpBtn.GetWindowRect (&rc);
  236. ::MapWindowPoints(NULL , pTemplateParentWnd->m_hWnd , (LPPOINT) &rc , 2);
  237. xshift -= rc.left;
  238. m_helpBtn.SetWindowPos (NULL, rc.left + xshift,
  239. btnTop - parentTop,
  240. -1, -1, SWP_NOSIZE | commFlags);
  241. m_settingsBtn.GetWindowRect (&rc);
  242. ::MapWindowPoints(NULL , pTemplateParentWnd->m_hWnd , (LPPOINT) &rc , 2);
  243. //move the Settings button so that the distance between the
  244. //Help and Settings button conforms to the UI guidelines.
  245. m_settingsBtn.SetWindowPos (NULL, rc.left + xshift,
  246. btnTop - parentTop, -1, -1,
  247. SWP_NOSIZE | commFlags);
  248. //now that all the controls have been positioned appropriately,
  249. //reposition the entire window so that it appears at the center
  250. //of the screen rather than being partially obscured by the screen.
  251. pParentWnd->GetClientRect (&rc);
  252. newHeight = rc.bottom;
  253. newWidth = rc.right;
  254. pDesktop = GetDesktopWindow();
  255. pDesktop->GetClientRect (&rc);
  256. yshift = (rc.bottom - newHeight)/2;
  257. xshift = (rc.right - newWidth)/2;
  258. //there might be a problem if someday the dialog should
  259. //get larger than the desktop. But then, there is no way
  260. //we can fit that window inside the desktop anyway.
  261. //So the best we can do is place it at the top left corner
  262. xshift = (xshift >= 0)?xshift:0;
  263. yshift = (yshift >= 0)?yshift:0;
  264. pParentWnd->SetWindowPos (NULL, xshift, yshift,
  265. -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
  266. pParentWnd->SetActiveWindow();
  267. }
  268. void CIrftpDlg::LoadFilter()
  269. {
  270. int strId;
  271. TCHAR* curr;
  272. int step, remainChars;
  273. for(strId = IDS_FILTER_START + 1, curr = m_szFilter, remainChars = MAX_PATH - 1;
  274. strId < IDS_FILTER_END;
  275. strId++, curr += step + 1, remainChars -= (step + 1))
  276. {
  277. step = LoadString(g_hInstance, strId, curr, remainChars);
  278. }
  279. *curr = '\0'; //terminated by 2 NULLs
  280. }
  281. void CIrftpDlg::OnSendButton()
  282. {
  283. int iSize = (m_iFileNamesCharCount>MAX_PATH)?m_iFileNamesCharCount:MAX_PATH; //kluge
  284. TCHAR *lpszName = NULL;
  285. TCHAR lpszPath[MAX_PATH];
  286. TCHAR *lpszFileList = NULL;
  287. TCHAR *lpszFullPathnamesList;
  288. int iFileCount;
  289. int iCharCount;
  290. BOOL bAllocFailed = FALSE;
  291. try
  292. {
  293. lpszName = new TCHAR [iSize];
  294. lpszFileList = new TCHAR [iSize];
  295. }
  296. catch (CMemoryException* e)
  297. {
  298. bAllocFailed = TRUE;
  299. e->Delete();
  300. }
  301. if (bAllocFailed || (NULL == lpszName) || (NULL == lpszFileList))
  302. goto cleanup_onSend;
  303. CommDlg_OpenSave_GetFolderPath(m_pParentWnd->m_hWnd, lpszPath, MAX_PATH);
  304. CommDlg_OpenSave_GetSpec (m_pParentWnd->m_hWnd, lpszName, MAX_PATH);
  305. iFileCount = ParseFileNames(lpszName, lpszFileList, iCharCount);
  306. if (!iFileCount)
  307. goto cleanup_onSend; //no files/dirs have been selected
  308. else if(1 == iFileCount) //this is a special case because if there is only one file, then absolute paths/UNC paths are allowed
  309. lpszFullPathnamesList = ProcessOneFile (lpszPath, lpszFileList, iFileCount, iCharCount);
  310. else
  311. lpszFullPathnamesList = GetFullPathnames(lpszPath, lpszFileList, iFileCount, iCharCount);
  312. CSendProgress* dlgProgress;
  313. dlgProgress = new CSendProgress(lpszFullPathnamesList, iCharCount);
  314. dlgProgress->ShowWindow(SW_SHOW);
  315. dlgProgress->SetFocus();
  316. dlgProgress->SetWindowPos (&wndTop, -1, -1, -1, -1, SWP_NOMOVE | SWP_NOSIZE);
  317. cleanup_onSend:
  318. if (lpszName)
  319. delete [] lpszName;
  320. if (lpszFileList)
  321. delete [] lpszFileList;
  322. }
  323. void CIrftpDlg::OnSettingsButton()
  324. {
  325. appController->PostMessage(WM_APP_TRIGGER_SETTINGS);
  326. }
  327. void CIrftpDlg::UpdateSelection()
  328. {
  329. CListCtrl* pDirContents;
  330. pDirContents = (CListCtrl*)(m_pParentWnd->GetDlgItem(lst2))->GetDescendantWindow(1);
  331. TCHAR lpszPath[MAX_PATH];
  332. CString szPath;
  333. CString szFullName;
  334. CString szEditBoxText;
  335. //get the path of the folder
  336. CommDlg_OpenSave_GetFolderPath (m_pParentWnd->m_hWnd, lpszPath, MAX_PATH);
  337. szPath = lpszPath; //easier to manipulate CStrings
  338. LONG nFiles = pDirContents->GetSelectedCount();
  339. TCHAR pszFileName[MAX_PATH];
  340. DWORD dwFileAttributes;
  341. CString szFilesList;
  342. int iSelectedDirCount = 0;
  343. int nIndex;
  344. if (nFiles)
  345. {
  346. //go to the point just before the first selected item
  347. nIndex = pDirContents->GetTopIndex() - 1;
  348. szEditBoxText.Empty();
  349. szPath += '\\';
  350. //first add all the directories
  351. while (-1 != (nIndex = pDirContents->GetNextItem(nIndex, LVNI_ALL | LVNI_SELECTED)))
  352. {
  353. pDirContents->GetItemText(nIndex, 0, pszFileName, MAX_PATH);
  354. szFullName = szPath + pszFileName;
  355. //check if it is a directory.
  356. dwFileAttributes = GetFileAttributes(szFullName);
  357. if (0xFFFFFFFF != dwFileAttributes &&
  358. (FILE_ATTRIBUTE_DIRECTORY & dwFileAttributes))
  359. {
  360. //it is a directory so add it to the edit box text
  361. szEditBoxText += '\"';
  362. szEditBoxText += pszFileName;
  363. szEditBoxText += TEXT("\" ");
  364. iSelectedDirCount++;
  365. }
  366. }
  367. //now we have got all the directories, get the files list if any
  368. if (nFiles > iSelectedDirCount)
  369. {
  370. //if nFiles > iSelectedDirCount, it means that all the selected
  371. //items are not dirs. this check is necessary because the function
  372. //GetFileName will return the names of the last set of files
  373. //selected if no file is currently selected. this is clearly
  374. //not what we want
  375. szFilesList.Empty();
  376. szFilesList = GetFileName();
  377. if ((!szFilesList.IsEmpty()) && '\"' != szFilesList[0])
  378. {
  379. //only one file is selected. we must add the enclosing
  380. //double quotes ourselves, since the common file dialog
  381. //does not do it for us.
  382. szFilesList = '\"' + szFilesList + TEXT("\" ");
  383. }
  384. //add the list of files to the end of the list of directories
  385. szEditBoxText += szFilesList;
  386. }
  387. //populate the controls with this list
  388. CommDlg_OpenSave_SetControlText(m_pParentWnd->m_hWnd, edt1, (LPCTSTR)szEditBoxText);
  389. CommDlg_OpenSave_SetControlText(m_pParentWnd->m_hWnd, cmb13, (LPCTSTR)szEditBoxText);
  390. m_iFileNamesCharCount = szEditBoxText.GetLength() + 1;
  391. }
  392. else
  393. {
  394. m_iFileNamesCharCount = 0;
  395. CommDlg_OpenSave_SetControlText(m_pParentWnd->m_hWnd, edt1, TEXT(""));
  396. CommDlg_OpenSave_SetControlText(m_pParentWnd->m_hWnd, cmb13, TEXT(""));
  397. }
  398. }
  399. void CIrftpDlg::PostNcDestroy()
  400. {
  401. if (m_ptl)
  402. {
  403. m_ptl->DeleteTab(m_pParentWnd->m_hWnd);
  404. m_ptl->Release();
  405. m_ptl = NULL;
  406. }
  407. CFileDialog::PostNcDestroy();
  408. }
  409. LONG CIrftpDlg::OnHelp (WPARAM wParam, LPARAM lParam)
  410. {
  411. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  412. LONG lResult = 0;
  413. CString szHelpFile;
  414. szHelpFile.LoadString(IDS_HELP_FILE);
  415. ::WinHelp((HWND)(((LPHELPINFO)lParam)->hItemHandle),
  416. (LPCTSTR) szHelpFile,
  417. HELP_WM_HELP,
  418. (ULONG_PTR)(LPTSTR)g_aHelpIDs_IDD_IRDA_DIALOG);
  419. return lResult;
  420. }
  421. LONG CIrftpDlg::OnContextMenu (WPARAM wParam, LPARAM lParam)
  422. {
  423. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  424. LONG lResult = 0;
  425. CString szHelpFile;
  426. szHelpFile.LoadString(IDS_HELP_FILE);
  427. ::WinHelp((HWND)wParam,
  428. (LPCTSTR)szHelpFile,
  429. HELP_CONTEXTMENU,
  430. (ULONG_PTR)(LPVOID)g_aHelpIDs_IDD_IRDA_DIALOG);
  431. return lResult;
  432. }