wordpad.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:27k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // wordpad.cpp : Defines the class behaviors for the application.
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "wordpad.h"
  22. #include "mainfrm.h"
  23. #include "wordpdoc.h"
  24. #include "wordpvw.h"
  25. #include "strings.h"
  26. #include "key.h"
  27. #include "filenewd.h"
  28. #include <locale.h>
  29. #include <winnls.h>
  30. #include <winreg.h>
  31. #include "AboutDlg.h"
  32. extern BOOL AFXAPI AfxFullPath(LPTSTR lpszPathOut, LPCTSTR lpszFileIn);
  33. static BOOL RegisterHelper(LPCTSTR* rglpszRegister, LPCTSTR* rglpszSymbols,
  34. BOOL bReplace);
  35. #ifdef _DEBUG
  36. #undef THIS_FILE
  37. static char BASED_CODE THIS_FILE[] = __FILE__;
  38. #endif
  39. CLIPFORMAT cfEmbeddedObject;
  40. CLIPFORMAT cfRTF;
  41. CLIPFORMAT cfRTO;
  42. int CWordPadApp::m_nOpenMsg = RegisterWindowMessage(_T("WordPadOpenMessage"));
  43. int CWordPadApp::m_nPrinterChangedMsg = RegisterWindowMessage(_T("WordPadPrinterChanged"));
  44. const int CWordPadApp::m_nPrimaryNumUnits = 4;
  45. const int CWordPadApp::m_nNumUnits = 7;
  46. CUnit CWordPadApp::m_units[7] =
  47. {
  48. //  TPU,    SmallDiv,   MedDiv, LargeDiv,   MinMove,    szAbbrev,           bSpace
  49. CUnit(1440, 180,        720,    1440,       90,         IDS_INCH1_ABBREV,   FALSE),//inches
  50. CUnit(568,  142,        284,    568,        142,        IDS_CM_ABBREV,      TRUE),//centimeters
  51. CUnit(20,   120,        720,    720,        100,        IDS_POINT_ABBREV,   TRUE),//points
  52. CUnit(240,  240,        1440,   1440,       120,        IDS_PICA_ABBREV,    TRUE),//picas
  53. CUnit(1440, 180,        720,    1440,       90,         IDS_INCH2_ABBREV,   FALSE),//in
  54. CUnit(1440, 180,        720,    1440,       90,         IDS_INCH3_ABBREV,   FALSE),//inch
  55. CUnit(1440, 180,        720,    1440,       90,         IDS_INCH4_ABBREV,   FALSE)//inches
  56. };
  57. static UINT _cdecl DoRegistry(LPVOID lpv)
  58. {
  59. ASSERT(lpv != NULL);
  60. ((CWordPadApp*)lpv)->UpdateRegistry();
  61. return 0;
  62. }
  63. /////////////////////////////////////////////////////////////////////////////
  64. // CWordPadApp
  65. BEGIN_MESSAGE_MAP(CWordPadApp, CWinApp)
  66. //{{AFX_MSG_MAP(CWordPadApp)
  67. ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
  68. ON_COMMAND(ID_FILE_NEW, OnFileNew)
  69. ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
  70. //}}AFX_MSG_MAP
  71. END_MESSAGE_MAP()
  72. void CWordPadCommandLineInfo::ParseParam(const char* pszParam,BOOL bFlag,BOOL bLast)
  73. {
  74. if (bFlag)
  75. {
  76. if (lstrcmpA(pszParam, "t") == 0)
  77. {
  78. m_bForceTextMode = TRUE;
  79. return;
  80. }
  81. }
  82. CCommandLineInfo::ParseParam(pszParam, bFlag, bLast);
  83. }
  84. /////////////////////////////////////////////////////////////////////////////
  85. // CWordPadApp construction
  86. CWordPadApp::CWordPadApp() : m_optionsText(0), m_optionsRTF(1),
  87. m_optionsWord(2), m_optionsWrite(2), m_optionsIP(2), m_optionsNull(0)  //
  88. {
  89. _tsetlocale(LC_ALL, _T(""));
  90. m_nFilterIndex = 1;
  91. DWORD dwVersion = ::GetVersion();
  92. m_bWin4 = (BYTE)dwVersion >= 4;
  93. #ifndef _UNICODE
  94. m_bWin31 = (dwVersion > 0x80000000 && !m_bWin4);
  95. #endif
  96. m_nDefFont = (m_bWin4) ? DEFAULT_GUI_FONT : ANSI_VAR_FONT;
  97. m_dcScreen.Attach(::GetDC(NULL));
  98. m_bLargeIcons = m_dcScreen.GetDeviceCaps(LOGPIXELSX) >= 120;
  99. m_bForceOEM = FALSE;
  100. }
  101. CWordPadApp::~CWordPadApp()
  102. {
  103. if (m_dcScreen.m_hDC != NULL)
  104. ::ReleaseDC(NULL, m_dcScreen.Detach());
  105. }
  106. /////////////////////////////////////////////////////////////////////////////
  107. // The one and only CWordPadApp object
  108. CWordPadApp theApp;
  109. // Register the application's document templates.  Document templates
  110. //  serve as the connection between documents, frame windows and views.
  111. static CSingleDocTemplate DocTemplate(
  112. IDR_MAINFRAME,
  113. RUNTIME_CLASS(CWordPadDoc),
  114. RUNTIME_CLASS(CMainFrame),       // main SDI frame window
  115. RUNTIME_CLASS(CWordPadView));
  116. // This identifier was generated to be statistically unique for your app.
  117. // You may change it if you prefer to choose a specific identifier.
  118. static const CLSID BASED_CODE clsid =
  119. { 0x73FDDC80L, 0xAEA9, 0x101A, { 0x98, 0xA7, 0x00, 0xAA, 0x00, 0x37, 0x49, 0x59} };
  120. /////////////////////////////////////////////////////////////////////////////
  121. // CWordPadApp initialization
  122. BOOL CWordPadApp::InitInstance()
  123. {
  124. ParseCommandLine(cmdInfo);
  125. if (::FindWindow(szWordPadClass, NULL) && IsDocOpen(cmdInfo.m_strFileName))
  126. return FALSE;
  127. SetRegistryKey(_T("Codejock Software Sample Applications"));
  128. LoadOptions();
  129. #if _MSC_VER <= 1200 // MFC 6.0 or earlier
  130. Enable3dControls();
  131. #endif
  132. CSplashWnd splash;
  133. BOOL bSplash = cmdInfo.m_bShowSplash;
  134. if (!cmdInfo.m_bRunEmbedded)
  135. {
  136. switch (m_nCmdShow)
  137. {
  138. case SW_HIDE:
  139. case SW_SHOWMINIMIZED:
  140. case SW_MINIMIZE:
  141. case SW_SHOWMINNOACTIVE:
  142. bSplash = FALSE;
  143. break;
  144. case SW_RESTORE:
  145. case SW_SHOW:
  146. case SW_SHOWDEFAULT:
  147. case SW_SHOWNA:
  148. case SW_SHOWNOACTIVATE:
  149. case SW_SHOWNORMAL:
  150. case SW_SHOWMAXIMIZED:
  151. if (m_bMaximized)
  152. m_nCmdShow = SW_SHOWMAXIMIZED;
  153. break;
  154. }
  155. }
  156. else
  157. {
  158. //Excel 4 will start OLE servers minimized
  159. m_nCmdShow = SW_SHOWNORMAL;
  160. }
  161. int nCmdShow = m_nCmdShow;
  162. if (bSplash)
  163. {
  164. // only show splash if not embedded
  165. splash.Create(NULL);
  166. splash.ShowWindow(SW_SHOW);
  167. splash.UpdateWindow();
  168. }
  169. LoadAbbrevStrings();
  170. m_hDevNames = CreateDevNames();
  171. NotifyPrinterChanged((m_hDevNames == NULL));
  172. free((void*)m_pszHelpFilePath);
  173. m_pszHelpFilePath = _T("WORDPAD.HLP");
  174. // Initialize OLE libraries
  175. if (!AfxOleInit())
  176. {
  177. AfxMessageBox(IDP_OLE_INIT_FAILED);
  178. return FALSE;
  179. }
  180. RegisterFormats();
  181. // Initialize RichEdit control
  182. if (LoadLibrary(_T("RICHED32.DLL")) == NULL)
  183. {
  184. AfxMessageBox(IDS_RICHED_LOAD_FAIL, MB_OK|MB_ICONEXCLAMATION);
  185. return FALSE;
  186. }
  187. // Standard initialization
  188. // If you are not using these features and wish to reduce the size
  189. //  of your final executable, you should remove from the following
  190. //  the specific initialization routines you do not need.
  191. LoadStdProfileSettings();  // Load standard INI file options (including MRU)
  192. // Register the application's document templates.  Document templates
  193. //  serve as the connection between documents, frame windows and views.
  194. DocTemplate.SetContainerInfo(IDR_CNTR_INPLACE);
  195. /*DocTemplate.SetServerInfo(
  196. IDR_SRVR_EMBEDDED, IDR_SRVR_INPLACE,
  197. RUNTIME_CLASS(CInPlaceFrame));*/
  198. // Connect the COleTemplateServer to the document template.
  199. //  The COleTemplateServer creates new documents on behalf
  200. //  of requesting OLE containers by using information
  201. //  specified in the document template.
  202. m_server.ConnectTemplate(clsid, &DocTemplate, TRUE);
  203. // Note: SDI applications register server objects only if /Embedding
  204. //   or /Automation is present on the command line.
  205. // Check to see if launched as OLE server
  206. if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)
  207. {
  208. // Register all OLE server (factories) as running.  This enables the
  209. //  OLE libraries to create objects from other applications.
  210. COleTemplateServer::RegisterAll();
  211. AfxOleSetUserCtrl(FALSE);
  212. // Application was run with /Embedding or /Automation.  Don't show the
  213. //  main window in this case.
  214. return TRUE;
  215. }
  216. // make sure the main window is showing
  217. m_bPromptForType = FALSE;
  218. OnFileNew();
  219. m_bPromptForType = TRUE;
  220. // destroy splash window
  221. if (cmdInfo.m_bShowSplash)
  222. splash.DestroyWindow();
  223. m_nCmdShow = -1;
  224. if (m_pMainWnd == NULL) // i.e. OnFileNew failed
  225. return FALSE;
  226. if (!cmdInfo.m_strFileName.IsEmpty())   // open an existing document
  227. m_nCmdShow = nCmdShow;
  228. // Dispatch commands specified on the command line
  229. if (cmdInfo.m_nShellCommand != CCommandLineInfo::FileNew &&
  230. !ProcessShellCommand(cmdInfo))
  231. {
  232. return FALSE;
  233. }
  234. // Enable File Manager drag/drop open
  235. m_pMainWnd->DragAcceptFiles();
  236. // When a server application is launched stand-alone, it is a good idea
  237. //  to update the system registry in case it has been damaged.
  238. // do registry stuff in separate thread
  239. #ifndef _UNICODE
  240. if (m_bWin31) // no threads on Win32s
  241. UpdateRegistry();
  242. else
  243. #endif
  244. AfxBeginThread(DoRegistry, this, THREAD_PRIORITY_IDLE);
  245. return TRUE;
  246. }
  247. BOOL CWordPadApp::IsDocOpen(LPCTSTR lpszFileName)
  248. {
  249. if (lpszFileName[0] == NULL)
  250. return FALSE;
  251. TCHAR szPath[_MAX_PATH];
  252. AfxFullPath(szPath, lpszFileName);
  253. ATOM atom = GlobalAddAtom(szPath);
  254. ASSERT(atom != NULL);
  255. if (atom == NULL)
  256. return FALSE;
  257. EnumWindows(StaticEnumProc, (LPARAM)&atom);
  258. if (atom == NULL)
  259. return TRUE;
  260. DeleteAtom(atom);
  261. return FALSE;
  262. }
  263. BOOL CALLBACK CWordPadApp::StaticEnumProc(HWND hWnd, LPARAM lParam)
  264. {
  265. TCHAR szClassName[30];
  266. GetClassName(hWnd, szClassName, 30);
  267. if (lstrcmp(szClassName, szWordPadClass) != 0)
  268. return TRUE;
  269. ATOM* pAtom = (ATOM*)lParam;
  270. ASSERT(pAtom != NULL);
  271. DWORD_PTR dw = NULL;
  272. ::SendMessageTimeout(hWnd, m_nOpenMsg, NULL, (LPARAM)*pAtom,
  273. SMTO_ABORTIFHUNG, 500, &dw);
  274. if (dw)
  275. {
  276. ::SetForegroundWindow(hWnd);
  277. DeleteAtom(*pAtom);
  278. *pAtom = NULL;
  279. return FALSE;
  280. }
  281. return TRUE;
  282. }
  283. void CWordPadApp::RegisterFormats()
  284. {
  285. cfEmbeddedObject = (CLIPFORMAT)::RegisterClipboardFormat(_T("Embedded Object"));
  286. cfRTF = (CLIPFORMAT)::RegisterClipboardFormat(CF_RTF);
  287. cfRTO = (CLIPFORMAT)::RegisterClipboardFormat(CF_RETEXTOBJ);
  288. }
  289. CDocOptions& CWordPadApp::GetDocOptions(int nDocType)
  290. {
  291. switch (nDocType)
  292. {
  293. case RD_WINWORD6:
  294. case RD_WORDPAD:
  295. return m_optionsWord;
  296. case RD_RICHTEXT:
  297. return m_optionsRTF;
  298. case RD_TEXT:
  299. case RD_OEMTEXT:
  300. return m_optionsText;
  301. case RD_WRITE:
  302. return m_optionsWrite;
  303. case RD_EMBEDDED:
  304. return m_optionsIP;
  305. }
  306. ASSERT(FALSE);
  307. return m_optionsNull;
  308. }
  309. CDockState& CWordPadApp::GetDockState(int nDocType, BOOL bPrimary)
  310. {
  311. return GetDocOptions(nDocType).GetDockState(bPrimary);
  312. }
  313. void CWordPadApp::SaveOptions()
  314. {
  315. WriteProfileInt(szSection, szWordSel, m_bWordSel);
  316. WriteProfileInt(szSection, szUnits, GetUnits());
  317. WriteProfileInt(szSection, szMaximized, m_bMaximized);
  318. WriteProfileBinary(szSection, szFrameRect, (BYTE*)&m_rectInitialFrame,
  319. sizeof(CRect));
  320. WriteProfileBinary(szSection, szPageMargin, (BYTE*)&m_rectPageMargin,
  321. sizeof(CRect));
  322. m_optionsText.SaveOptions(szTextSection);
  323. m_optionsRTF.SaveOptions(szRTFSection);
  324. m_optionsWord.SaveOptions(szWordSection);
  325. m_optionsWrite.SaveOptions(szWriteSection);
  326. m_optionsIP.SaveOptions(szIPSection);
  327. }
  328. void CWordPadApp::LoadOptions()
  329. {
  330. BYTE* pb = NULL;
  331. UINT nLen = 0;
  332. HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
  333. if (hFont == NULL)
  334. hFont = (HFONT)GetStockObject(ANSI_VAR_FONT);
  335. VERIFY(GetObject(hFont, sizeof(LOGFONT), &m_lf));
  336. m_bWordSel = GetProfileInt(szSection, szWordSel, TRUE);
  337. TCHAR buf[2];
  338. buf[0] = NULL;
  339. GetLocaleInfo(GetUserDefaultLCID(), LOCALE_IMEASURE, buf, 2);
  340. int nDefUnits = buf[0] == '1' ? 0 : 1;
  341. SetUnits(GetProfileInt(szSection, szUnits, nDefUnits));
  342. m_bMaximized = GetProfileInt(szSection, szMaximized, (int)FALSE);
  343. if (GetProfileBinary(szSection, szFrameRect, &pb, &nLen))
  344. {
  345. ASSERT(nLen == sizeof(CRect));
  346. MEMCPY_S(&m_rectInitialFrame, pb, sizeof(CRect));
  347. delete pb;
  348. }
  349. else
  350. m_rectInitialFrame.SetRect(0,0,0,0);
  351. CRect rectScreen(0, 0, GetSystemMetrics(SM_CXSCREEN),
  352. GetSystemMetrics(SM_CYSCREEN));
  353. CRect rectInt;
  354. rectInt.IntersectRect(&rectScreen, &m_rectInitialFrame);
  355. if (rectInt.Width() < 10 || rectInt.Height() < 10)
  356. m_rectInitialFrame.SetRect(0, 0, 0, 0);
  357. if (GetProfileBinary(szSection, szPageMargin, &pb, &nLen))
  358. {
  359. ASSERT(nLen == sizeof(CRect));
  360. MEMCPY_S(&m_rectPageMargin, pb, sizeof(CRect));
  361. delete pb;
  362. }
  363. else
  364. m_rectPageMargin.SetRect(1800, 1440, 1800, 1440);
  365. m_optionsText.LoadOptions(szTextSection);
  366. m_optionsRTF.LoadOptions(szRTFSection);
  367. m_optionsWord.LoadOptions(szWordSection);
  368. m_optionsWrite.LoadOptions(szWriteSection);
  369. m_optionsIP.LoadOptions(szIPSection);
  370. }
  371. void CWordPadApp::LoadAbbrevStrings()
  372. {
  373. for (int i=0;i<m_nNumUnits;i++)
  374. m_units[i].m_strAbbrev.LoadString(m_units[i].m_nAbbrevID);
  375. }
  376. BOOL CWordPadApp::ParseMeasurement(LPTSTR buf, int& lVal)
  377. {
  378. TCHAR* pch;
  379. if (buf[0] == NULL)
  380. return FALSE;
  381. float f = (float)_tcstod(buf,&pch);
  382. // eat white space, if any
  383. while (isspace(*pch))
  384. pch++;
  385. if (pch[0] == NULL) // default
  386. {
  387. lVal = (f < 0.f) ? (int)(f*GetTPU()-0.5f) : (int)(f*GetTPU()+0.5f);
  388. return TRUE;
  389. }
  390. for (int i=0;i<m_nNumUnits;i++)
  391. {
  392. if (lstrcmpi(pch, GetAbbrev(i)) == 0)
  393. {
  394. lVal = (f < 0.f) ? (int)(f*GetTPU(i)-0.5f) : (int)(f*GetTPU(i)+0.5f);
  395. return TRUE;
  396. }
  397. }
  398. return FALSE;
  399. }
  400. void CWordPadApp::PrintTwips(TCHAR* buf, int nValue, int nDec)
  401. {
  402. ASSERT(nDec == 2);
  403. int div = GetTPU();
  404. int lval = nValue;
  405. BOOL bNeg = FALSE;
  406. int* pVal = new int[nDec+1];
  407. if (lval < 0)
  408. {
  409. bNeg = TRUE;
  410. lval = -lval;
  411. }
  412. int i;
  413. for (i=0;i<=nDec;i++)
  414. {
  415. pVal[i] = lval/div; //integer number
  416. lval -= pVal[i]*div;
  417. lval *= 10;
  418. }
  419. i--;
  420. if (lval >= div/2)
  421. pVal[i]++;
  422. while ((pVal[i] == 10) && (i != 0))
  423. {
  424. pVal[i] = 0;
  425. pVal[--i]++;
  426. }
  427. while (nDec && pVal[nDec] == 0)
  428. nDec--;
  429. #if (_MSC_VER > 1310) // VS2005
  430. _stprintf_s(buf, 64, _T("%.*f"), nDec, (float)nValue/(float)div);
  431. #else
  432. _stprintf(buf, _T("%.*f"), nDec, (float)nValue/(float)div);
  433. #endif
  434. if (m_units[m_nUnits].m_bSpaceAbbrev)
  435. lstrcat(buf, _T(" "));
  436. lstrcat(buf, GetAbbrev());
  437. delete []pVal;
  438. }
  439. /////////////////////////////////////////////////////////////////////////////
  440. // CWordPadApp commands
  441. void CWordPadApp::OnAppAbout()
  442. {
  443. CAboutDlg dlgAbout;
  444. dlgAbout.DoModal();
  445. }
  446. int CWordPadApp::ExitInstance()
  447. {
  448. m_pszHelpFilePath = NULL;
  449. FreeLibrary(GetModuleHandle(_T("RICHED32.DLL")));
  450. SaveOptions();
  451. return CWinApp::ExitInstance();
  452. }
  453. void CWordPadApp::OnFileNew()
  454. {
  455. int nDocType = -1;
  456. if (!m_bPromptForType)
  457. {
  458. if (cmdInfo.m_bForceTextMode)
  459. nDocType = RD_TEXT;
  460. else if (!cmdInfo.m_strFileName.IsEmpty())
  461. {
  462. CFileException fe;
  463. nDocType = GetDocTypeFromName(cmdInfo.m_strFileName, fe);
  464. }
  465. if (nDocType == -1)
  466. nDocType = RD_DEFAULT;
  467. }
  468. else
  469. {
  470. CFileNewDialog dlg;
  471. if (dlg.DoModal() == IDCANCEL)
  472. return;
  473. nDocType = (dlg.m_nSel == 0) ? RD_DEFAULT:  //Word 6
  474. (dlg.m_nSel == 1) ? RD_RICHTEXT :   //RTF
  475. RD_TEXT ;                   //text
  476. if (nDocType != RD_TEXT)
  477. cmdInfo.m_bForceTextMode = FALSE;
  478. }
  479. m_nNewDocType = nDocType;
  480. DocTemplate.OpenDocumentFile(NULL);
  481. // if returns NULL, the user has already been alerted
  482. }
  483. // prompt for file name - used for open and save as
  484. // static function called from app
  485. BOOL CWordPadApp::PromptForFileName(CString& fileName, UINT nIDSTitle,
  486. DWORD dwFlags, BOOL bOpenFileDialog, int* pType)
  487. {
  488. ScanForConverters();
  489. CFileDialog dlgFile(bOpenFileDialog);
  490. CString title;
  491. VERIFY(title.LoadString(nIDSTitle));
  492. dlgFile.m_ofn.Flags |= dwFlags;
  493. //  dlgFile.m_ofn.Flags &= ~OFN_SHOWHELP;
  494. int nIndex = m_nFilterIndex;
  495. if (!bOpenFileDialog)
  496. {
  497. int nDocType = (pType != NULL) ? *pType : RD_DEFAULT;
  498. nIndex = GetIndexFromType(nDocType, bOpenFileDialog);
  499. if (nIndex == -1)
  500. nIndex = GetIndexFromType(RD_DEFAULT, bOpenFileDialog);
  501. if (nIndex == -1)
  502. nIndex = GetIndexFromType(RD_NATIVE, bOpenFileDialog);
  503. ASSERT(nIndex != -1);
  504. nIndex++;
  505. }
  506. dlgFile.m_ofn.nFilterIndex = nIndex;
  507. // strDefExt is necessary to hold onto the memory from GetExtFromType
  508. CString strDefExt = GetExtFromType(GetTypeFromIndex(nIndex-1, bOpenFileDialog));
  509. dlgFile.m_ofn.lpstrDefExt = strDefExt;
  510. CString strFilter = GetFileTypes(bOpenFileDialog);
  511. dlgFile.m_ofn.lpstrFilter = strFilter;
  512. dlgFile.m_ofn.lpstrTitle = title;
  513. dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH);
  514. BOOL bRet = (dlgFile.DoModal() == IDOK) ? TRUE : FALSE;
  515. fileName.ReleaseBuffer();
  516. if (bRet)
  517. {
  518. if (bOpenFileDialog)
  519. m_nFilterIndex = dlgFile.m_ofn.nFilterIndex;
  520. if (pType != NULL)
  521. {
  522. int nIndex = (int)dlgFile.m_ofn.nFilterIndex - 1;
  523. ASSERT(nIndex >= 0);
  524. *pType = GetTypeFromIndex(nIndex, bOpenFileDialog);
  525. }
  526. }
  527. return bRet;
  528. }
  529. void CWordPadApp::OnFileOpen()
  530. {
  531. // prompt the user (with all document templates)
  532. CString newName;
  533. int nType = RD_DEFAULT;
  534. if (!PromptForFileName(newName, AFX_IDS_OPENFILE,
  535. OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, &nType))
  536. return; // open cancelled
  537. if (nType == RD_OEMTEXT)
  538. m_bForceOEM = TRUE;
  539. OpenDocumentFile(newName);
  540. m_bForceOEM = FALSE;
  541. // if returns NULL, the user has already been alerted
  542. }
  543. BOOL CWordPadApp::OnDDECommand(LPTSTR /*lpszCommand*/)
  544. {
  545. return FALSE;
  546. }
  547. /////////////////////////////////////////////////////////////////////////////
  548. // DDE and ShellExecute support
  549. //HKEY_CLASSES_ROOT.RTF = rtffile
  550. //HKEY_CLASSES_ROOTrtffile =
  551. //HKEY_CLASSES_ROOTrtffileCLSID = {73FDDC80-AEA9-101A-98A7-00AA00374959}
  552. //HKEY_CLASSES_ROOTrtffileprotocolStdFileEditingserver = WORDPAD.EXE
  553. //HKEY_CLASSES_ROOTrtffileprotocolStdFileEditingverb = &Edit
  554. //HKEY_CLASSES_ROOTrtffileshellopencommand = WORDPAD.EXE %1
  555. //HKEY_CLASSES_ROOTrtffileshellprintcommand = WORDPAD.EXE /p %1
  556. #define REGENTRY(key, value) _T(key) _T("") _T(value)
  557. #define REGENTRYX(key, valuename, value) _T(key) _T("") _T(valuename) _T("") _T(value)
  558. static const TCHAR sz00[] = REGENTRY("%2", "%5");
  559. static const TCHAR sz01[] = REGENTRY("%2\CLSID", "%1");
  560. static const TCHAR sz02[] = REGENTRY("%2\Insertable", "");
  561. static const TCHAR sz03[] = REGENTRY("%2\protocol\StdFileEditing\verb\0", "&Edit");
  562. static const TCHAR sz04[] = REGENTRY("%2\protocol\StdFileEditing\server", "%3");
  563. static const TCHAR sz05[] = REGENTRY("CLSID\%1", "%5");
  564. static const TCHAR sz06[] = REGENTRY("CLSID\%1\ProgID", "%2");
  565. static const TCHAR sz07[] = REGENTRY("CLSID\%1\InprocHandler32", "ole32.dll");
  566. static const TCHAR sz08[] = REGENTRY("CLSID\%1\LocalServer32", "%3");
  567. static const TCHAR sz09[] = REGENTRY("CLSID\%1\Verb\0", "&Edit,0,2");
  568. static const TCHAR sz10[] = REGENTRY("CLSID\%1\Verb\1", "&Open,0,2");
  569. static const TCHAR sz11[] = REGENTRY("CLSID\%1\Insertable", "");
  570. static const TCHAR sz12[] = REGENTRY("CLSID\%1\AuxUserType\2", "%4");
  571. static const TCHAR sz13[] = REGENTRY("CLSID\%1\AuxUserType\3", "%6");
  572. static const TCHAR sz14[] = REGENTRY("CLSID\%1\DefaultIcon", "%3,1");
  573. static const TCHAR sz15[] = REGENTRY("CLSID\%1\MiscStatus", "0");
  574. static const TCHAR sz16[] = REGENTRY("%2\shell\open\command", "%3 "%%1"");
  575. static const TCHAR sz17[] = REGENTRY("%2\shell\print\command", "%3 /p "%%1"");
  576. static const TCHAR sz18[] = REGENTRY("%7", "%2");
  577. static const TCHAR sz19[] = REGENTRY("%2", ""); // like sz00 only no long type name
  578. static const TCHAR sz20[] = REGENTRY("%2\shell\printto\command", "%3 /pt "%%1" "%%2" "%%3" "%%4"");
  579. static const TCHAR sz21[] = REGENTRY("%2\DefaultIcon", "%3,%8");
  580. static const TCHAR sz22[] = REGENTRYX("%7\ShellNew", "NullFile", "true");
  581. static const TCHAR sz23[] = REGENTRYX("%7\ShellNew", "Data", "{\rtf1}");
  582. // %1 - class ID
  583. // %2 - class name              WordPad.Document.1
  584. // %3 - SFN executable path     C:PROGRA~1ACCESS~1WORDPAD.EXE
  585. // %4 - short type name         Document
  586. // %5 - long type name          Microsoft WordPad Document
  587. // %6 - long application name   Microsoft WordPad
  588. // %7 = extension               .rtf
  589. // %8 = default icon            0,1,2,3
  590. #define NUM_REG_ARGS 8
  591. static const LPCTSTR rglpszWordPadRegister[] =
  592. {sz00, sz02, sz03, sz05, sz09, sz10, sz11, sz15, NULL};
  593. static const LPCTSTR rglpszWordPadOverwrite[] =
  594. {sz01, sz04, sz06, sz07, sz08, sz12, sz13, sz14, sz16, sz17, sz20, NULL};
  595. //static const LPCTSTR rglpszExtRegister[] =
  596. //{sz00, sz18, NULL};
  597. //static const LPCTSTR rglpszExtOverwrite[] =
  598. //{sz01, sz16, sz17, sz21, NULL};
  599. static const LPCTSTR rglpszWriExtRegister[] =
  600. {sz18, NULL};
  601. static const LPCTSTR rglpszWriRegister[] =
  602. {sz00, sz01, sz16, sz17, sz20, sz21, NULL};
  603. static const LPCTSTR rglpszRtfExtRegister[] =
  604. {sz18, sz23, NULL};
  605. static const LPCTSTR rglpszRtfRegister[] =
  606. {sz00, sz01, sz16, sz17, sz20, sz21, NULL};
  607. static const LPCTSTR rglpszTxtExtRegister[] =
  608. {sz18, sz22, NULL};
  609. static const LPCTSTR rglpszTxtRegister[] =
  610. {sz00, sz01, sz16, sz17, sz20, sz21, NULL};
  611. static const LPCTSTR rglpszDocExtRegister[] =
  612. {sz18, sz22, NULL};
  613. static const LPCTSTR rglpszDocRegister[] =
  614. {sz00, sz01, sz16, sz17, sz20, sz21, NULL};
  615. static void RegisterExt(LPCTSTR lpszExt, LPCTSTR lpszProgID, UINT nIDTypeName,
  616. LPCTSTR* rglpszSymbols, LPCTSTR* rglpszExtRegister,
  617. LPCTSTR* rglpszRegister, int nIcon)
  618. {
  619. // don't overwrite anything with the extensions
  620. CString strWhole;
  621. VERIFY(strWhole.LoadString(nIDTypeName));
  622. CString str;
  623. AfxExtractSubString(str, strWhole, DOCTYPE_PROGID);
  624. rglpszSymbols[1] = lpszProgID;
  625. rglpszSymbols[4] = str;
  626. rglpszSymbols[6] = lpszExt;
  627. TCHAR buf[10];
  628. wsprintf(buf, _T("%d"), nIcon);
  629. rglpszSymbols[7] = buf;
  630. // check for .ext and progid
  631. CKey key;
  632. if (!key.Open(HKEY_CLASSES_ROOT, lpszExt)) // .ext doesn't exist
  633. RegisterHelper(rglpszExtRegister, rglpszSymbols, TRUE);
  634. key.Close();
  635. if (!key.Open(HKEY_CLASSES_ROOT, lpszProgID)) // ProgID doesn't exist (i.e. txtfile)
  636. RegisterHelper(rglpszRegister, rglpszSymbols, TRUE);
  637. }
  638. void CWordPadApp::UpdateRegistry()
  639. {
  640. USES_CONVERSION;
  641. LPOLESTR lpszClassID = NULL;
  642. CDocTemplate* pDocTemplate = &DocTemplate;
  643. // get registration info from doc template string
  644. CString strServerName;
  645. CString strLocalServerName;
  646. CString strLocalShortName;
  647. if (!pDocTemplate->GetDocString(strServerName,
  648. CDocTemplate::regFileTypeId) || strServerName.IsEmpty())
  649. {
  650. TRACE0("Error: not enough information in DocTemplate to register OLE server.n");
  651. return;
  652. }
  653. if (!pDocTemplate->GetDocString(strLocalServerName,
  654. CDocTemplate::regFileTypeName))
  655. strLocalServerName = strServerName;     // use non-localized name
  656. if (!pDocTemplate->GetDocString(strLocalShortName,
  657. CDocTemplate::fileNewName))
  658. strLocalShortName = strLocalServerName; // use long name
  659. ASSERT(strServerName.Find(' ') == -1);  // no spaces allowed
  660. ::StringFromCLSID(clsid, &lpszClassID);
  661. ASSERT (lpszClassID != NULL);
  662. // get path name to server
  663. TCHAR szLongPathName[_MAX_PATH];
  664. TCHAR szShortPathName[_MAX_PATH];
  665. ::GetModuleFileName(AfxGetInstanceHandle(), szLongPathName, _MAX_PATH);
  666. ::GetShortPathName(szLongPathName, szShortPathName, _MAX_PATH);
  667. LPCTSTR rglpszSymbols[NUM_REG_ARGS];
  668. rglpszSymbols[0] = OLE2CT(lpszClassID);
  669. rglpszSymbols[1] = strServerName;
  670. rglpszSymbols[2] = szShortPathName;
  671. rglpszSymbols[3] = strLocalShortName;
  672. rglpszSymbols[4] = strLocalServerName;
  673. rglpszSymbols[5] = m_pszAppName;    // will usually be long, readable name
  674. rglpszSymbols[6] = NULL;
  675. if (RegisterHelper((LPCTSTR*)rglpszWordPadRegister, rglpszSymbols, FALSE))
  676. RegisterHelper((LPCTSTR*)rglpszWordPadOverwrite, rglpszSymbols, TRUE);
  677. //  RegisterExt(_T(".txt"), _T("txtfile"), IDS_TEXT_DOC, rglpszSymbols,
  678. //      (LPCTSTR*)rglpszTxtExtRegister, (LPCTSTR*)rglpszTxtRegister, 3);
  679. RegisterExt(_T(".rtf"), _T("rtffile"), IDS_RICHTEXT_DOC, rglpszSymbols,
  680. (LPCTSTR*)rglpszRtfExtRegister, (LPCTSTR*)rglpszRtfRegister, 1);
  681. RegisterExt(_T(".wri"), _T("wrifile"), IDS_WRITE_DOC, rglpszSymbols,
  682. (LPCTSTR*)rglpszWriExtRegister, (LPCTSTR*)rglpszWriRegister, 2);
  683. RegisterExt(_T(".doc"), _T("WordPad.Document.1"), IDS_WINWORD6_DOC, rglpszSymbols,
  684. (LPCTSTR*)rglpszDocExtRegister, (LPCTSTR*)rglpszDocRegister, 1);
  685. // free memory for class ID
  686. ASSERT(lpszClassID != NULL);
  687. CoTaskMemFree(lpszClassID);
  688. }
  689. BOOL RegisterHelper(LPCTSTR* rglpszRegister, LPCTSTR* rglpszSymbols,
  690. BOOL bReplace)
  691. {
  692. ASSERT(rglpszRegister != NULL);
  693. ASSERT(rglpszSymbols != NULL);
  694. CString strKey;
  695. CString strValueName;
  696. CString strValue;
  697. // keeping a key open makes this go a bit faster
  698. CKey keyTemp;
  699. VERIFY(keyTemp.Create(HKEY_CLASSES_ROOT, _T("CLSID")));
  700. BOOL bResult = TRUE;
  701. while (*rglpszRegister != NULL)
  702. {
  703. LPCTSTR lpszKey = *rglpszRegister++;
  704. if (*lpszKey == '')
  705. continue;
  706. LPCTSTR lpszValueName = lpszKey + lstrlen(lpszKey) + 1;
  707. LPCTSTR lpszValue = lpszValueName + lstrlen(lpszValueName) + 1;
  708. strKey.ReleaseBuffer(
  709. FormatMessage(FORMAT_MESSAGE_FROM_STRING |
  710. FORMAT_MESSAGE_ARGUMENT_ARRAY, lpszKey, NULL,   NULL,
  711. strKey.GetBuffer(256), 256, (va_list*) rglpszSymbols));
  712. strValueName = lpszValueName;
  713. strValue.ReleaseBuffer(
  714. FormatMessage(FORMAT_MESSAGE_FROM_STRING |
  715. FORMAT_MESSAGE_ARGUMENT_ARRAY, lpszValue, NULL, NULL,
  716. strValue.GetBuffer(256), 256, (va_list*) rglpszSymbols));
  717. if (strKey.IsEmpty())
  718. {
  719. TRACE1("Warning: skipping empty key '%s'.n", lpszKey);
  720. continue;
  721. }
  722. CKey key;
  723. VERIFY(key.Create(HKEY_CLASSES_ROOT, strKey));
  724. if (!bReplace)
  725. {
  726. CString str;
  727. if (key.GetStringValue(str, strValueName) && !str.IsEmpty())
  728. continue;
  729. }
  730. if (!key.SetStringValue(strValue, strValueName))
  731. {
  732. TRACE2("Error: failed setting key '%s' to value '%s'.n",
  733. (LPCTSTR)strKey, (LPCTSTR)strValue);
  734. bResult = FALSE;
  735. break;
  736. }
  737. }
  738. return bResult;
  739. }
  740. void CWordPadApp::WinHelp(DWORD dwData, UINT nCmd)
  741. {
  742. if (nCmd == HELP_INDEX || nCmd == HELP_CONTENTS)
  743. nCmd = HELP_FINDER;
  744. CWinApp::WinHelp(dwData, nCmd);
  745. }
  746. BOOL CWordPadApp::PreTranslateMessage(MSG* pMsg)
  747. {
  748. if (pMsg->message == WM_PAINT)
  749. return FALSE;
  750. // CWinApp::PreTranslateMessage does nothing but call base
  751. return CWinThread::PreTranslateMessage(pMsg);
  752. }
  753. void CWordPadApp::NotifyPrinterChanged(BOOL bUpdatePrinterSelection)
  754. {
  755. if (bUpdatePrinterSelection)
  756. UpdatePrinterSelection(FALSE);
  757. POSITION pos = m_listPrinterNotify.GetHeadPosition();
  758. while (pos != NULL)
  759. {
  760. HWND hWnd = m_listPrinterNotify.GetNext(pos);
  761. ::SendMessage(hWnd, m_nPrinterChangedMsg, 0, 0);
  762. }
  763. }
  764. BOOL CWordPadApp::IsIdleMessage(MSG* pMsg)
  765. {
  766. if (pMsg->message == WM_MOUSEMOVE || pMsg->message == WM_NCMOUSEMOVE)
  767. return FALSE;
  768. return CWinApp::IsIdleMessage(pMsg);
  769. }
  770. HGLOBAL CWordPadApp::CreateDevNames()
  771. {
  772. HGLOBAL hDev = NULL;
  773. if (!cmdInfo.m_strDriverName.IsEmpty() && !cmdInfo.m_strPrinterName.IsEmpty() &&
  774. !cmdInfo.m_strPortName.IsEmpty())
  775. {
  776. hDev = GlobalAlloc(GPTR, 4*sizeof(WORD)+
  777. cmdInfo.m_strDriverName.GetLength() + 1 +
  778. cmdInfo.m_strPrinterName.GetLength() + 1 +
  779. cmdInfo.m_strPortName.GetLength()+1);
  780. LPDEVNAMES lpDev = (LPDEVNAMES)GlobalLock(hDev);
  781. lpDev->wDriverOffset = sizeof(WORD)*4;
  782. lstrcpy((TCHAR*)lpDev + lpDev->wDriverOffset, cmdInfo.m_strDriverName);
  783. lpDev->wDeviceOffset = (WORD)(lpDev->wDriverOffset + cmdInfo.m_strDriverName.GetLength()+1);
  784. lstrcpy((TCHAR*)lpDev + lpDev->wDeviceOffset, cmdInfo.m_strPrinterName);
  785. lpDev->wOutputOffset = (WORD)(lpDev->wDeviceOffset + cmdInfo.m_strPrinterName.GetLength()+1);
  786. lstrcpy((TCHAR*)lpDev + lpDev->wOutputOffset, cmdInfo.m_strPortName);
  787. lpDev->wDefault = 0;
  788. }
  789. return hDev;
  790. }