WORDPAD.CPP
上传用户:aakk678
上传日期:2022-07-09
资源大小:406k
文件大小:27k
源码类别:

界面编程

开发平台:

Visual C++

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