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.

344 lines
9.0 KiB

  1. // shimgvwr.cpp : Defines the class behaviors for the application.
  2. //
  3. #include "stdafx.h"
  4. #include "shimgvwr.h"
  5. #include "MainFrm.h"
  6. #include "ImageDoc.h"
  7. #include "ImageView.h"
  8. #include "ofn.h"
  9. #include <gdiplus.h>
  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15. using namespace Gdiplus;
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CPreviewApp
  18. BEGIN_MESSAGE_MAP(CPreviewApp, CWinApp)
  19. //{{AFX_MSG_MAP(CPreviewApp)
  20. ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
  21. //}}AFX_MSG_MAP
  22. // Standard file based document commands
  23. ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
  24. ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
  25. END_MESSAGE_MAP()
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CPreviewApp construction
  28. CPreviewApp::CPreviewApp()
  29. {
  30. m_hFileMap = INVALID_HANDLE_VALUE;
  31. }
  32. CPreviewApp::~CPreviewApp()
  33. {
  34. if ( m_hFileMap != INVALID_HANDLE_VALUE)
  35. {
  36. CloseHandle (m_hFileMap);
  37. }
  38. }
  39. void CPreviewApp::OnFileOpen ()
  40. {
  41. CString newName;
  42. if (! DoPromptFileName( newName, AFX_IDS_OPENFILE,
  43. OFN_HIDEREADONLY | OFN_FILEMUSTEXIST,
  44. TRUE ))
  45. return; // open cancelled
  46. if (OpenDocumentFile(newName) == NULL)
  47. {
  48. OnFileNew();
  49. }
  50. }
  51. void MakeFilterFromCodecs (CString &strFilter, UINT nCodecs, ImageCodecInfo *pCodecs)
  52. {
  53. strFilter+=TEXT('\0');
  54. for (UINT i=0;i<nCodecs;i++)
  55. {
  56. strFilter+=pCodecs->FormatDescription;
  57. strFilter+=TEXT('\0');
  58. strFilter+=pCodecs->FilenameExtension;
  59. strFilter+=TEXT('\0');
  60. pCodecs++;
  61. }
  62. }
  63. void
  64. GetFilterStringForSave (CString &strFilter)
  65. {
  66. strFilter.LoadString(IDS_ALLFILES);
  67. strFilter+=TEXT('\0');
  68. strFilter+=TEXT("*.*");
  69. UINT nCodecs = 0;
  70. UINT cbCodecs = 0;
  71. BYTE *pData;
  72. GetImageEncodersSize (&nCodecs, &cbCodecs);
  73. if (cbCodecs)
  74. {
  75. pData = new BYTE[cbCodecs];
  76. if (pData)
  77. {
  78. ImageCodecInfo *pCodecs = reinterpret_cast<ImageCodecInfo*>(pData);
  79. if (Ok == GetImageEncoders (nCodecs, cbCodecs, pCodecs))
  80. {
  81. MakeFilterFromCodecs (strFilter, nCodecs, pCodecs);
  82. }
  83. delete [] pData;
  84. }
  85. }
  86. strFilter+=TEXT('\0');
  87. }
  88. void
  89. GetFilterStringForOpen (CString &strFilter)
  90. {
  91. strFilter.LoadString(IDS_ALLFILES);
  92. strFilter+=TEXT('\0');
  93. strFilter+=TEXT("*.*");
  94. // query GDI+ for supported image decoders
  95. UINT nCodecs = 0;
  96. UINT cbCodecs = 0;
  97. BYTE *pData;
  98. GetImageDecodersSize (&nCodecs, &cbCodecs);
  99. if (cbCodecs)
  100. {
  101. pData = new BYTE[cbCodecs];
  102. if (pData)
  103. {
  104. ImageCodecInfo *pCodecs = reinterpret_cast<ImageCodecInfo*>(pData);
  105. if (Ok == GetImageDecoders (nCodecs, cbCodecs, pCodecs))
  106. {
  107. MakeFilterFromCodecs (strFilter, nCodecs, pCodecs);
  108. }
  109. delete [] pData;
  110. }
  111. }
  112. strFilter+=TEXT('\0');
  113. }
  114. // Get the extension of a file path.
  115. //
  116. CString GetExtension(const TCHAR* szFilePath)
  117. {
  118. TCHAR szExt [_MAX_EXT];
  119. MySplitPath(szFilePath, NULL, NULL, NULL, szExt);
  120. return CString(szExt);
  121. }
  122. BOOL CPreviewApp::DoPromptFileName( CString& fileName, UINT nIDSTitle, DWORD lFlags,
  123. BOOL bOpenFileDialog )
  124. {
  125. COpenFileName dlgFile( bOpenFileDialog );
  126. if (!dlgFile.m_pofn)
  127. return FALSE;
  128. CString title;
  129. VERIFY( title.LoadString( nIDSTitle ) );
  130. lFlags |= OFN_EXPLORER;
  131. if (!bOpenFileDialog)
  132. lFlags |= OFN_OVERWRITEPROMPT;
  133. dlgFile.m_pofn->Flags |= lFlags;
  134. dlgFile.m_pofn->Flags &= ~OFN_SHOWHELP;
  135. CString strFilter;
  136. if (bOpenFileDialog)
  137. {
  138. GetFilterStringForOpen (strFilter);
  139. }
  140. else
  141. {
  142. GetFilterStringForSave (strFilter);
  143. }
  144. CString strExt = GetExtension(fileName);
  145. dlgFile.m_pofn->lpstrFilter = strFilter;
  146. dlgFile.m_pofn->hwndOwner = AfxGetMainWnd()->GetSafeHwnd();
  147. dlgFile.m_pofn->hInstance = AfxGetResourceHandle();
  148. dlgFile.m_pofn->lpstrTitle = title;
  149. dlgFile.m_pofn->lpstrFile = fileName.GetBuffer(_MAX_PATH);
  150. dlgFile.m_pofn->nMaxFile = _MAX_PATH;
  151. dlgFile.m_pofn->lpstrInitialDir = NULL;
  152. dlgFile.m_pofn->lpstrDefExt = strExt;
  153. BOOL bRet = dlgFile.DoModal() == IDOK? TRUE : FALSE;
  154. fileName.ReleaseBuffer();
  155. return bRet;
  156. }
  157. /////////////////////////////////////////////////////////////////////////////
  158. // The one and only CPreviewApp object
  159. CPreviewApp theApp;
  160. /////////////////////////////////////////////////////////////////////////////
  161. // CPreviewApp initialization
  162. BOOL CPreviewApp::InitInstance()
  163. {
  164. CoInitialize (NULL);
  165. AfxEnableControlContainer();
  166. // Standard initialization
  167. // If you are not using these features and wish to reduce the size
  168. // of your final executable, you should remove from the following
  169. // the specific initialization routines you do not need.
  170. #ifdef _AFXDLL
  171. Enable3dControls(); // Call this when using MFC in a shared DLL
  172. #else
  173. Enable3dControlsStatic(); // Call this when linking to MFC statically
  174. #endif
  175. // Change the registry key under which our settings are stored.
  176. SetRegistryKey(_T("Shell_Image_Previewer"));
  177. LoadStdProfileSettings(); // Load standard INI file options (including MRU)
  178. // Register the application's document templates. Document templates
  179. // serve as the connection between documents, frame windows and views.
  180. CSingleDocTemplate* pDocTemplate;
  181. pDocTemplate = new CSingleDocTemplate(
  182. IDR_MAINFRAME,
  183. RUNTIME_CLASS(CImageDoc),
  184. RUNTIME_CLASS(CMainFrame), // main SDI frame window
  185. RUNTIME_CLASS(CImageView));
  186. AddDocTemplate(pDocTemplate);
  187. // Parse command line for standard shell commands, DDE, file open
  188. CCommandLineInfo cmdInfo;
  189. ParseCommandLine(cmdInfo);
  190. if (cmdInfo.m_nShellCommand == CCommandLineInfo::FileOpen && PrevInstance (cmdInfo.m_strFileName))
  191. {
  192. return FALSE;
  193. }
  194. // Dispatch commands specified on the command line
  195. if (!ProcessShellCommand(cmdInfo))
  196. return FALSE;
  197. // The one and only window has been initialized, so show and update it.
  198. m_pMainWnd->ShowWindow(SW_SHOW);
  199. m_pMainWnd->UpdateWindow();
  200. return TRUE;
  201. }
  202. #define FILEMAPPINGNAME TEXT("Shimgvwr")
  203. bool
  204. CPreviewApp::PrevInstance(const CString &strFile)
  205. {
  206. CString strMapping(FILEMAPPINGNAME);
  207. bool bRet = false;
  208. strMapping += strFile;
  209. OutputDebugString (strMapping);
  210. OutputDebugString (TEXT("\n"));
  211. strMapping.Replace (TEXT('\\'), TEXT('/'));
  212. HANDLE hMap = CreateFileMapping (INVALID_HANDLE_VALUE,
  213. NULL,
  214. PAGE_READWRITE,
  215. 0, sizeof(HWND),
  216. strMapping);
  217. if (hMap )
  218. {
  219. DWORD dw = GetLastError();
  220. HWND *phwnd = reinterpret_cast<HWND*>(MapViewOfFile (hMap, FILE_MAP_WRITE, 0, 0, sizeof(HWND)));
  221. if (phwnd)
  222. {
  223. CWnd WndPrev;
  224. CWnd *pWndChild;
  225. WndPrev.Attach(*phwnd);
  226. if (ERROR_ALREADY_EXISTS == dw)
  227. {
  228. pWndChild = WndPrev.GetLastActivePopup();
  229. if (WndPrev.IsIconic())
  230. {
  231. WndPrev.ShowWindow (SW_RESTORE);
  232. }
  233. pWndChild->SetForegroundWindow();
  234. bRet = true;
  235. CloseHandle (hMap); // we can close the handle before unmapping the view
  236. }
  237. else
  238. {
  239. *phwnd = 0;
  240. m_hFileMap = hMap;
  241. }
  242. UnmapViewOfFile (phwnd);
  243. }
  244. }
  245. return bRet;
  246. }
  247. /////////////////////////////////////////////////////////////////////////////
  248. // CAboutDlg dialog used for App About
  249. class CAboutDlg : public CDialog
  250. {
  251. public:
  252. CAboutDlg();
  253. // Dialog Data
  254. //{{AFX_DATA(CAboutDlg)
  255. enum { IDD = IDD_ABOUTBOX };
  256. //}}AFX_DATA
  257. // ClassWizard generated virtual function overrides
  258. //{{AFX_VIRTUAL(CAboutDlg)
  259. protected:
  260. virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
  261. //}}AFX_VIRTUAL
  262. // Implementation
  263. protected:
  264. //{{AFX_MSG(CAboutDlg)
  265. // No message handlers
  266. //}}AFX_MSG
  267. DECLARE_MESSAGE_MAP()
  268. };
  269. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  270. {
  271. //{{AFX_DATA_INIT(CAboutDlg)
  272. //}}AFX_DATA_INIT
  273. }
  274. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  275. {
  276. CDialog::DoDataExchange(pDX);
  277. //{{AFX_DATA_MAP(CAboutDlg)
  278. //}}AFX_DATA_MAP
  279. }
  280. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  281. //{{AFX_MSG_MAP(CAboutDlg)
  282. // No message handlers
  283. //}}AFX_MSG_MAP
  284. END_MESSAGE_MAP()
  285. // App command to run the dialog
  286. void CPreviewApp::OnAppAbout()
  287. {
  288. CString sTitle;
  289. HICON hIcon = LoadIcon(IDR_MAINFRAME);
  290. sTitle.LoadString(AFX_IDS_APP_TITLE);
  291. ShellAbout(AfxGetMainWnd()->GetSafeHwnd(), sTitle, NULL, hIcon);
  292. }