maindlg.cpp
Upload User: meilifafa
Upload Date: 2009-11-20
Package Size: 11k
Code Size: 13k
Development Platform:

Visual C++

  1. #include "stdafx.h"
  2. #include "resource.h"
  3. #include "maindlg.h"
  4. #import "msxml3.dll" raw_interfaces_only
  5. using namespace MSXML2;
  6. // quick and dirty wait cursor class
  7. class CWaitCursor
  8. {
  9. public:
  10. CWaitCursor() : m_hCursorOld(::SetCursor(::LoadCursor(NULL, IDC_WAIT)))
  11. {
  12. }
  13. ~CWaitCursor()
  14. {
  15. ::SetCursor(m_hCursorOld);
  16. }
  17. private:
  18. HCURSOR m_hCursorOld;
  19. };
  20. CMainDlg::CMainDlg() : m_bInit(FALSE)
  21. {
  22. m_csMinSize.cx = m_csMinSize.cy = 0;
  23. }
  24. LRESULT CMainDlg::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  25. {
  26. Init();
  27. // I don't like Window logo as icons
  28. SetIcon(::LoadIcon(NULL, IDI_APPLICATION), TRUE);
  29. SetIcon(::LoadIcon(NULL, IDI_APPLICATION), FALSE);
  30. // init text in edit box
  31. SetDlgItemText(IDC_FILENAME, _T("test.xml"));
  32. CenterWindow();
  33. return TRUE;
  34. }
  35. LRESULT CMainDlg::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  36. {
  37. EndDialog(IDCANCEL);
  38. return 0;
  39. }
  40. LRESULT CMainDlg::OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  41. {
  42. if (m_bInit)
  43. {
  44. LPMINMAXINFO pmmi = (LPMINMAXINFO)lParam;
  45. pmmi->ptMinTrackSize.x = m_csMinSize.cx;
  46. pmmi->ptMinTrackSize.y = m_csMinSize.cy;
  47. }
  48. return 0;
  49. }
  50. LRESULT CMainDlg::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  51. {
  52. if (m_bInit)
  53. {
  54. // set up client rect
  55. RECT rcClient;
  56. ::SetRect(&rcClient, 0, 0, (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam));
  57. int iWidth = rcClient.right - rcClient.left;
  58. int iHeight = rcClient.bottom - rcClient.top;
  59. HDWP hdwp = ::BeginDeferWindowPos(9);
  60. // resize "File Name" edit box
  61. ::DeferWindowPos(
  62. hdwp, GetDlgItem(IDC_FILENAME), NULL,
  63. 0, 0, iWidth - m_csFilename.cx, m_csFilename.cy,
  64. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE
  65. );
  66. // resize "Try File" button
  67. ::DeferWindowPos(
  68. hdwp, GetDlgItem(IDC_TRYFILE), NULL,
  69. rcClient.right - m_csTryFile.cx, rcClient.top + m_csTryFile.cy, 0, 0,
  70. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE
  71. );
  72. // resize "Try Demo" button
  73. ::DeferWindowPos(
  74. hdwp, GetDlgItem(IDC_TRYDEMO), NULL,
  75. rcClient.right - m_csTryDemo.cx, rcClient.top + m_csTryDemo.cy, 0, 0,
  76. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE
  77. );
  78. // resize "Exit" button
  79. ::DeferWindowPos(
  80. hdwp, GetDlgItem(IDC_EXIT), NULL,
  81. rcClient.right - m_csExit.cx, rcClient.top + m_csExit.cy, 0, 0,
  82. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE
  83. );
  84. // resize separator
  85. ::DeferWindowPos(
  86. hdwp, GetDlgItem(IDC_SEPARATOR), NULL,
  87. 0, 0, iWidth - m_csSeparator.cx, m_csSeparator.cy,
  88. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE
  89. );
  90. // resize "Events" label
  91. ::DeferWindowPos(
  92. hdwp, GetDlgItem(IDC_EVENTS_LABEL), NULL,
  93. rcClient.left + m_csEventsLabel.cx, rcClient.top + m_csEventsLabel.cy, 0, 0,
  94. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE
  95. );
  96. // resize "Events" edit box
  97. ::DeferWindowPos(
  98. hdwp, GetDlgItem(IDC_EVENTS), NULL,
  99. 0, 0,
  100. m_csEvents.cx, iHeight - m_csEvents.cy,
  101. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE
  102. );
  103. // resize "XML" label
  104. ::DeferWindowPos(
  105. hdwp, GetDlgItem(IDC_XML_LABEL), NULL,
  106. rcClient.left + m_csXmlLabel.cx, rcClient.top + m_csXmlLabel.cy, 0, 0,
  107. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE
  108. );
  109. // resize "XML" edit box
  110. ::DeferWindowPos(
  111. hdwp, GetDlgItem(IDC_XML), NULL,
  112. 0, 0,
  113. iWidth - m_csXml.cx, iHeight - m_csXml.cy,
  114. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE
  115. );
  116. ::EndDeferWindowPos(hdwp);
  117. }
  118. return 0;
  119. }
  120. LRESULT CMainDlg::OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  121. {
  122. // do nothing to eat up Esc key
  123. return 0;
  124. }
  125. LRESULT CMainDlg::OnExit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  126. {
  127. EndDialog(IDOK); // close dialog
  128. return 0;
  129. }
  130. LRESULT CMainDlg::OnTryFile(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  131. {
  132. CWaitCursor wc;
  133. // create writer
  134. CComPtr<IMXWriter> pWriter;
  135. HRESULT hr = pWriter.CoCreateInstance(__uuidof(MXXMLWriter), NULL);
  136. _ASSERT(SUCCEEDED(hr));
  137. // create reader
  138. CComPtr<ISAXXMLReader> pReader;
  139. hr = pReader.CoCreateInstance(__uuidof(SAXXMLReader), NULL);
  140. _ASSERT(SUCCEEDED(hr));
  141. // set up handlers
  142. CComQIPtr<ISAXContentHandler> pContentHandler(pWriter);
  143. CComQIPtr<ISAXDTDHandler> pDTDHandler(pWriter);
  144. CComQIPtr<ISAXErrorHandler> pErrorHandler(pWriter);
  145. hr = pReader->putContentHandler(pContentHandler);
  146. _ASSERT(SUCCEEDED(hr));
  147. hr = pReader->putDTDHandler(pDTDHandler);
  148. _ASSERT(SUCCEEDED(hr));
  149. hr = pReader->putErrorHandler(pErrorHandler);
  150. _ASSERT(SUCCEEDED(hr));
  151. // put properties
  152. CComVariant var;
  153. var = (LPUNKNOWN)pWriter;
  154. hr = pReader->putProperty(
  155. L"http://xml.org/sax/properties/declaration-handler",
  156. var
  157. );
  158. _ASSERT(SUCCEEDED(hr));
  159. hr = pReader->putProperty(
  160. L"http://xml.org/sax/properties/lexical-handler",
  161. var
  162. );
  163. _ASSERT(SUCCEEDED(hr));
  164. // set parameters, clean the scene
  165. m_wndEvents.SetWindowText(_T(""));
  166. var = L"";
  167. hr = pWriter->put_output(var);
  168. _ASSERT(SUCCEEDED(hr));
  169. hr = pWriter->put_omitXMLDeclaration(VARIANT_TRUE);
  170. _ASSERT(SUCCEEDED(hr));
  171. USES_CONVERSION;
  172. // parse
  173. TCHAR szTemp[MAX_PATH];
  174. m_wndFilename.GetWindowText(szTemp, MAX_PATH);
  175. hr = pReader->parseURL(T2W(szTemp));
  176. if (SUCCEEDED(hr))
  177. {
  178. // return output
  179. var.Clear();
  180. hr = pWriter->get_output(&var);
  181. _ASSERT(SUCCEEDED(hr));
  182. OutputToXmlWindow(&var);
  183. }
  184. else
  185. {
  186. wsprintf(szTemp, _T("Error: Check if file exists in the correct placernResult Code = 0x%08X"), hr);
  187. m_wndXml.SetWindowText(szTemp);
  188. }
  189. return 0;
  190. }
  191. LRESULT CMainDlg::OnTryDemo(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  192. {
  193. CWaitCursor wc;
  194. // create writer
  195. CComPtr<IMXWriter> pWriter;
  196. HRESULT hr = pWriter.CoCreateInstance(__uuidof(MXXMLWriter), NULL);
  197. _ASSERT(SUCCEEDED(hr));
  198. // create attributes
  199. CComPtr<IMXAttributes> pMXAttrs;
  200. hr = pMXAttrs.CoCreateInstance(__uuidof(SAXAttributes), NULL);
  201. _ASSERT(SUCCEEDED(hr));
  202. CComQIPtr<ISAXAttributes> pSAXAttrs(pMXAttrs);
  203. // set them all to writer, writer implements all these interfaces
  204. CComQIPtr<ISAXContentHandler> pContentHandler(pWriter);
  205. CComQIPtr<ISAXDTDHandler> pDTDHandler(pWriter);
  206. CComQIPtr<ISAXLexicalHandler> pLexicalHandler(pWriter);
  207. CComQIPtr<ISAXDeclHandler> pDeclHandler(pWriter);
  208. CComQIPtr<ISAXErrorHandler> pErrorHandler(pWriter);
  209. // set parameters, clean the scene
  210. m_wndEvents.SetWindowText(_T(""));
  211. CComVariant var(L"");
  212. hr = pWriter->put_output(var);
  213. _ASSERT(SUCCEEDED(hr));
  214. // and manually call necessary events to generate XML file
  215. Log(_T("Content->startDocument"));
  216. pContentHandler->startDocument();
  217. Log(_T("Lexical->startDTD"));
  218. pLexicalHandler->startDTD(
  219. L"MyDTD", lstrlenW(L"MyDTD"),
  220. L"", 0,
  221. L"http://eureka.sample/mydtd.dtd", lstrlenW(L"http://eureka.sample/mydtd.dtd")
  222. );
  223. Log(_T("Decl->elementDecl"));
  224. pDeclHandler->elementDecl(
  225. L"book", lstrlenW(L"book"),
  226. L"title | descr", lstrlenW(L"title | descr")
  227. );
  228. Log(_T("Decl->attributeDecl"));
  229. pDeclHandler->attributeDecl(
  230. L"book", lstrlenW(L"book"),
  231. L"author", lstrlenW(L"author"),
  232. L"CDATA", lstrlenW(L"CDATA"),
  233. L"#IMPLIED", lstrlenW(L"#IMPLIED"),
  234. L"", lstrlenW(L"")
  235. );
  236. Log(_T("Decl->attributeDecl"));
  237. pDeclHandler->attributeDecl(
  238. L"book", lstrlenW(L"book"),
  239. L"ISBN", lstrlenW(L"ISBN"),
  240. L"CDATA", lstrlenW(L"CDATA"),
  241. L"#REQUIRED", lstrlenW(L"#REQUIRED"),
  242. L"000000000", lstrlenW(L"000000000")
  243. );
  244. Log(_T("Decl->attributeDecl"));
  245. pDeclHandler->attributeDecl(
  246. L"book", lstrlenW(L"book"),
  247. L"cover", lstrlenW(L"cover"),
  248. L"(hard|soft)", lstrlenW(L"(hard|soft)"),
  249. L"", lstrlenW(L""),
  250. L"soft", lstrlenW(L"soft")
  251. );
  252. Log(_T("Decl-elementDecl"));
  253. pDeclHandler->elementDecl(
  254. L"title", lstrlenW(L"title"),
  255. L"(#PCDATA)", lstrlenW(L"(#PCDATA)")
  256. );
  257. Log(_T("Decl-elementDecl"));
  258. pDeclHandler->elementDecl(
  259. L"descr", lstrlenW(L"descr"),
  260. L"(#PCDATA)", lstrlenW(L"(#PCDATA)")
  261. );
  262. Log(_T("Lexical->endDTD"));
  263. pLexicalHandler->endDTD();
  264. Log(_T("Content->startElement"));
  265. pMXAttrs->addAttribute(
  266. CComBSTR(""),
  267. CComBSTR(""),
  268. CComBSTR("cover"),
  269. CComBSTR(""),
  270. CComBSTR("hard")
  271. );
  272. pContentHandler->startElement(
  273. L"", lstrlenW(L""),
  274. L"", lstrlenW(L""),
  275. L"book", lstrlenW(L"book"),
  276. pSAXAttrs
  277. );
  278. Log(_T("Content->startElement"));
  279. pMXAttrs->clear();
  280. pContentHandler->startElement(
  281. L"", lstrlenW(L""),
  282. L"", lstrlenW(L""),
  283. L"title", lstrlenW(L"title"),
  284. pSAXAttrs
  285. );
  286. Log(_T("Content->characters"));
  287. pContentHandler->characters(
  288. L"On the Circular Problem of Quadratic Equations",
  289. lstrlenW(L"On the Circular Problem of Quadratic Equations")
  290. );
  291. Log(_T("Content->endElement"));
  292. pContentHandler->endElement(
  293. L"", lstrlenW(L""),
  294. L"", lstrlenW(L""),
  295. L"title", lstrlenW(L"title")
  296. );
  297. Log(_T("Content->endElement"));
  298. pContentHandler->endElement(
  299. L"", lstrlenW(L""),
  300. L"", lstrlenW(L""),
  301. L"book", lstrlenW(L"book")
  302. );
  303. // output XML
  304. var.Clear();
  305. hr = pWriter->get_output(&var);
  306. _ASSERT(SUCCEEDED(hr));
  307. OutputToXmlWindow(&var);
  308. return 0;
  309. }
  310. void CMainDlg::Init()
  311. {
  312. // calculate minimum window size
  313. RECT rc;
  314. GetWindowRect(&rc);
  315. m_csMinSize.cx = rc.right - rc.left;
  316. m_csMinSize.cy = rc.bottom - rc.top;
  317. RECT rcCtrl;
  318. GetClientRect(&rc);
  319. // calculate "File Name" edit box resizing info
  320. ::GetWindowRect(GetDlgItem(IDC_FILENAME), &rcCtrl);
  321. ScreenToClient(&rcCtrl);
  322. m_csFilename.cx = (rc.right - rc.left) -
  323. (rcCtrl.right - rcCtrl.left); // store width difference
  324. m_csFilename.cy = rcCtrl.bottom - rcCtrl.top; // store control height
  325. // calculate "Try File" button resizing info
  326. ::GetWindowRect(GetDlgItem(IDC_TRYFILE), &rcCtrl);
  327. ScreenToClient(&rcCtrl);
  328. m_csTryFile.cx = rc.right - rcCtrl.left; // store right offset
  329. m_csTryFile.cy = rcCtrl.top - rc.top; // store top offset
  330. // calculate "Try Demo" button resizing info
  331. ::GetWindowRect(GetDlgItem(IDC_TRYDEMO), &rcCtrl);
  332. ScreenToClient(&rcCtrl);
  333. m_csTryDemo.cx = rc.right - rcCtrl.left; // store right offset
  334. m_csTryDemo.cy = rcCtrl.top - rc.top; // store top offset
  335. // calculate "Exit" button resizing info
  336. ::GetWindowRect(GetDlgItem(IDC_EXIT), &rcCtrl);
  337. ScreenToClient(&rcCtrl);
  338. m_csExit.cx = rc.right - rcCtrl.left; // store right offset
  339. m_csExit.cy = rcCtrl.top - rc.top; // store top offset
  340. // calculate separator resizing info
  341. ::GetWindowRect(GetDlgItem(IDC_SEPARATOR), &rcCtrl);
  342. ScreenToClient(&rcCtrl);
  343. m_csSeparator.cx = (rc.right - rc.left) -
  344. (rcCtrl.right - rcCtrl.left); // store width difference
  345. m_csSeparator.cy = rcCtrl.bottom - rcCtrl.top; // store control height
  346. // calculate "Events" label resizing info
  347. ::GetWindowRect(GetDlgItem(IDC_EVENTS_LABEL), &rcCtrl);
  348. ScreenToClient(&rcCtrl);
  349. m_csEventsLabel.cx = rcCtrl.left - rc.left; // store left offset
  350. m_csEventsLabel.cy = rcCtrl.top - rc.top; // store top offset
  351. // calculate "Events" edit box resizing info
  352. ::GetWindowRect(GetDlgItem(IDC_EVENTS), &rcCtrl);
  353. ScreenToClient(&rcCtrl);
  354. m_csEvents.cx = rcCtrl.right - rcCtrl.left; // store width
  355. m_csEvents.cy = (rc.bottom - rc.top) -
  356. (rcCtrl.bottom - rcCtrl.top); // store height difference
  357. // calculate "XML" label resizing info
  358. ::GetWindowRect(GetDlgItem(IDC_XML_LABEL), &rcCtrl);
  359. ScreenToClient(&rcCtrl);
  360. m_csXmlLabel.cx = rcCtrl.left - rc.left; // store left offset
  361. m_csXmlLabel.cy = rcCtrl.top - rc.top; // store top offset
  362. // calculate "XML" edit box resizing info
  363. ::GetWindowRect(GetDlgItem(IDC_XML), &rcCtrl);
  364. ScreenToClient(&rcCtrl);
  365. m_csXml.cx = (rc.right - rc.left) -
  366. (rcCtrl.right - rcCtrl.left); // store width difference
  367. m_csXml.cy = (rc.bottom - rc.top) -
  368. (rcCtrl.bottom - rcCtrl.top); // store height difference
  369. // attach window class to controls (I am lazy to use raw SendMessage)
  370. m_wndFilename.Attach(GetDlgItem(IDC_FILENAME));
  371. m_wndEvents.Attach(GetDlgItem(IDC_EVENTS));
  372. m_wndXml.Attach(GetDlgItem(IDC_XML));
  373. // limit text for safety
  374. m_wndFilename.SendMessage(EM_LIMITTEXT, MAX_PATH);
  375. // I like smaller tabstops
  376. UINT nTabStops = 16;
  377. m_wndEvents.SendMessage(EM_SETTABSTOPS, 1, (LPARAM)&nTabStops);
  378. m_wndXml.SendMessage(EM_SETTABSTOPS, 1, (LPARAM)&nTabStops);
  379. m_bInit = TRUE;
  380. }
  381. void CMainDlg::OutputToXmlWindow(VARIANT* pVar)
  382. {
  383. LPTSTR pszOutput;
  384. #ifndef UNICODE
  385. // since output can be quite large, ATL's internal conversion is not going make it
  386. int iSize = ::SysStringLen(V_BSTR(pVar)) + 1;
  387. pszOutput = new CHAR[iSize];
  388. _ASSERT(pszOutput);
  389. ::WideCharToMultiByte(
  390. ::GetACP(),
  391. 0,
  392. (LPWSTR)V_BSTR(pVar),
  393. -1,
  394. pszOutput,
  395. iSize,
  396. NULL,
  397. NULL
  398. );
  399. #else
  400. pszOutput = (LPWSTR)V_BSTR(pVar);
  401. #endif
  402. m_wndXml.SetWindowText(pszOutput);
  403. #ifndef UNICODE
  404. delete [] pszOutput;
  405. #endif
  406. }
  407. void CMainDlg::Log(LPCTSTR pszMsg)
  408. {
  409. // set selection to the end and append
  410. int iLen = m_wndEvents.GetWindowTextLength();
  411. m_wndEvents.SendMessage(EM_SETSEL, (WPARAM)iLen, (LPARAM)iLen);
  412. m_wndEvents.SendMessage(EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)pszMsg);
  413. // put a new line
  414. m_wndEvents.SendMessage(EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)_T("rn"));
  415. }