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.

365 lines
8.8 KiB

  1. // ImageDoc.cpp : implementation of the CImageDoc class
  2. //
  3. #include "stdafx.h"
  4. #include "shimgvwr.h"
  5. #include "ImageDoc.h"
  6. #include "imageview.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. extern CPreviewApp theApp;
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CImageDoc
  15. IMPLEMENT_DYNCREATE(CImageDoc, CDocument)
  16. BEGIN_MESSAGE_MAP(CImageDoc, CDocument)
  17. //{{AFX_MSG_MAP(CImageDoc)
  18. ON_COMMAND(ID_FILE_SCAN, OnFileScan)
  19. ON_COMMAND(ID_FILE_PROPERTIES, OnFileProperties)
  20. ON_COMMAND(ID_FILE_SEND_MAIL, OnFileSendMail)
  21. ON_COMMAND(ID_FILE_PAPER_TILE, OnFilePaperTile)
  22. ON_COMMAND(ID_FILE_PAPER_CENTER, OnFilePaperCenter)
  23. ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
  24. ON_UPDATE_COMMAND_UI(ID_FILE_SCAN, OnUpdateFileScan)
  25. // these items are enabled if the current file is not a temp file
  26. ON_UPDATE_COMMAND_UI(ID_FILE_PROPERTIES, OnUpdateFileMenu)
  27. ON_UPDATE_COMMAND_UI(ID_FILE_SEND_MAIL, OnUpdateFileMenu)
  28. ON_UPDATE_COMMAND_UI(ID_FILE_PAPER_TILE, OnUpdateFileMenu)
  29. ON_UPDATE_COMMAND_UI(ID_FILE_PAPER_CENTER, OnUpdateFileMenu)
  30. // NOTE - the ClassWizard will add and remove mapping macros here.
  31. // DO NOT EDIT what you see in these blocks of generated code!
  32. //}}AFX_MSG_MAP
  33. END_MESSAGE_MAP()
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CImageDoc construction/destruction
  36. CImageDoc::CImageDoc()
  37. {
  38. m_bUseTempPath = false;
  39. }
  40. CImageDoc::~CImageDoc()
  41. {
  42. DelTempFile ();
  43. }
  44. BOOL CImageDoc::OnNewDocument()
  45. {
  46. if (!CDocument::OnNewDocument())
  47. return FALSE;
  48. DelTempFile ();
  49. return TRUE;
  50. }
  51. void MySplitPath (const TCHAR *szPath, TCHAR *szDrive, TCHAR *szDir, TCHAR *szName, TCHAR *szExt)
  52. {
  53. // Found this in tchar.h
  54. _tsplitpath (szPath, szDrive, szDir, szName, szExt);
  55. }
  56. // Remove the name part of a file path. Return just the drive and directory, and name.
  57. //
  58. CString StripExtension(const TCHAR* szFilePath)
  59. {
  60. TCHAR szPath [_MAX_DRIVE + _MAX_DIR + _MAX_FNAME];
  61. TCHAR szDir [_MAX_DIR];
  62. TCHAR szName [_MAX_FNAME];
  63. MySplitPath(szFilePath, szPath, szDir, szName, NULL);
  64. lstrcat(szPath, szDir);
  65. lstrcat(szPath, szName);
  66. return CString(szPath);
  67. }
  68. void CImageDoc::OnFileSaveAs ()
  69. {
  70. CString sNewName = StripExtension(GetPathName());
  71. if (theApp.DoPromptFileName (sNewName, AFX_IDS_SAVEFILE,
  72. OFN_HIDEREADONLY | OFN_PATHMUSTEXIST,
  73. FALSE))
  74. {
  75. if (!OnSaveDocument (sNewName))
  76. {
  77. // be sure to delete the file
  78. TRY
  79. {
  80. CFile::Remove( sNewName );
  81. }
  82. CATCH_ALL(e)
  83. {
  84. TRACE0( "Warning: failed to delete file after failed SaveAs\n" );
  85. }
  86. END_CATCH_ALL
  87. }
  88. }
  89. }
  90. BOOL CImageDoc::OnSaveDocument(LPCTSTR szPathName)
  91. {
  92. // the view deals with the preview control, so ask it to do the save
  93. BOOL bRet = FALSE;
  94. POSITION pos = GetFirstViewPosition();
  95. CImageView *pView = dynamic_cast<CImageView*>(GetNextView(pos));
  96. if (pView)
  97. {
  98. HRESULT hr = pView->SaveImageAs(szPathName);
  99. if (SUCCEEDED(hr))
  100. {
  101. SetModifiedFlag (FALSE);
  102. SetPathName(szPathName);
  103. UpdateAllViews(NULL);
  104. bRet = TRUE;
  105. }
  106. else
  107. {
  108. LPTSTR szMsg = NULL;
  109. FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  110. NULL,
  111. hr,
  112. 0,
  113. reinterpret_cast<LPTSTR>(&szMsg),
  114. 1,
  115. NULL);
  116. if (szMsg)
  117. {
  118. AfxMessageBox (szMsg, MB_ICONHAND|MB_OK);
  119. }
  120. }
  121. }
  122. return bRet;
  123. }
  124. /////////////////////////////////////////////////////////////////////////////
  125. // CImageDoc serialization
  126. void CImageDoc::Serialize(CArchive& ar)
  127. {
  128. if (ar.IsStoring())
  129. {
  130. // TODO: add storing code here
  131. }
  132. else
  133. {
  134. // TODO: add loading code here
  135. }
  136. }
  137. /////////////////////////////////////////////////////////////////////////////
  138. // CImageDoc diagnostics
  139. #ifdef _DEBUG
  140. void CImageDoc::AssertValid() const
  141. {
  142. CDocument::AssertValid();
  143. }
  144. void CImageDoc::Dump(CDumpContext& dc) const
  145. {
  146. CDocument::Dump(dc);
  147. }
  148. #endif //_DEBUG
  149. /////////////////////////////////////////////////////////////////////////////
  150. // CImageDoc commands
  151. BOOL CImageDoc::OnOpenDocument(LPCTSTR lpszPathName)
  152. {
  153. if (!CDocument::OnOpenDocument(lpszPathName))
  154. return FALSE;
  155. DelTempFile ();
  156. return TRUE;
  157. }
  158. const CString&
  159. CImageDoc::GetImagePathName() const
  160. {
  161. if (m_bUseTempPath)
  162. {
  163. return m_strTempPath;
  164. }
  165. else
  166. {
  167. return GetPathName();
  168. }
  169. }
  170. void
  171. CImageDoc::SetTempFileName(const CString &strTempFile)
  172. {
  173. m_strTempPath = strTempFile;
  174. m_bUseTempPath = true;
  175. CString strUntitled;
  176. strUntitled.LoadString(AFX_IDS_UNTITLED);
  177. SetPathName (strUntitled, FALSE);
  178. }
  179. void
  180. CImageDoc::DelTempFile()
  181. {
  182. if (m_bUseTempPath)
  183. {
  184. m_bUseTempPath = false;
  185. CFile::Remove(m_strTempPath);
  186. }
  187. }
  188. void CImageDoc::OnFileScan()
  189. {
  190. // First, make a new document
  191. OnNewDocument();
  192. GetDevMgr();
  193. // Now do a scan to a temp file
  194. CString strTempPath;
  195. LPTSTR szPath;
  196. GUID guidFmt = WiaImgFmt_JPEG;
  197. GetTempPath (MAX_PATH, szPath = strTempPath.GetBufferSetLength(MAX_PATH));
  198. GetTempFileName (szPath, TEXT("img"),0,szPath);
  199. strTempPath.ReleaseBuffer();
  200. POSITION pos = GetFirstViewPosition();
  201. if (S_OK == m_pDevMgr->GetImageDlg(GetNextView(pos)->GetSafeHwnd(),
  202. StiDeviceTypeDefault,
  203. WIA_DEVICE_DIALOG_SINGLE_IMAGE,
  204. WIA_INTENT_NONE,
  205. NULL,
  206. CComBSTR(strTempPath),
  207. &guidFmt))
  208. {
  209. SetTempFileName(strTempPath);
  210. SetModifiedFlag(TRUE);
  211. UpdateAllViews(NULL);
  212. }
  213. }
  214. void CImageDoc::OnUpdateFileScan(CCmdUI* pCmdUI)
  215. {
  216. pCmdUI->Enable(bWIADeviceInstalled());
  217. }
  218. bool
  219. CImageDoc::bWIADeviceInstalled()
  220. {
  221. bool bRet = false;
  222. GetDevMgr();
  223. if (m_pDevMgr.p)
  224. {
  225. CComPtr<IEnumWIA_DEV_INFO> pEnum;
  226. if (SUCCEEDED(m_pDevMgr->EnumDeviceInfo (0, &pEnum)))
  227. {
  228. ULONG ul = 0;
  229. if (SUCCEEDED(pEnum->GetCount(&ul)))
  230. {
  231. bRet = ul ? true : false;
  232. }
  233. }
  234. }
  235. return bRet;
  236. }
  237. void
  238. CImageDoc::OnFileProperties ()
  239. {
  240. SHELLEXECUTEINFO sei;
  241. CString strPath = GetImagePathName();
  242. ZeroMemory (&sei, sizeof(sei));
  243. sei.cbSize = sizeof(sei);
  244. sei.fMask = SEE_MASK_INVOKEIDLIST;
  245. POSITION pos = GetFirstViewPosition();
  246. sei.hwnd = GetNextView(pos)->GetSafeHwnd();
  247. sei.lpVerb = TEXT("properties");
  248. sei.lpFile = strPath;
  249. sei.nShow = SW_SHOW;
  250. ShellExecuteEx (&sei);
  251. }
  252. void
  253. CImageDoc::OnFilePaperCenter ()
  254. {
  255. SetWallpaper (false);
  256. }
  257. void
  258. CImageDoc::OnFilePaperTile ()
  259. {
  260. SetWallpaper (true);
  261. }
  262. void
  263. CImageDoc::SetWallpaper(bool bTile)
  264. {
  265. // need to modify the registry directly in addition to the SPI
  266. DWORD dwDisp;
  267. HKEY hKey = 0;
  268. if (RegCreateKeyEx( HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"),
  269. REG_OPTION_RESERVED, TEXT(""),
  270. REG_OPTION_NON_VOLATILE,
  271. KEY_ALL_ACCESS, NULL, &hKey, &dwDisp ) == ERROR_SUCCESS)
  272. {
  273. RegSetValueEx( hKey, TEXT("TileWallpaper"), 0, REG_SZ,
  274. reinterpret_cast<BYTE *>(bTile? TEXT("1"): TEXT("0")), 2*sizeof(TCHAR) );
  275. RegCloseKey( hKey );
  276. }
  277. CString strPath = GetImagePathName();
  278. SystemParametersInfo( SPI_SETDESKWALLPAPER, bTile? 1: 0,
  279. (LPVOID)(strPath.GetBuffer( strPath.GetLength() )),
  280. SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE );
  281. strPath.ReleaseBuffer();
  282. }
  283. void
  284. CImageDoc::OnUpdateFileMenu (CCmdUI* pCmdUI)
  285. {
  286. BOOL bEnable = GetPathName().GetLength();
  287. switch (pCmdUI->m_nID)
  288. {
  289. case ID_FILE_SEND_MAIL:
  290. OnUpdateFileSendMail(pCmdUI);
  291. return;
  292. default:
  293. bEnable = bEnable && !m_bUseTempPath;
  294. break;
  295. }
  296. pCmdUI->Enable(bEnable);
  297. }
  298. void
  299. CImageDoc::GetDevMgr ()
  300. {
  301. if (!m_pDevMgr) // Create our WIA device manager pointer
  302. CoCreateInstance (CLSID_WiaDevMgr,
  303. NULL,
  304. CLSCTX_LOCAL_SERVER,
  305. IID_IWiaDevMgr,
  306. reinterpret_cast<LPVOID*>(&m_pDevMgr));
  307. }