Leaked source code of windows server 2003
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.

1518 lines
50 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: COMTRANS.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 9/28/1999
  12. *
  13. * DESCRIPTION: Transfer page. Gets the destination path and filename.
  14. *
  15. *******************************************************************************/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #include <psutil.h>
  19. #include "mboxex.h"
  20. #include "comtrans.h"
  21. #include "simcrack.h"
  22. #include "waitcurs.h"
  23. #include "resource.h"
  24. #include "wiatextc.h"
  25. #include "flnfile.h"
  26. #include "itranhlp.h"
  27. #include "itranspl.h"
  28. #include "isuppfmt.h"
  29. #include "wiadevdp.h"
  30. #include "destdata.h"
  31. #include "simrect.h"
  32. #include "wiaffmt.h"
  33. //
  34. // We use this instead of GetSystemMetrics(SM_CXSMICON)/GetSystemMetrics(SM_CYSMICON) because
  35. // large "small" icons wreak havoc with dialog layout
  36. //
  37. #define SMALL_ICON_SIZE 16
  38. //
  39. // Maximum length of the filename we allow
  40. //
  41. #define MAXIMUM_ALLOWED_FILENAME_LENGTH 64
  42. //
  43. // These are the formats we will put in the save as list
  44. //
  45. static const GUID *g_pSupportedOutputFormats[] =
  46. {
  47. &WiaImgFmt_JPEG,
  48. &WiaImgFmt_BMP,
  49. &WiaImgFmt_TIFF,
  50. &WiaImgFmt_PNG
  51. };
  52. //
  53. // Sole constructor
  54. //
  55. CCommonTransferPage::CCommonTransferPage( HWND hWnd )
  56. : m_hWnd(hWnd),
  57. m_nWiaEventMessage(RegisterWindowMessage(STR_WIAEVENT_NOTIFICATION_MESSAGE)),
  58. m_pControllerWindow(NULL),
  59. m_bUseSubdirectory(true),
  60. m_hFontBold(NULL)
  61. {
  62. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::CCommonTransferPage")));
  63. }
  64. //
  65. // Destructor
  66. //
  67. CCommonTransferPage::~CCommonTransferPage(void)
  68. {
  69. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::~CCommonTransferPage")));
  70. m_hWnd = NULL;
  71. m_pControllerWindow = NULL;
  72. m_hFontBold = NULL;
  73. }
  74. LRESULT CCommonTransferPage::OnInitDialog( WPARAM, LPARAM lParam )
  75. {
  76. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::OnInitDialog")));
  77. //
  78. // Open the registry key where we store various things
  79. //
  80. CSimpleReg reg( HKEY_CURRENT_USER, REGSTR_PATH_USER_SETTINGS_WIAACMGR, false );
  81. //
  82. // Make sure this starts out NULL
  83. //
  84. m_pControllerWindow = NULL;
  85. //
  86. // Get the PROPSHEETPAGE.lParam
  87. //
  88. PROPSHEETPAGE *pPropSheetPage = reinterpret_cast<PROPSHEETPAGE*>(lParam);
  89. if (pPropSheetPage)
  90. {
  91. m_pControllerWindow = reinterpret_cast<CAcquisitionManagerControllerWindow*>(pPropSheetPage->lParam);
  92. if (m_pControllerWindow)
  93. {
  94. m_pControllerWindow->m_WindowList.Add(m_hWnd);
  95. }
  96. }
  97. //
  98. // Bail out
  99. //
  100. if (!m_pControllerWindow)
  101. {
  102. EndDialog(m_hWnd,IDCANCEL);
  103. return -1;
  104. }
  105. //
  106. // Get the right color-depth flag for this display
  107. //
  108. int nImageListColorDepth = PrintScanUtil::CalculateImageListColorDepth();
  109. //
  110. // Set the path control's image list
  111. //
  112. HIMAGELIST hDestImageList = ImageList_Create( SMALL_ICON_SIZE, SMALL_ICON_SIZE, nImageListColorDepth|ILC_MASK, 30, 10 );
  113. if (hDestImageList)
  114. {
  115. SendDlgItemMessage( m_hWnd, IDC_TRANSFER_DESTINATION, CBEM_SETIMAGELIST, 0, reinterpret_cast<LPARAM>(hDestImageList) );
  116. }
  117. //
  118. // Only create the file type image list if this control exists
  119. //
  120. if (GetDlgItem(m_hWnd,IDC_TRANSFER_IMAGETYPE))
  121. {
  122. //
  123. // Set the file type's image list
  124. //
  125. HIMAGELIST hFileTypeImageList = ImageList_Create( SMALL_ICON_SIZE, SMALL_ICON_SIZE, nImageListColorDepth|ILC_MASK, 3, 3 );
  126. if (hFileTypeImageList)
  127. {
  128. SendDlgItemMessage( m_hWnd, IDC_TRANSFER_IMAGETYPE, CBEM_SETIMAGELIST, 0, reinterpret_cast<LPARAM>(hFileTypeImageList) );
  129. }
  130. }
  131. //
  132. // Get the last selected type
  133. // Assume JPEG if nothing is defined
  134. //
  135. GUID guidResult;
  136. if (sizeof(GUID) == reg.QueryBin( REG_STR_LASTFORMAT, (PBYTE)&guidResult, sizeof(GUID) ))
  137. {
  138. m_guidLastSelectedType = guidResult;
  139. }
  140. else
  141. {
  142. m_guidLastSelectedType = WiaImgFmt_JPEG;
  143. }
  144. //
  145. // Add the file types if we are dealing with a scanner
  146. //
  147. if (m_pControllerWindow->m_DeviceTypeMode == CAcquisitionManagerControllerWindow::ScannerMode && m_pControllerWindow->m_pCurrentScannerItem)
  148. {
  149. PopulateSaveAsTypeList(m_pControllerWindow->m_pCurrentScannerItem->WiaItem());
  150. }
  151. //
  152. // Read the MRU lists from the registry
  153. //
  154. m_MruDirectory.Read( HKEY_CURRENT_USER, REGSTR_PATH_USER_SETTINGS_WIAACMGR, REG_STR_DIRNAME_MRU );
  155. m_MruRootFilename.Read( HKEY_CURRENT_USER, REGSTR_PATH_USER_SETTINGS_WIAACMGR, REG_STR_ROOTNAME_MRU );
  156. //
  157. // Make sure we have a default filename
  158. //
  159. if (m_MruRootFilename.Empty())
  160. {
  161. m_MruRootFilename.Add( CSimpleString( IDS_DEFAULT_BASE_NAME, g_hInstance ) );
  162. }
  163. //
  164. // Populate the rootname list
  165. //
  166. m_MruRootFilename.PopulateComboBox(GetDlgItem( m_hWnd, IDC_TRANSFER_ROOTNAME ));
  167. //
  168. // Ensure the first item in the rootname combobox is selected
  169. //
  170. SendDlgItemMessage( m_hWnd, IDC_TRANSFER_ROOTNAME, CB_SETCURSEL, 0, 0 );
  171. //
  172. // Make sure we have My Pictures+topic in the list, even if it has fallen off the end
  173. //
  174. CDestinationData DestDataMyPicturesTopic( CSIDL_MYPICTURES, CDestinationData::APPEND_TOPIC_TO_PATH );
  175. if (m_MruDirectory.Find(DestDataMyPicturesTopic) == m_MruDirectory.End())
  176. {
  177. m_MruDirectory.Append(DestDataMyPicturesTopic);
  178. }
  179. //
  180. // Make sure we have My Pictures+date+topic in the list, even if it has fallen off the end
  181. //
  182. CDestinationData DestDataMyPicturesDateTopic( CSIDL_MYPICTURES, CDestinationData::APPEND_DATE_TO_PATH|CDestinationData::APPEND_TOPIC_TO_PATH );
  183. if (m_MruDirectory.Find(DestDataMyPicturesDateTopic) == m_MruDirectory.End())
  184. {
  185. m_MruDirectory.Append(DestDataMyPicturesDateTopic);
  186. }
  187. //
  188. // Make sure we have My Pictures+date in the list, even if it has fallen off the end
  189. //
  190. CDestinationData DestDataMyPicturesDate( CSIDL_MYPICTURES, CDestinationData::APPEND_DATE_TO_PATH );
  191. if (m_MruDirectory.Find(DestDataMyPicturesDate) == m_MruDirectory.End())
  192. {
  193. m_MruDirectory.Append(DestDataMyPicturesDate);
  194. }
  195. //
  196. // Make sure we have My Pictures in the list, even if it has fallen off the end
  197. //
  198. CDestinationData DestDataMyPictures( CSIDL_MYPICTURES );
  199. if (m_MruDirectory.Find(DestDataMyPictures) == m_MruDirectory.End())
  200. {
  201. m_MruDirectory.Append(DestDataMyPictures);
  202. }
  203. //
  204. // Make sure we have Common Pictures in the list, even if it has fallen off the end
  205. //
  206. CDestinationData DestDataCommonPicturesTopic( CSIDL_COMMON_PICTURES );
  207. if (m_MruDirectory.Find(DestDataCommonPicturesTopic) == m_MruDirectory.End())
  208. {
  209. m_MruDirectory.Append(DestDataCommonPicturesTopic);
  210. }
  211. bool bCdBurnerAvailable = false;
  212. //
  213. // Try to instantiate the CD burner helper interface
  214. //
  215. CComPtr<ICDBurn> pCDBurn;
  216. HRESULT hr = CoCreateInstance( CLSID_CDBurn, NULL, CLSCTX_SERVER, IID_ICDBurn, (void**)&pCDBurn );
  217. if (SUCCEEDED(hr))
  218. {
  219. //
  220. // Get the drive letter of the available CD burner
  221. //
  222. WCHAR szDriveLetter[MAX_PATH];
  223. hr = pCDBurn->GetRecorderDriveLetter( szDriveLetter, ARRAYSIZE(szDriveLetter) );
  224. if (S_OK == hr && lstrlenW(szDriveLetter))
  225. {
  226. //
  227. // Make sure we have CD Burning in the list, even if it has fallen off the end
  228. //
  229. CDestinationData DestDataCDBurningArea( CSIDL_CDBURN_AREA );
  230. WIA_TRACE((TEXT("Adding DestDataCDBurningArea (%s)"),CSimpleIdList().GetSpecialFolder(m_hWnd,CSIDL_CDBURN_AREA).Name().String()));
  231. if (m_MruDirectory.Find(DestDataCDBurningArea) == m_MruDirectory.End())
  232. {
  233. m_MruDirectory.Append(DestDataCDBurningArea);
  234. }
  235. bCdBurnerAvailable = true;
  236. }
  237. else
  238. {
  239. WIA_PRINTHRESULT((hr,TEXT("pCDBurn->GetRecorderDriveLetter failed")));
  240. }
  241. }
  242. else
  243. {
  244. WIA_PRINTHRESULT((hr,TEXT("CoCreateInstance on CLSID_CDBurn failed")));
  245. }
  246. //
  247. // If there is no CD available, remove CD burner from the list
  248. //
  249. if (!bCdBurnerAvailable)
  250. {
  251. m_MruDirectory.Remove(CDestinationData( CSIDL_CDBURN_AREA ));
  252. }
  253. //
  254. // Populate the controls with the MRU data
  255. //
  256. PopulateDestinationList();
  257. //
  258. // Limit the length of the filename
  259. //
  260. SendDlgItemMessage( m_hWnd, IDC_TRANSFER_ROOTNAME, CB_LIMITTEXT, MAXIMUM_ALLOWED_FILENAME_LENGTH, 0 );
  261. //
  262. // Figure out where we are storing per-device-type data
  263. //
  264. LPTSTR pszStoreInSubDirectory, pszSubdirectoryDated;
  265. bool bDefaultUseSubdirectory;
  266. switch (m_pControllerWindow->m_DeviceTypeMode)
  267. {
  268. case CAcquisitionManagerControllerWindow::ScannerMode:
  269. //
  270. // Scanners
  271. //
  272. pszStoreInSubDirectory = REG_STR_STORE_IN_SUBDIRECTORY_SCANNER;
  273. pszSubdirectoryDated = REG_STR_SUBDIRECTORY_DATED_SCANNER;
  274. bDefaultUseSubdirectory = false;
  275. break;
  276. default:
  277. //
  278. // Cameras and video cameras
  279. //
  280. pszStoreInSubDirectory = REG_STR_STORE_IN_SUBDIRECTORY_CAMERA;
  281. pszSubdirectoryDated = REG_STR_SUBDIRECTORY_DATED_CAMERA;
  282. bDefaultUseSubdirectory = true;
  283. break;
  284. };
  285. UpdateDynamicPaths();
  286. //
  287. // Fix up the behavior of ComboBoxEx32s
  288. //
  289. WiaUiUtil::SubclassComboBoxEx( GetDlgItem( m_hWnd, IDC_TRANSFER_DESTINATION ) );
  290. WiaUiUtil::SubclassComboBoxEx( GetDlgItem( m_hWnd, IDC_TRANSFER_IMAGETYPE ) );
  291. //
  292. // Bold the number prompts
  293. //
  294. m_hFontBold = WiaUiUtil::CreateFontWithPointSizeFromWindow( GetDlgItem( m_hWnd, IDC_TRANSFER_1 ), 0, true, false );
  295. if (m_hFontBold)
  296. {
  297. SendDlgItemMessage( m_hWnd, IDC_TRANSFER_1, WM_SETFONT, reinterpret_cast<WPARAM>(m_hFontBold), FALSE );
  298. SendDlgItemMessage( m_hWnd, IDC_TRANSFER_2, WM_SETFONT, reinterpret_cast<WPARAM>(m_hFontBold), FALSE );
  299. SendDlgItemMessage( m_hWnd, IDC_TRANSFER_3, WM_SETFONT, reinterpret_cast<WPARAM>(m_hFontBold), FALSE );
  300. }
  301. //
  302. // Use the nifty balloon help to warn the user about invalid characters
  303. //
  304. CComPtr<IShellFolder> pShellFolder;
  305. hr = SHGetDesktopFolder( &pShellFolder );
  306. if (SUCCEEDED(hr))
  307. {
  308. SHLimitInputCombo( GetDlgItem( m_hWnd, IDC_TRANSFER_ROOTNAME ), pShellFolder );
  309. }
  310. return 0;
  311. }
  312. //
  313. // Validate a pathname and print a message if it is invalid
  314. //
  315. bool CCommonTransferPage::ValidatePathname( LPCTSTR pszPath )
  316. {
  317. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::ValidatePathname")));
  318. //
  319. // Check if the path is valid
  320. //
  321. if (!CAcquisitionManagerControllerWindow::DirectoryExists(pszPath))
  322. {
  323. //
  324. // Get the reason why it was invalid
  325. //
  326. DWORD dwLastError = GetLastError();
  327. WIA_PRINTHRESULT((HRESULT_FROM_WIN32(dwLastError),TEXT("error from DirectoryExists")));
  328. if (!CAcquisitionManagerControllerWindow::DirectoryExists(pszPath))
  329. {
  330. //
  331. // If it isn't valid, display a message box explaining why not
  332. //
  333. bool bRetry;
  334. switch (dwLastError)
  335. {
  336. case ERROR_NOT_READY:
  337. {
  338. bRetry = (CMessageBoxEx::IDMBEX_OK == CMessageBoxEx::MessageBox( m_hWnd, CSimpleString().Format( IDS_REPLACE_REMOVEABLE_MEDIA, g_hInstance, pszPath ), CSimpleString( IDS_ERROR_TITLE, g_hInstance ), CMessageBoxEx::MBEX_OKCANCEL|CMessageBoxEx::MBEX_ICONWARNING ));
  339. }
  340. break;
  341. default:
  342. {
  343. bRetry = (CMessageBoxEx::IDMBEX_YES == CMessageBoxEx::MessageBox( m_hWnd, CSimpleString().Format( IDS_COMTRANS_BAD_DIRECTORY, g_hInstance, pszPath ), CSimpleString( IDS_ERROR_TITLE, g_hInstance ), CMessageBoxEx::MBEX_YESNO|CMessageBoxEx::MBEX_ICONQUESTION ));
  344. }
  345. break;
  346. }
  347. if (bRetry)
  348. {
  349. //
  350. // Try to create the directory
  351. //
  352. CAcquisitionManagerControllerWindow::RecursiveCreateDirectory( pszPath );
  353. //
  354. // Check now if it exists
  355. //
  356. if (!CAcquisitionManagerControllerWindow::DirectoryExists(pszPath))
  357. {
  358. //
  359. // If it doesn't, give up
  360. //
  361. CMessageBoxEx::MessageBox( m_hWnd, CSimpleString().Format( IDS_COMTRANS_BAD_DIRECTORY_2ND_TRY, g_hInstance, pszPath ), CSimpleString( IDS_ERROR_TITLE, g_hInstance ), CMessageBoxEx::MBEX_OK|CMessageBoxEx::MBEX_ICONWARNING );
  362. return false;
  363. }
  364. }
  365. else return false;
  366. }
  367. }
  368. return true;
  369. }
  370. bool CCommonTransferPage::StorePathAndFilename(void)
  371. {
  372. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::StorePathAndFilename")));
  373. bool bResult = true;
  374. //
  375. // Get the base file name
  376. //
  377. CSimpleString strRootName;
  378. strRootName.GetWindowText( GetDlgItem( m_hWnd, IDC_TRANSFER_ROOTNAME ) );
  379. //
  380. // Store the base name
  381. //
  382. lstrcpyn( m_pControllerWindow->m_szRootFileName, strRootName, ARRAYSIZE(m_pControllerWindow->m_szRootFileName) );
  383. //
  384. // Store the currently selected path
  385. //
  386. GetCurrentDestinationFolder( true );
  387. return bResult;
  388. }
  389. //
  390. // We return an HWND in case of error, and the property sheet code will set the focus
  391. // to that control. If nothing bad happens, return NULL
  392. //
  393. HWND CCommonTransferPage::ValidatePathAndFilename(void)
  394. {
  395. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::ValidatePathAndFilename")));
  396. //
  397. // Get the base file name
  398. //
  399. CSimpleString strRootName;
  400. strRootName.GetWindowText( GetDlgItem( m_hWnd, IDC_TRANSFER_ROOTNAME ) );
  401. strRootName.Trim();
  402. //
  403. // Get the default base name if none was entered
  404. //
  405. if (!strRootName.Length())
  406. {
  407. //
  408. // Display a message box to the user telling them their lovely filename is invalid,
  409. // then set the focus on the combobox edit control and select the text in the control
  410. //
  411. CMessageBoxEx::MessageBox( m_hWnd, CSimpleString( IDS_EMPTYFILENAME, g_hInstance ), CSimpleString( IDS_ERROR_TITLE, g_hInstance ), CMessageBoxEx::MBEX_OK|CMessageBoxEx::MBEX_ICONWARNING );
  412. //
  413. // Return the window handle of the invalid control
  414. //
  415. return GetDlgItem( m_hWnd, IDC_TRANSFER_ROOTNAME );
  416. }
  417. if (ValidateFilename(strRootName))
  418. {
  419. //
  420. // Store the base name
  421. //
  422. lstrcpyn( m_pControllerWindow->m_szRootFileName, strRootName, ARRAYSIZE(m_pControllerWindow->m_szRootFileName) );
  423. //
  424. // Add this base filename to the filename MRU
  425. //
  426. m_MruRootFilename.Add(strRootName);
  427. //
  428. // If the string is already in the list, remove it
  429. //
  430. LRESULT lRes = SendDlgItemMessage( m_hWnd, IDC_TRANSFER_ROOTNAME, CB_FINDSTRINGEXACT, -1, reinterpret_cast<LPARAM>(strRootName.String() ));
  431. if (lRes != CB_ERR)
  432. {
  433. SendDlgItemMessage( m_hWnd, IDC_TRANSFER_ROOTNAME, CB_DELETESTRING, lRes, 0 );
  434. }
  435. //
  436. // Add the new string and make sure it is selected.
  437. //
  438. SendDlgItemMessage( m_hWnd, IDC_TRANSFER_ROOTNAME, CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(strRootName.String() ));
  439. SendDlgItemMessage( m_hWnd, IDC_TRANSFER_ROOTNAME, CB_SETCURSEL, 0, 0 );
  440. //
  441. // Get the currently selected path, and save it for the output code
  442. //
  443. CDestinationData *pDestinationData = GetCurrentDestinationFolder( true );
  444. if (pDestinationData)
  445. {
  446. //
  447. // Validate path. We don't validate special folders, because if they don't exist, we will create them.
  448. //
  449. if (!pDestinationData->IsSpecialFolder() && !ValidatePathname(m_pControllerWindow->m_szDestinationDirectory))
  450. {
  451. // Return the window handle of the invalid control
  452. return GetDlgItem( m_hWnd, IDC_TRANSFER_DESTINATION );
  453. }
  454. //
  455. // Save the current destination
  456. //
  457. m_pControllerWindow->m_CurrentDownloadDestination = *pDestinationData;
  458. }
  459. //
  460. // Make sure this is the first pDestinationData in the list next time
  461. // Store the destination MRU
  462. //
  463. if (pDestinationData)
  464. {
  465. m_MruDirectory.Add( *pDestinationData );
  466. PopulateDestinationList();
  467. }
  468. }
  469. else
  470. {
  471. //
  472. // Display a message box to the user telling them their lovely filename is invalid,
  473. // then set the focus on the combobox edit control and select the text in the control
  474. //
  475. CMessageBoxEx::MessageBox( m_hWnd, CSimpleString().Format( IDS_INVALIDFILENAME, g_hInstance, strRootName.String() ), CSimpleString( IDS_ERROR_TITLE, g_hInstance ), CMessageBoxEx::MBEX_OK|CMessageBoxEx::MBEX_ICONWARNING );
  476. //
  477. // Return the window handle of the invalid control
  478. //
  479. return GetDlgItem( m_hWnd, IDC_TRANSFER_ROOTNAME );
  480. }
  481. //
  482. // NULL means OK
  483. //
  484. return NULL;
  485. }
  486. LRESULT CCommonTransferPage::OnWizNext( WPARAM, LPARAM )
  487. {
  488. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::OnWizNext")));
  489. //
  490. // Make sure everything is OK. If it isn't, return the offending window handle to prevent closing the wizard.
  491. //
  492. HWND hWndFocus = ValidatePathAndFilename();
  493. if (hWndFocus)
  494. {
  495. SetFocus(hWndFocus);
  496. return -1;
  497. }
  498. //
  499. // Make sure there are selected images
  500. //
  501. if (!m_pControllerWindow || !m_pControllerWindow->GetSelectedImageCount())
  502. {
  503. CMessageBoxEx::MessageBox( m_hWnd, CSimpleString( IDS_NO_IMAGES_SELECTED, g_hInstance ), CSimpleString( IDS_ERROR_TITLE, g_hInstance ), CMessageBoxEx::MBEX_OK|CMessageBoxEx::MBEX_ICONINFORMATION );
  504. return -1;
  505. }
  506. //
  507. // Check the length of the generated filename, in case they chose a really deeply nested directory
  508. //
  509. int nPathLength = lstrlen(m_pControllerWindow->m_szDestinationDirectory) + // Directory
  510. lstrlen(m_pControllerWindow->m_szRootFileName) + // Filename
  511. CSimpleString().Format( IDS_NUMBER_MASK,g_hInstance, 0 ).Length() + // Number
  512. 5 + // Extension + dot
  513. 4 + // .tmp file
  514. 10; // Extra digits in number mask
  515. if (nPathLength >= MAX_PATH)
  516. {
  517. CMessageBoxEx::MessageBox( m_hWnd, CSimpleString( IDS_PATH_TOO_LONG, g_hInstance ), CSimpleString( IDS_ERROR_TITLE, g_hInstance ), CMessageBoxEx::MBEX_OK|CMessageBoxEx::MBEX_ICONINFORMATION );
  518. return reinterpret_cast<LRESULT>(GetDlgItem( m_hWnd, IDC_TRANSFER_DESTINATION ));
  519. }
  520. //
  521. // Store the information needed to do the download
  522. //
  523. GUID *pCurrFormat = GetCurrentOutputFormat();
  524. if (pCurrFormat)
  525. {
  526. m_pControllerWindow->m_guidOutputFormat = *pCurrFormat;
  527. }
  528. else
  529. {
  530. m_pControllerWindow->m_guidOutputFormat = IID_NULL;
  531. }
  532. //
  533. // Decide if we should delete the pictures after we download them
  534. //
  535. m_pControllerWindow->m_bDeletePicturesIfSuccessful = (SendDlgItemMessage( m_hWnd, IDC_TRANSFER_DELETEAFTERDOWNLOAD, BM_GETCHECK, 0, 0 )==BST_CHECKED);
  536. //
  537. // Prepare the name data we will be using for this transfer
  538. //
  539. m_pControllerWindow->m_DestinationNameData = PrepareNameDecorationData(false);
  540. //
  541. // Return
  542. //
  543. return 0;
  544. }
  545. //
  546. // handler for PSN_WIZBACK
  547. //
  548. LRESULT CCommonTransferPage::OnWizBack( WPARAM, LPARAM )
  549. {
  550. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::OnWizBack")));
  551. return 0;
  552. }
  553. CDestinationData::CNameData CCommonTransferPage::PrepareNameDecorationData( bool bUseCurrentSelection )
  554. {
  555. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::PrepareNameDecorationData")));
  556. CDestinationData::CNameData NameData;
  557. //
  558. // If bUseCurrentSelection is true, we need to use CB_GETLBTEXT, because we don't get a CBN_EDITCHANGE message
  559. // when the user changes the selection
  560. //
  561. if (bUseCurrentSelection)
  562. {
  563. //
  564. // Find the currently selected item
  565. //
  566. LRESULT nCurSel = SendDlgItemMessage( m_hWnd, IDC_TRANSFER_ROOTNAME, CB_GETCURSEL, 0, 0 );
  567. if (nCurSel != CB_ERR)
  568. {
  569. //
  570. // Figure out the length of this item
  571. //
  572. LRESULT nTextLen = SendDlgItemMessage( m_hWnd, IDC_TRANSFER_ROOTNAME, CB_GETLBTEXTLEN, nCurSel, 0 );
  573. if (CB_ERR != nTextLen)
  574. {
  575. //
  576. // Allocate enough space to hold the string
  577. //
  578. LPTSTR pszText = new TCHAR[nTextLen+1];
  579. if (pszText)
  580. {
  581. //
  582. // Get the string
  583. //
  584. if (CB_ERR != SendDlgItemMessage( m_hWnd, IDC_TRANSFER_ROOTNAME, CB_GETLBTEXT, nCurSel, reinterpret_cast<LPARAM>(pszText)))
  585. {
  586. //
  587. // Save the string
  588. //
  589. NameData.strTopic = pszText;
  590. }
  591. //
  592. // Free the string
  593. //
  594. delete[] pszText;
  595. }
  596. }
  597. }
  598. }
  599. //
  600. // If the topic string length is still zero, just get the window text from the edit control
  601. //
  602. if (!NameData.strTopic.Length())
  603. {
  604. NameData.strTopic.GetWindowText( GetDlgItem( m_hWnd, IDC_TRANSFER_ROOTNAME ) );
  605. }
  606. NameData.strDate = CAcquisitionManagerControllerWindow::GetCurrentDate();
  607. NameData.strDateAndTopic = CSimpleString().Format( IDS_DATEANDTOPIC, g_hInstance, NameData.strDate.String(), NameData.strTopic.String() );
  608. return NameData;
  609. }
  610. //
  611. // handler for PSN_SETACTIVE
  612. //
  613. LRESULT CCommonTransferPage::OnSetActive( WPARAM, LPARAM )
  614. {
  615. WIA_PUSHFUNCTION(TEXT("CCommonTransferPage::OnSetActive"));
  616. //
  617. // Make sure we have a valid controller window
  618. //
  619. if (!m_pControllerWindow)
  620. {
  621. return -1;
  622. }
  623. //
  624. // Put up a wait cursor. It can take a while to find out if any images can be deleted
  625. //
  626. CWaitCursor wc;
  627. //
  628. // Disable the delete button if none of the images can be deleted
  629. //
  630. if (!m_pControllerWindow->CanSomeSelectedImagesBeDeleted())
  631. {
  632. EnableWindow( GetDlgItem( m_hWnd, IDC_TRANSFER_DELETEAFTERDOWNLOAD ), FALSE );
  633. }
  634. else
  635. {
  636. EnableWindow( GetDlgItem( m_hWnd, IDC_TRANSFER_DELETEAFTERDOWNLOAD ), TRUE );
  637. }
  638. //
  639. // Clear the delete check box
  640. //
  641. SendDlgItemMessage( m_hWnd, IDC_TRANSFER_DELETEAFTERDOWNLOAD, BM_SETCHECK, BST_UNCHECKED, 0 );
  642. //
  643. // Allow next and back
  644. //
  645. PropSheet_SetWizButtons( GetParent(m_hWnd), PSWIZB_NEXT|PSWIZB_BACK );
  646. //
  647. // We do want to exit on disconnect if we are on this page
  648. //
  649. m_pControllerWindow->m_OnDisconnect = CAcquisitionManagerControllerWindow::OnDisconnectGotoLastpage|CAcquisitionManagerControllerWindow::OnDisconnectFailDownload|CAcquisitionManagerControllerWindow::OnDisconnectFailUpload|CAcquisitionManagerControllerWindow::OnDisconnectFailDelete;
  650. //
  651. // Make sure all of the strings fit
  652. //
  653. WiaUiUtil::ModifyComboBoxDropWidth(GetDlgItem( m_hWnd, IDC_TRANSFER_ROOTNAME ));
  654. //
  655. // Make sure the paths are updated
  656. //
  657. UpdateDynamicPaths();
  658. return 0;
  659. }
  660. void CCommonTransferPage::PopulateSaveAsTypeList( IWiaItem *pWiaItem )
  661. {
  662. WIA_PUSHFUNCTION(TEXT("CCommonTransferPage::PopulateSaveAsTypeList"));
  663. //
  664. // Get the list control
  665. //
  666. HWND hWndList = GetDlgItem( m_hWnd, IDC_TRANSFER_IMAGETYPE );
  667. if (hWndList)
  668. {
  669. //
  670. // Clear the combo box
  671. //
  672. SendMessage( hWndList, CB_RESETCONTENT, 0, 0 );
  673. //
  674. // Get the list control's image list
  675. //
  676. HIMAGELIST hComboBoxExImageList = reinterpret_cast<HIMAGELIST>(SendMessage( hWndList, CBEM_GETIMAGELIST, 0, 0 ));
  677. if (hComboBoxExImageList)
  678. {
  679. //
  680. // Get the default icon, in case we run into an unknown type
  681. //
  682. HICON hDefaultImageTypeIcon = reinterpret_cast<HICON>(LoadImage( g_hInstance, MAKEINTRESOURCE(IDI_DEFTYPE), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR ));
  683. //
  684. // Get the GDI Plus types we can convert to
  685. //
  686. CWiaFileFormatList GdiPlusFileFormatList(g_pSupportedOutputFormats,ARRAYSIZE(g_pSupportedOutputFormats), hDefaultImageTypeIcon );
  687. //
  688. // Debug output
  689. //
  690. GdiPlusFileFormatList.Dump();
  691. //
  692. // Get the formats this object supports directly
  693. //
  694. CWiaFileFormatList WiaItemFileFormatList( pWiaItem, hDefaultImageTypeIcon );
  695. //
  696. // Debug output
  697. //
  698. WiaItemFileFormatList.Dump();
  699. //
  700. // Merge the GDI+ and native format lists
  701. //
  702. WiaItemFileFormatList.Union(GdiPlusFileFormatList);
  703. //
  704. // Loop through the merged list of formats and add each one to the list
  705. //
  706. for (int i=0;i<WiaItemFileFormatList.FormatList().Size();i++)
  707. {
  708. //
  709. // Make sure we have a valid format
  710. //
  711. if (WiaItemFileFormatList.FormatList()[i].IsValid() && WiaItemFileFormatList.FormatList()[i].Icon())
  712. {
  713. //
  714. // Add the icon to the image list
  715. //
  716. int nIconIndex = ImageList_AddIcon( hComboBoxExImageList, WiaItemFileFormatList.FormatList()[i].Icon() );
  717. //
  718. // Get the description string. Like "BMP File"
  719. //
  720. CSimpleString strFormatDescription = WiaItemFileFormatList.FormatList()[i].Description();
  721. //
  722. // If we didn't get a description string, make one
  723. //
  724. if (!strFormatDescription.Length())
  725. {
  726. strFormatDescription.Format( IDS_BLANKFILETYPENAME, g_hInstance, WiaItemFileFormatList.FormatList()[i].Extension().ToUpper().String() );
  727. }
  728. //
  729. // Create the full string description, like "BMP (BMP File)"
  730. //
  731. CSimpleString strFormatName;
  732. strFormatName.Format( IDS_FILETYPE, g_hInstance, WiaItemFileFormatList.FormatList()[i].Extension().ToUpper().String(), strFormatDescription.String() );
  733. //
  734. // If we have a valid name
  735. //
  736. if (strFormatName.Length())
  737. {
  738. //
  739. // Allocate a GUID to store the guid in as an LPARAM
  740. //
  741. GUID *pGuid = new GUID;
  742. if (pGuid)
  743. {
  744. //
  745. // Save the GUID
  746. //
  747. *pGuid = WiaItemFileFormatList.FormatList()[i].Format();
  748. //
  749. // Get the cbex item ready for an insert (really an append)
  750. //
  751. COMBOBOXEXITEM cbex = {0};
  752. ZeroMemory( &cbex, sizeof(cbex) );
  753. cbex.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_LPARAM;
  754. cbex.iItem = -1;
  755. cbex.pszText = const_cast<LPTSTR>(strFormatName.String());
  756. cbex.iImage = nIconIndex;
  757. cbex.iSelectedImage = nIconIndex;
  758. cbex.lParam = reinterpret_cast<LPARAM>(pGuid);
  759. //
  760. // Insert the item
  761. //
  762. SendMessage( hWndList, CBEM_INSERTITEM, 0, reinterpret_cast<LPARAM>(&cbex) );
  763. }
  764. }
  765. }
  766. }
  767. if (hDefaultImageTypeIcon)
  768. {
  769. DestroyIcon(hDefaultImageTypeIcon);
  770. }
  771. }
  772. //
  773. // Now set the current selection to the last selected type
  774. //
  775. int nSelectedItem = 0;
  776. //
  777. // Search the combo box for a match for this type
  778. //
  779. for (int i=0;i<SendMessage(hWndList,CB_GETCOUNT,0,0);i++)
  780. {
  781. //
  782. // Get an item from the combo box
  783. //
  784. COMBOBOXEXITEM ComboBoxExItem = {0};
  785. ComboBoxExItem.iItem = i;
  786. ComboBoxExItem.mask = CBEIF_LPARAM;
  787. if (SendMessage( hWndList, CBEM_GETITEM, 0, reinterpret_cast<LPARAM>(&ComboBoxExItem)))
  788. {
  789. //
  790. // Compare its guid with the MRU type
  791. //
  792. GUID *pGuid = reinterpret_cast<GUID*>(ComboBoxExItem.lParam);
  793. if (pGuid && *pGuid == m_guidLastSelectedType)
  794. {
  795. //
  796. // Save the index and exit the loop
  797. //
  798. nSelectedItem = i;
  799. break;
  800. }
  801. }
  802. }
  803. //
  804. // Set the current selection
  805. //
  806. SendMessage(hWndList,CB_SETCURSEL,nSelectedItem,0);
  807. //
  808. // Make sure all of the strings fit
  809. //
  810. WiaUiUtil::ModifyComboBoxDropWidth(hWndList);
  811. }
  812. }
  813. GUID *CCommonTransferPage::GetCurrentOutputFormat(void)
  814. {
  815. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::GetCurrentOutputFormat")));
  816. HWND hWndList = GetDlgItem( m_hWnd, IDC_TRANSFER_IMAGETYPE );
  817. if (hWndList)
  818. {
  819. LRESULT lResult = SendMessage( hWndList, CB_GETCURSEL, 0, 0 );
  820. if (lResult != CB_ERR)
  821. {
  822. COMBOBOXEXITEM ComboBoxExItem;
  823. ZeroMemory( &ComboBoxExItem, sizeof(ComboBoxExItem) );
  824. ComboBoxExItem.mask = CBEIF_LPARAM;
  825. ComboBoxExItem.iItem = lResult;
  826. lResult = SendMessage( hWndList, CBEM_GETITEM, 0, reinterpret_cast<LPARAM>(&ComboBoxExItem) );
  827. if (lResult && ComboBoxExItem.lParam)
  828. {
  829. //
  830. // There's a GUID
  831. //
  832. return reinterpret_cast<GUID*>(ComboBoxExItem.lParam);
  833. }
  834. }
  835. }
  836. return NULL;
  837. }
  838. LRESULT CCommonTransferPage::OnDestroy( WPARAM, LPARAM )
  839. {
  840. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::OnDestroy")));
  841. //
  842. // Save the MRU lists to the registry
  843. //
  844. m_MruDirectory.Write( HKEY_CURRENT_USER, REGSTR_PATH_USER_SETTINGS_WIAACMGR, REG_STR_DIRNAME_MRU );
  845. m_MruRootFilename.Write( HKEY_CURRENT_USER, REGSTR_PATH_USER_SETTINGS_WIAACMGR, REG_STR_ROOTNAME_MRU );
  846. //
  847. // Save page settings
  848. //
  849. CSimpleReg reg( HKEY_CURRENT_USER, REGSTR_PATH_USER_SETTINGS_WIAACMGR, true, KEY_WRITE );
  850. //
  851. // Save current format
  852. //
  853. GUID *pCurrFormat = GetCurrentOutputFormat();
  854. if (pCurrFormat)
  855. {
  856. reg.SetBin( REG_STR_LASTFORMAT, (PBYTE)pCurrFormat, sizeof(GUID), REG_BINARY );
  857. }
  858. //
  859. // Destroy the image lists
  860. //
  861. HIMAGELIST hImageList = reinterpret_cast<HIMAGELIST>(SendDlgItemMessage( m_hWnd, IDC_TRANSFER_DESTINATION, CBEM_SETIMAGELIST, 0, NULL ));
  862. if (hImageList)
  863. {
  864. ImageList_Destroy(hImageList);
  865. }
  866. if (GetDlgItem(m_hWnd,IDC_TRANSFER_IMAGETYPE))
  867. {
  868. hImageList = reinterpret_cast<HIMAGELIST>(SendDlgItemMessage( m_hWnd, IDC_TRANSFER_IMAGETYPE, CBEM_SETIMAGELIST, 0, NULL ));
  869. if (hImageList)
  870. {
  871. ImageList_Destroy(hImageList);
  872. }
  873. }
  874. if (m_hFontBold)
  875. {
  876. DeleteFont(m_hFontBold);
  877. m_hFontBold = NULL;
  878. }
  879. return 0;
  880. }
  881. CSimpleString CCommonTransferPage::GetFolderName( LPCITEMIDLIST pidl )
  882. {
  883. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::GetFolderName")));
  884. if (!pidl)
  885. {
  886. return CSimpleString(TEXT(""));
  887. }
  888. if (CSimpleIdList().GetSpecialFolder( NULL, CSIDL_MYPICTURES|CSIDL_FLAG_CREATE ) == pidl)
  889. {
  890. SHFILEINFO shfi;
  891. ZeroMemory( &shfi, sizeof(shfi) );
  892. if (SHGetFileInfo( reinterpret_cast<LPCTSTR>(pidl), 0, &shfi, sizeof(shfi), SHGFI_PIDL | SHGFI_DISPLAYNAME ))
  893. {
  894. return(shfi.szDisplayName);
  895. }
  896. }
  897. else if (CSimpleIdList().GetSpecialFolder( NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE ) == pidl)
  898. {
  899. SHFILEINFO shfi;
  900. ZeroMemory( &shfi, sizeof(shfi) );
  901. if (SHGetFileInfo( reinterpret_cast<LPCTSTR>(pidl), 0, &shfi, sizeof(shfi), SHGFI_PIDL | SHGFI_DISPLAYNAME ))
  902. {
  903. return(shfi.szDisplayName);
  904. }
  905. }
  906. TCHAR szPath[MAX_PATH];
  907. if (SHGetPathFromIDList( pidl, szPath ))
  908. {
  909. return(szPath);
  910. }
  911. return(CSimpleString(TEXT("")));
  912. }
  913. LRESULT CCommonTransferPage::AddPathToComboBoxExOrListView( HWND hWnd, CDestinationData &Path, bool bComboBoxEx )
  914. {
  915. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::AddPathToComboBoxExOrListView")));
  916. if (!IsWindow(hWnd))
  917. {
  918. return(-1);
  919. }
  920. if (Path.IsValid())
  921. {
  922. //
  923. // Make sure this path can be used in a folder name
  924. //
  925. if (Path.IsValidFileSystemPath(PrepareNameDecorationData()))
  926. {
  927. //
  928. // Get the name of the folder
  929. //
  930. CSimpleString strName = Path.DisplayName(PrepareNameDecorationData());
  931. if (!strName.Length())
  932. {
  933. return(CB_ERR);
  934. }
  935. //
  936. // Get the combobox's image list and add the shell's icon to it.
  937. //
  938. int nIconIndex = 0;
  939. HICON hIcon = Path.SmallIcon();
  940. if (hIcon)
  941. {
  942. if (bComboBoxEx)
  943. {
  944. HIMAGELIST hImageList = reinterpret_cast<HIMAGELIST>(SendMessage( hWnd, CBEM_GETIMAGELIST, 0, 0 ));
  945. if (hImageList)
  946. {
  947. nIconIndex = ImageList_AddIcon( hImageList, hIcon );
  948. }
  949. }
  950. else
  951. {
  952. HIMAGELIST hImageList = reinterpret_cast<HIMAGELIST>(SendMessage( hWnd, LVM_GETIMAGELIST, LVSIL_SMALL, 0 ));
  953. if (hImageList)
  954. {
  955. nIconIndex = ImageList_AddIcon( hImageList, hIcon );
  956. }
  957. }
  958. }
  959. //
  960. // If it already exists, don't add it
  961. //
  962. if (bComboBoxEx)
  963. {
  964. LRESULT nFind = SendMessage( hWnd, CB_FINDSTRINGEXACT, 0, reinterpret_cast<LPARAM>(strName.String()));
  965. if (nFind != CB_ERR)
  966. {
  967. return(nFind);
  968. }
  969. }
  970. if (bComboBoxEx)
  971. {
  972. //
  973. // Prepare the cbex struct
  974. //
  975. COMBOBOXEXITEM cbex = {0};
  976. cbex.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_LPARAM;
  977. cbex.iItem = -1;
  978. cbex.pszText = const_cast<LPTSTR>(strName.String());
  979. cbex.iImage = nIconIndex;
  980. cbex.iSelectedImage = nIconIndex;
  981. cbex.lParam = reinterpret_cast<LPARAM>(&Path);
  982. //
  983. // Add the item
  984. //
  985. LRESULT lRes = SendMessage( hWnd, CBEM_INSERTITEM, 0, reinterpret_cast<LPARAM>(&cbex) );
  986. //
  987. // Make sure all of the strings fit
  988. //
  989. WiaUiUtil::ModifyComboBoxDropWidth(hWnd);
  990. return lRes;
  991. }
  992. else
  993. {
  994. LVITEM lvItem = {0};
  995. lvItem.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
  996. lvItem.iItem = 0;
  997. lvItem.pszText = const_cast<LPTSTR>(strName.String());
  998. lvItem.iImage = nIconIndex;
  999. lvItem.lParam = reinterpret_cast<LPARAM>(&Path);
  1000. //
  1001. // Add the item
  1002. //
  1003. return SendMessage( hWnd, LVM_INSERTITEM, 0, reinterpret_cast<LPARAM>(&lvItem) );
  1004. }
  1005. }
  1006. }
  1007. return -1;
  1008. }
  1009. /*****************************************************************************
  1010. PopulateDestinationList
  1011. Fills in the destinatin drop down list w/the info from the MRU
  1012. saved in the registry.
  1013. *****************************************************************************/
  1014. void CCommonTransferPage::PopulateDestinationList(void)
  1015. {
  1016. WIA_PUSHFUNCTION((TEXT("CCommonTransferPage::PopulateDestinationList")));
  1017. //
  1018. // Empty the list controls
  1019. //
  1020. SendDlgItemMessage( m_hWnd, IDC_TRANSFER_DESTINATION, CB_RESETCONTENT, 0, 0 );
  1021. //
  1022. // Remove all of the images from the image list
  1023. //
  1024. HIMAGELIST hImageList = reinterpret_cast<HIMAGELIST>(SendDlgItemMessage( m_hWnd,IDC_TRANSFER_DESTINATION, CBEM_GETIMAGELIST, 0, 0 ));
  1025. if (hImageList)
  1026. {
  1027. ImageList_RemoveAll(hImageList);
  1028. }
  1029. //
  1030. // Add all of the paths in the MRU list. Dupes will be ignored.
  1031. //
  1032. CMruDestinationData::Iterator ListIter = m_MruDirectory.Begin();
  1033. while (ListIter != m_MruDirectory.End())
  1034. {
  1035. AddPathToComboBoxExOrListView( GetDlgItem(m_hWnd,IDC_TRANSFER_DESTINATION), *ListIter, true );
  1036. ++ListIter;
  1037. }
  1038. //
  1039. // Set the current selection to item 0, since the MRU should have taken care of ordering
  1040. //
  1041. SendDlgItemMessage( m_hWnd, IDC_TRANSFER_DESTINATION, CB_SETCURSEL, 0, 0 );
  1042. WiaUiUtil::ModifyComboBoxDropWidth(GetDlgItem(m_hWnd,IDC_TRANSFER_DESTINATION));
  1043. }
  1044. /*****************************************************************************
  1045. GetCurrentDestinationFolder
  1046. Given a handle to the dialog, return the path to the directory that
  1047. the user has selected.
  1048. pszPath is assumed to point to a MAX_PATH (or greater) character buffer
  1049. Pass a NULL pszPath to get just the pidl
  1050. *****************************************************************************/
  1051. CDestinationData *CCommonTransferPage::GetCurrentDestinationFolder( bool bStore )
  1052. {
  1053. WIA_PUSHFUNCTION((TEXT("CCommonTransferPage::GetCurrentDestinationFolder")));
  1054. //
  1055. // Assume failure
  1056. //
  1057. CDestinationData *pResult = NULL;
  1058. //
  1059. // Saving to a folder?
  1060. //
  1061. LRESULT lResult = SendDlgItemMessage( m_hWnd, IDC_TRANSFER_DESTINATION, CB_GETCURSEL, 0, 0 );
  1062. if (lResult != CB_ERR)
  1063. {
  1064. //
  1065. // Get the item
  1066. //
  1067. COMBOBOXEXITEM ComboBoxExItem = {0};
  1068. ComboBoxExItem.mask = CBEIF_LPARAM;
  1069. ComboBoxExItem.iItem = lResult;
  1070. lResult = SendDlgItemMessage( m_hWnd, IDC_TRANSFER_DESTINATION, CBEM_GETITEM, 0, reinterpret_cast<LPARAM>(&ComboBoxExItem) );
  1071. //
  1072. // If this message succeeded, and it has an lParam
  1073. //
  1074. if (lResult && ComboBoxExItem.lParam)
  1075. {
  1076. //
  1077. // Get the data
  1078. //
  1079. pResult = reinterpret_cast<CDestinationData*>(ComboBoxExItem.lParam);
  1080. }
  1081. }
  1082. if (pResult)
  1083. {
  1084. //
  1085. // If this is an idlist, set the path and return an idlist
  1086. //
  1087. if (bStore && m_pControllerWindow)
  1088. {
  1089. //
  1090. // Get the pathname, if requested
  1091. //
  1092. CSimpleString strPath = pResult->Path(PrepareNameDecorationData());
  1093. if (strPath.Length())
  1094. {
  1095. lstrcpyn( m_pControllerWindow->m_szDestinationDirectory, strPath, MAX_PATH );
  1096. }
  1097. }
  1098. }
  1099. return pResult;
  1100. }
  1101. bool CCommonTransferPage::ValidateFilename( LPCTSTR pszFilename )
  1102. {
  1103. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::ValidateFilename")));
  1104. //
  1105. // if the filename is NULL or empty, it is invalid
  1106. //
  1107. if (!pszFilename || !*pszFilename)
  1108. {
  1109. return false;
  1110. }
  1111. for (LPCTSTR pszCurr = pszFilename;*pszCurr;pszCurr=CharNext(pszCurr))
  1112. {
  1113. if (*pszCurr == TEXT(':') ||
  1114. *pszCurr == TEXT('\\') ||
  1115. *pszCurr == TEXT('/') ||
  1116. *pszCurr == TEXT('?') ||
  1117. *pszCurr == TEXT('"') ||
  1118. *pszCurr == TEXT('<') ||
  1119. *pszCurr == TEXT('>') ||
  1120. *pszCurr == TEXT('|') ||
  1121. *pszCurr == TEXT('*'))
  1122. {
  1123. return false;
  1124. }
  1125. }
  1126. return true;
  1127. }
  1128. int CALLBACK CCommonTransferPage::BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData )
  1129. {
  1130. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::BrowseCallbackProc")));
  1131. if (BFFM_INITIALIZED == uMsg && lpData)
  1132. {
  1133. SendMessage( hWnd, BFFM_SETSELECTION, FALSE, lpData );
  1134. WIA_TRACE((TEXT("CSimpleIdList(reinterpret_cast<LPITEMIDLIST>(lpData)).Name().String(): %s"), CSimpleIdList(reinterpret_cast<LPITEMIDLIST>(lpData)).Name().String() ));
  1135. }
  1136. return(0);
  1137. }
  1138. void CCommonTransferPage::OnBrowseDestination( WPARAM, LPARAM )
  1139. {
  1140. WIA_PUSHFUNCTION((TEXT("CCommonTransferPage::OnBrowseDestination")));
  1141. TCHAR szDisplay[MAX_PATH];
  1142. //
  1143. // Get the initial ID list
  1144. //
  1145. CSimpleIdList InitialIdList;
  1146. CDestinationData *pResult = GetCurrentDestinationFolder( false );
  1147. if (pResult)
  1148. {
  1149. CSimpleIdList InitialIdList;
  1150. if (pResult->IsSpecialFolder())
  1151. {
  1152. InitialIdList.GetSpecialFolder( m_hWnd, pResult->Csidl() );
  1153. }
  1154. else
  1155. {
  1156. InitialIdList = pResult->IdList();
  1157. }
  1158. //
  1159. // Load the title string
  1160. //
  1161. CSimpleString strBrowseTitle( IDS_BROWSE_TITLE, g_hInstance );
  1162. //
  1163. // Prepare the folder browsing structure
  1164. //
  1165. BROWSEINFO BrowseInfo;
  1166. ZeroMemory( &BrowseInfo, sizeof(BrowseInfo) );
  1167. BrowseInfo.hwndOwner = m_hWnd;
  1168. BrowseInfo.pidlRoot = NULL;
  1169. BrowseInfo.pszDisplayName = szDisplay;
  1170. BrowseInfo.lpszTitle = const_cast<LPTSTR>(strBrowseTitle.String());
  1171. BrowseInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_EDITBOX;
  1172. BrowseInfo.lParam = reinterpret_cast<LPARAM>(InitialIdList.IdList());
  1173. BrowseInfo.lpfn = BrowseCallbackProc;
  1174. //
  1175. // Open the folder browser
  1176. //
  1177. LPITEMIDLIST pidl = SHBrowseForFolder( &BrowseInfo );
  1178. if (pidl)
  1179. {
  1180. //
  1181. // Create a destination data for this PIDL
  1182. //
  1183. CDestinationData DestinationData(pidl);
  1184. if (DestinationData.IsValid())
  1185. {
  1186. //
  1187. // Add this pidl to the directory mru
  1188. //
  1189. m_MruDirectory.Add( DestinationData );
  1190. //
  1191. // Add this pidl to the destination list too, by repopulating the list
  1192. //
  1193. PopulateDestinationList();
  1194. }
  1195. //
  1196. // Free pidl
  1197. //
  1198. LPMALLOC pMalloc = NULL;
  1199. if (SUCCEEDED(SHGetMalloc(&pMalloc)) && pMalloc)
  1200. {
  1201. pMalloc->Free(pidl);
  1202. pMalloc->Release();
  1203. }
  1204. }
  1205. }
  1206. }
  1207. void CCommonTransferPage::UpdateDynamicPaths( bool bSelectionChanged )
  1208. {
  1209. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::UpdateDynamicPaths")));
  1210. CDestinationData::CNameData NameData = PrepareNameDecorationData( bSelectionChanged != false );
  1211. //
  1212. // Get the current selection
  1213. //
  1214. LRESULT nCurSel = SendDlgItemMessage( m_hWnd, IDC_TRANSFER_DESTINATION, CB_GETCURSEL, 0, 0 );
  1215. //
  1216. // We will only redraw if a dynamic item is selected
  1217. //
  1218. bool bRedrawNeeded = false;
  1219. //
  1220. // Loop through all of the items in the list
  1221. //
  1222. LRESULT nCount = SendDlgItemMessage( m_hWnd, IDC_TRANSFER_DESTINATION, CB_GETCOUNT, 0, 0 );
  1223. for (LRESULT i=0;i<nCount;i++)
  1224. {
  1225. //
  1226. // Get the item
  1227. //
  1228. COMBOBOXEXITEM ComboBoxExItem = {0};
  1229. ComboBoxExItem.mask = CBEIF_LPARAM;
  1230. ComboBoxExItem.iItem = i;
  1231. LRESULT lResult = SendDlgItemMessage( m_hWnd, IDC_TRANSFER_DESTINATION, CBEM_GETITEM, 0, reinterpret_cast<LPARAM>(&ComboBoxExItem) );
  1232. //
  1233. // If this message succeeded, and it has an lParam
  1234. //
  1235. if (lResult && ComboBoxExItem.lParam)
  1236. {
  1237. //
  1238. // Get the data
  1239. //
  1240. CDestinationData *pDestinationData = reinterpret_cast<CDestinationData*>(ComboBoxExItem.lParam);
  1241. //
  1242. // If this item has any dynamic decorations
  1243. //
  1244. if (pDestinationData && (pDestinationData->Flags() & CDestinationData::DECORATION_MASK))
  1245. {
  1246. //
  1247. // Get the display name for this item.
  1248. //
  1249. CSimpleString strDisplayName = pDestinationData->DisplayName( NameData );
  1250. //
  1251. // Make sure we have a valid display name
  1252. //
  1253. if (strDisplayName.Length())
  1254. {
  1255. //
  1256. // Set the data
  1257. //
  1258. COMBOBOXEXITEM ComboBoxExItem = {0};
  1259. ComboBoxExItem.mask = CBEIF_TEXT;
  1260. ComboBoxExItem.iItem = i;
  1261. ComboBoxExItem.pszText = const_cast<LPTSTR>(strDisplayName.String());
  1262. SendDlgItemMessage( m_hWnd, IDC_TRANSFER_DESTINATION, CBEM_SETITEM, 0, reinterpret_cast<LPARAM>(&ComboBoxExItem) );
  1263. //
  1264. // If this item is currently selected, force a redraw
  1265. //
  1266. if (nCurSel == i)
  1267. {
  1268. bRedrawNeeded = true;
  1269. }
  1270. }
  1271. }
  1272. }
  1273. }
  1274. //
  1275. // Update the control, if necessary
  1276. //
  1277. if (bRedrawNeeded)
  1278. {
  1279. InvalidateRect( GetDlgItem( m_hWnd, IDC_TRANSFER_DESTINATION ), NULL, FALSE );
  1280. }
  1281. }
  1282. void CCommonTransferPage::OnRootNameChange( WPARAM wParam, LPARAM )
  1283. {
  1284. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::OnRootNameChange")));
  1285. UpdateDynamicPaths(HIWORD(wParam) == CBN_SELCHANGE);
  1286. }
  1287. LRESULT CCommonTransferPage::OnImageTypeDeleteItem( WPARAM, LPARAM lParam )
  1288. {
  1289. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::OnImageTypeDeleteItem")));
  1290. PNMCOMBOBOXEX pNmComboBoxEx = reinterpret_cast<PNMCOMBOBOXEX>(lParam);
  1291. if (pNmComboBoxEx)
  1292. {
  1293. GUID *pGuid = reinterpret_cast<GUID*>(pNmComboBoxEx->ceItem.lParam);
  1294. if (pGuid)
  1295. {
  1296. delete pGuid;
  1297. }
  1298. }
  1299. return 0;
  1300. }
  1301. LRESULT CCommonTransferPage::OnEventNotification( WPARAM, LPARAM lParam )
  1302. {
  1303. WIA_PUSH_FUNCTION((TEXT("CCommonTransferPage::OnEventNotification") ));
  1304. CGenericWiaEventHandler::CEventMessage *pEventMessage = reinterpret_cast<CGenericWiaEventHandler::CEventMessage *>(lParam);
  1305. if (pEventMessage)
  1306. {
  1307. //
  1308. // Don't delete the message, it is deleted in the controller window
  1309. //
  1310. }
  1311. return 0;
  1312. }
  1313. LRESULT CCommonTransferPage::OnCommand( WPARAM wParam, LPARAM lParam )
  1314. {
  1315. SC_BEGIN_COMMAND_HANDLERS()
  1316. {
  1317. SC_HANDLE_COMMAND( IDC_TRANSFER_BROWSE, OnBrowseDestination );
  1318. SC_HANDLE_COMMAND_NOTIFY(CBN_EDITCHANGE,IDC_TRANSFER_ROOTNAME,OnRootNameChange);
  1319. SC_HANDLE_COMMAND_NOTIFY(CBN_SELCHANGE,IDC_TRANSFER_ROOTNAME,OnRootNameChange);
  1320. }
  1321. SC_END_COMMAND_HANDLERS();
  1322. }
  1323. LRESULT CCommonTransferPage::OnNotify( WPARAM wParam, LPARAM lParam )
  1324. {
  1325. SC_BEGIN_NOTIFY_MESSAGE_HANDLERS()
  1326. {
  1327. SC_HANDLE_NOTIFY_MESSAGE_CODE(PSN_WIZBACK,OnWizBack);
  1328. SC_HANDLE_NOTIFY_MESSAGE_CODE(PSN_WIZNEXT,OnWizNext);
  1329. SC_HANDLE_NOTIFY_MESSAGE_CODE(PSN_SETACTIVE,OnSetActive);
  1330. SC_HANDLE_NOTIFY_MESSAGE_CONTROL(CBEN_DELETEITEM,IDC_TRANSFER_IMAGETYPE,OnImageTypeDeleteItem);
  1331. }
  1332. SC_END_NOTIFY_MESSAGE_HANDLERS();
  1333. }
  1334. INT_PTR CALLBACK CCommonTransferPage::DialogProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  1335. {
  1336. SC_BEGIN_DIALOG_MESSAGE_HANDLERS(CCommonTransferPage)
  1337. {
  1338. SC_HANDLE_DIALOG_MESSAGE( WM_INITDIALOG, OnInitDialog );
  1339. SC_HANDLE_DIALOG_MESSAGE( WM_COMMAND, OnCommand );
  1340. SC_HANDLE_DIALOG_MESSAGE( WM_DESTROY, OnDestroy );
  1341. SC_HANDLE_DIALOG_MESSAGE( WM_NOTIFY, OnNotify );
  1342. }
  1343. SC_END_DIALOG_MESSAGE_HANDLERS();
  1344. }