SimpleBrowser.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281
  1. /////////////////////////////////////////////////////////////////////////////
  2. // SimpleBrowser.cpp: Web browser control
  3. /////////////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "comdef.h"
  6. #include "mshtml.h"
  7. #include "mshtmcid.h"
  8. #include "mshtmhst.h"
  9. #include "exdispid.h"
  10. #include "SimpleBrowser.h"
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. #define Unused(parameter) parameter // avoid compile warnings
  17. // about unused parameters
  18. /////////////////////////////////////////////////////////////////////////////
  19. // Construction and creation
  20. /////////////////////////////////////////////////////////////////////////////
  21. SimpleBrowser::SimpleBrowser()
  22. : _Browser(NULL),
  23. _BrowserDispatch(NULL),
  24. _Ready(false),
  25. _Content(_T(""))
  26. {
  27. }
  28. SimpleBrowser::~SimpleBrowser()
  29. {
  30. // release browser interfaces
  31. if (_Browser != NULL) {
  32. _Browser->Release();
  33. _Browser = NULL;
  34. }
  35. if (_BrowserDispatch != NULL) {
  36. _BrowserDispatch->Release();
  37. _BrowserDispatch = NULL;
  38. }
  39. }
  40. // Standard create
  41. BOOL SimpleBrowser::Create(DWORD dwStyle,
  42. const RECT& rect,
  43. CWnd* pParentWnd,
  44. UINT nID)
  45. {
  46. BOOL results = TRUE;
  47. _Ready = false;
  48. _Browser = NULL;
  49. // create this window
  50. CWnd *window = this;
  51. results = window->Create(AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW),
  52. NULL,
  53. dwStyle,
  54. rect,
  55. pParentWnd,
  56. nID);
  57. if (!results) return FALSE;
  58. // create browser control window as child of this window;
  59. // this window sinks events from control
  60. CRect browser_window_rect(0,0,(rect.right - rect.left),(rect.bottom - rect.top));
  61. results = _BrowserWindow.CreateControl(CLSID_WebBrowser,
  62. NULL,
  63. (WS_VISIBLE | WS_TABSTOP),
  64. browser_window_rect,
  65. this,
  66. AFX_IDW_PANE_FIRST);
  67. if (!results) {
  68. DestroyWindow();
  69. return FALSE;
  70. }
  71. // get control interfaces
  72. LPUNKNOWN unknown = _BrowserWindow.GetControlUnknown();
  73. HRESULT hr = unknown->QueryInterface(IID_IWebBrowser2,(void **)&_Browser);
  74. if (SUCCEEDED(hr)) {
  75. hr = unknown->QueryInterface(IID_IDispatch,(void **)&_BrowserDispatch);
  76. }
  77. if (!SUCCEEDED(hr)) {
  78. _BrowserWindow.DestroyWindow();
  79. DestroyWindow();
  80. return FALSE;
  81. }
  82. // navigate to initial blank page
  83. if (_Browser != NULL) {
  84. Navigate(_T("about:blank"));
  85. }
  86. return TRUE;
  87. }
  88. // Create in place of dialog control
  89. BOOL SimpleBrowser::CreateFromControl(CWnd *pParentWnd,UINT nID,DWORD dwStyle)
  90. {
  91. BOOL result = FALSE;
  92. ASSERT(pParentWnd != NULL);
  93. CWnd *control = pParentWnd->GetDlgItem(nID);
  94. if (control != NULL) {
  95. // get control location
  96. CRect rect;
  97. control->GetWindowRect(&rect);
  98. pParentWnd->ScreenToClient(&rect);
  99. // destroy control, since the browser will take its place
  100. control->DestroyWindow();
  101. // create browser
  102. result = Create(dwStyle,
  103. rect,
  104. pParentWnd,
  105. nID);
  106. }
  107. return result;
  108. }
  109. // Destruction
  110. void SimpleBrowser::PostNcDestroy()
  111. {
  112. // release browser interfaces
  113. if (_Browser != NULL) {
  114. _Browser->Release();
  115. _Browser = NULL;
  116. }
  117. if (_BrowserDispatch != NULL) {
  118. _BrowserDispatch->Release();
  119. _BrowserDispatch = NULL;
  120. }
  121. _Ready = false;
  122. _Content = _T("");
  123. CWnd::PostNcDestroy();
  124. }
  125. /////////////////////////////////////////////////////////////////////////////
  126. // Controls
  127. /////////////////////////////////////////////////////////////////////////////
  128. // Navigate to URL
  129. void SimpleBrowser::Copy()
  130. {
  131. if (_Browser != NULL) {
  132. _Browser->ExecWB(OLECMDID_COPY, OLECMDEXECOPT_DONTPROMPTUSER, NULL, NULL);
  133. }
  134. }
  135. void SimpleBrowser::Navigate(LPCTSTR URL)
  136. {
  137. _Ready = false;
  138. _Content = _T("");
  139. if (_Browser != NULL) {
  140. CString url(URL);
  141. _variant_t flags(0L,VT_I4);
  142. _variant_t target_frame_name("");
  143. _variant_t post_data("");
  144. _variant_t headers("");
  145. _Browser->Navigate(url.AllocSysString(),
  146. &flags,
  147. &target_frame_name,
  148. &post_data,
  149. &headers);
  150. }
  151. }
  152. // Navigate to HTML document in resource
  153. void SimpleBrowser::NavigateResource(int resource_ID)
  154. {
  155. if (_Browser != NULL) {
  156. CString resource_string;
  157. // load HTML document from resource
  158. HRSRC resource_handle = FindResource(AfxGetResourceHandle(),
  159. MAKEINTRESOURCE(resource_ID),
  160. RT_HTML);
  161. if (resource_handle != NULL) {
  162. HGLOBAL resource = LoadResource(AfxGetResourceHandle(),
  163. resource_handle);
  164. if (resource != NULL) {
  165. LPVOID resource_memory = LockResource(resource);
  166. if (resource_memory != NULL) {
  167. DWORD resource_size = SizeofResource(AfxGetResourceHandle(),
  168. resource_handle);
  169. // identify the resource document as MBCS (e.g. ANSI)
  170. // or UNICODE
  171. bool UNICODE_document = false;
  172. wchar_t *UNICODE_memory = (wchar_t *)resource_memory;
  173. int UNICODE_size = resource_size / sizeof(wchar_t);
  174. if (UNICODE_size >= 1) {
  175. // check for UNICODE byte order mark
  176. if (*UNICODE_memory == L'\xFEFF') {
  177. UNICODE_document = true;
  178. UNICODE_memory += 1;
  179. UNICODE_size -= 1;
  180. }
  181. // otherwise, check for UNICODE leading tag
  182. else if (UNICODE_size >= 5) {
  183. if ((UNICODE_memory[0] == L'<') &&
  184. (towupper(UNICODE_memory[1]) == L'H') &&
  185. (towupper(UNICODE_memory[2]) == L'T') &&
  186. (towupper(UNICODE_memory[3]) == L'M') &&
  187. (towupper(UNICODE_memory[4]) == L'L')) {
  188. UNICODE_document = true;
  189. }
  190. }
  191. // Note: This logic assumes that the UNICODE resource document is
  192. // in little-endian byte order, which would be typical for
  193. // any HTML document used as a resource in a Windows application.
  194. }
  195. // convert resource document if required
  196. #if !defined(UNICODE)
  197. if (UNICODE_document) {
  198. char *MBCS_buffer = resource_string.GetBufferSetLength(resource_size + 1);
  199. int MBCS_length = ::WideCharToMultiByte(CP_ACP,
  200. 0,
  201. UNICODE_memory,
  202. UNICODE_size,
  203. MBCS_buffer,
  204. resource_size + 1,
  205. NULL,
  206. NULL);
  207. resource_string.ReleaseBuffer(MBCS_length);
  208. }
  209. else {
  210. resource_string = CString((char *)resource_memory,resource_size);
  211. }
  212. #else
  213. if (UNICODE_document) {
  214. resource_string = CString(UNICODE_memory,UNICODE_size);
  215. }
  216. else {
  217. wchar_t *UNICODE_buffer = resource_string.GetBufferSetLength(resource_size + 1);
  218. int UNICODE_length = ::MultiByteToWideChar(CP_ACP,
  219. 0,
  220. (const char *)resource_memory,
  221. resource_size,
  222. UNICODE_buffer,
  223. (resource_size + 1));
  224. resource_string.ReleaseBuffer(UNICODE_length);
  225. }
  226. #endif
  227. }
  228. }
  229. }
  230. Clear();
  231. Write(resource_string);
  232. }
  233. }
  234. // Append string to current document
  235. void SimpleBrowser::Write(LPCTSTR string)
  236. {
  237. if (_Browser != NULL) {
  238. _Content.Append(string);
  239. _ContentWrite();
  240. }
  241. }
  242. void SimpleBrowser::Clear()
  243. {
  244. if (_Browser != NULL) {
  245. _Content = _T("");
  246. // get document interface
  247. IHTMLDocument2 *document = GetDocument();
  248. HRESULT hr = S_OK;
  249. if (document != NULL) {
  250. // close and re-open document to empty contents
  251. document->close();
  252. VARIANT open_name;
  253. VARIANT open_features;
  254. VARIANT open_replace;
  255. IDispatch *open_window = NULL;
  256. ::VariantInit(&open_name);
  257. open_name.vt = VT_BSTR;
  258. open_name.bstrVal = ::SysAllocString(L"_self");
  259. ::VariantInit(&open_features);
  260. ::VariantInit(&open_replace);
  261. hr = document->open(::SysAllocString(L"text/html"),
  262. open_name,
  263. open_features,
  264. open_replace,
  265. &open_window);
  266. if (hr == S_OK) {
  267. Refresh();
  268. }
  269. if (open_window != NULL) {
  270. open_window->Release();
  271. }
  272. ::VariantClear(&open_name);
  273. document->Release();
  274. document = NULL;
  275. }
  276. else {
  277. Navigate(_T("about:blank"));
  278. }
  279. }
  280. }
  281. // Navigation operations
  282. void SimpleBrowser::GoBack()
  283. {
  284. if (_Browser != NULL) {
  285. _Browser->GoBack();
  286. }
  287. }
  288. void SimpleBrowser::GoForward()
  289. {
  290. if (_Browser != NULL) {
  291. _Browser->GoForward();
  292. }
  293. }
  294. void SimpleBrowser::GoHome()
  295. {
  296. if (_Browser != NULL) {
  297. _Browser->GoHome();
  298. }
  299. }
  300. void SimpleBrowser::Refresh()
  301. {
  302. if (_Browser != NULL) {
  303. _Browser->Refresh();
  304. }
  305. }
  306. void SimpleBrowser::Stop()
  307. {
  308. if (_Browser != NULL) {
  309. _Browser->Stop();
  310. }
  311. }
  312. // Print contents
  313. void SimpleBrowser::Print(LPCTSTR header,LPCTSTR footer)
  314. {
  315. if (_Browser != NULL) {
  316. // construct two element SAFEARRAY;
  317. // first element is header string, second element is footer string
  318. HRESULT hr;
  319. VARIANT header_variant;
  320. VariantInit(&header_variant);
  321. V_VT(&header_variant) = VT_BSTR;
  322. V_BSTR(&header_variant) = CString(header).AllocSysString();
  323. VARIANT footer_variant;
  324. VariantInit(&footer_variant);
  325. V_VT(&footer_variant) = VT_BSTR;
  326. V_BSTR(&footer_variant) = CString(footer).AllocSysString();
  327. long index;
  328. SAFEARRAYBOUND parameter_array_bound[1];
  329. SAFEARRAY *parameter_array = NULL;
  330. parameter_array_bound[0].cElements = 2;
  331. parameter_array_bound[0].lLbound = 0;
  332. parameter_array = SafeArrayCreate(VT_VARIANT,1,parameter_array_bound);
  333. index = 0;
  334. hr = SafeArrayPutElement(parameter_array,&index,&header_variant);
  335. index = 1;
  336. hr = SafeArrayPutElement(parameter_array,&index,&footer_variant);
  337. VARIANT parameter;
  338. VariantInit(&parameter);
  339. V_VT(&parameter) = VT_ARRAY | VT_BYREF;
  340. V_ARRAY(&parameter) = parameter_array;
  341. // start printing browser contents
  342. hr = _Browser->ExecWB(OLECMDID_PRINT,OLECMDEXECOPT_DODEFAULT,&parameter,NULL);
  343. // release SAFEARRAY
  344. if (!SUCCEEDED(hr)) {
  345. VariantClear(&header_variant);
  346. VariantClear(&footer_variant);
  347. if (parameter_array != NULL) {
  348. SafeArrayDestroy(parameter_array);
  349. }
  350. }
  351. }
  352. }
  353. void SimpleBrowser::PrintPreview()
  354. {
  355. if (_Browser != NULL) {
  356. _Browser->ExecWB(OLECMDID_PRINTPREVIEW,OLECMDEXECOPT_DODEFAULT,NULL,NULL);
  357. }
  358. }
  359. // Miscellaneous
  360. bool SimpleBrowser::GetBusy()
  361. {
  362. bool busy = false;
  363. if (_Browser != NULL) {
  364. VARIANT_BOOL variant_bool;
  365. HRESULT hr = _Browser->get_Busy(&variant_bool);
  366. if (SUCCEEDED(hr)) {
  367. busy = (variant_bool == VARIANT_TRUE);
  368. }
  369. }
  370. return busy;
  371. }
  372. CString SimpleBrowser::GetLocationName()
  373. {
  374. CString location_name = _T("");
  375. if (_Browser != NULL) {
  376. BSTR location_name_BSTR = NULL;
  377. HRESULT hr = _Browser->get_LocationName(&location_name_BSTR);
  378. if (SUCCEEDED(hr)) {
  379. location_name = location_name_BSTR;
  380. }
  381. ::SysFreeString(location_name_BSTR);
  382. }
  383. return location_name;
  384. }
  385. CString SimpleBrowser::GetLocationURL()
  386. {
  387. CString location_URL = _T("");
  388. if (_Browser != NULL) {
  389. BSTR location_URL_BSTR = NULL;
  390. HRESULT hr = _Browser->get_LocationURL(&location_URL_BSTR);
  391. if (SUCCEEDED(hr)) {
  392. location_URL = location_URL_BSTR;
  393. }
  394. ::SysFreeString(location_URL_BSTR);
  395. }
  396. return location_URL;
  397. }
  398. READYSTATE SimpleBrowser::GetReadyState()
  399. {
  400. READYSTATE readystate = READYSTATE_UNINITIALIZED;
  401. if (_Browser != NULL) {
  402. _Browser->get_ReadyState(&readystate);
  403. }
  404. return readystate;
  405. }
  406. bool SimpleBrowser::GetSilent()
  407. {
  408. bool silent = false;
  409. if (_Browser != NULL) {
  410. VARIANT_BOOL silent_variant;
  411. HRESULT hr = _Browser->get_Silent(&silent_variant);
  412. if (SUCCEEDED(hr)) {
  413. silent = (silent_variant == VARIANT_TRUE);
  414. }
  415. }
  416. return silent;
  417. }
  418. void SimpleBrowser::PutSilent(bool silent)
  419. {
  420. if (_Browser != NULL) {
  421. VARIANT_BOOL silent_variant;
  422. if (silent) silent_variant = VARIANT_TRUE;
  423. else silent_variant = VARIANT_FALSE;
  424. _Browser->put_Silent(silent_variant);
  425. }
  426. }
  427. IHTMLDocument2 *SimpleBrowser::GetDocument()
  428. {
  429. IHTMLDocument2 *document = NULL;
  430. if (_Browser != NULL) {
  431. // get browser document's dispatch interface
  432. IDispatch *document_dispatch = NULL;
  433. HRESULT hr = _Browser->get_Document(&document_dispatch);
  434. if (SUCCEEDED(hr) && (document_dispatch != NULL)) {
  435. // get the actual document interface
  436. hr = document_dispatch->QueryInterface(IID_IHTMLDocument2,
  437. (void **)&document);
  438. // release dispatch interface
  439. document_dispatch->Release();
  440. }
  441. }
  442. return document;
  443. }
  444. /////////////////////////////////////////////////////////////////////////////
  445. // Message handlers
  446. /////////////////////////////////////////////////////////////////////////////
  447. BEGIN_MESSAGE_MAP(SimpleBrowser,CWnd)
  448. //{{AFX_MSG_MAP(SimpleBrowser)
  449. ON_WM_SIZE()
  450. //}}AFX_MSG_MAP
  451. END_MESSAGE_MAP()
  452. BOOL SimpleBrowser::PreTranslateMessage(MSG *pMsg)
  453. {
  454. BOOL result = FALSE;
  455. // translate keys correctly, especially Tab, Del, (Enter?)
  456. if (_Browser != NULL) {
  457. IOleInPlaceActiveObject* OleInPlaceActiveObject = NULL;
  458. HRESULT hr = _Browser->QueryInterface(IID_IOleInPlaceActiveObject, (void**)&OleInPlaceActiveObject);
  459. if (SUCCEEDED(hr) && (OleInPlaceActiveObject != NULL)) {
  460. hr = OleInPlaceActiveObject->TranslateAccelerator(pMsg);
  461. result = (hr == S_OK ? TRUE : FALSE);
  462. OleInPlaceActiveObject->Release();
  463. }
  464. }
  465. else {
  466. result = CWnd::PreTranslateMessage(pMsg);
  467. }
  468. return result;
  469. }
  470. // Resize control window as this window is resized
  471. void SimpleBrowser::OnSize(UINT nType, int cx, int cy)
  472. {
  473. CWnd::OnSize(nType, cx, cy);
  474. if (_Browser != NULL) {
  475. CRect rect(0,0,cx,cy);
  476. _BrowserWindow.MoveWindow(&rect);
  477. }
  478. }
  479. /////////////////////////////////////////////////////////////////////////////
  480. // Event handlers
  481. /////////////////////////////////////////////////////////////////////////////
  482. #ifndef DISPID_PRINTTEMPLATEINSTANTIATION
  483. #define DISPID_PRINTTEMPLATEINSTANTIATION 225
  484. #endif
  485. #ifndef DISPID_PRINTTEMPLATETEARDOWN
  486. #define DISPID_PRINTTEMPLATETEARDOWN 226
  487. #endif
  488. BEGIN_EVENTSINK_MAP(SimpleBrowser,CWnd)
  489. ON_EVENT(SimpleBrowser,AFX_IDW_PANE_FIRST,
  490. DISPID_BEFORENAVIGATE2,
  491. _OnBeforeNavigate2,
  492. VTS_DISPATCH VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PBOOL)
  493. ON_EVENT(SimpleBrowser,AFX_IDW_PANE_FIRST,
  494. DISPID_DOCUMENTCOMPLETE,
  495. _OnDocumentComplete,
  496. VTS_DISPATCH VTS_PVARIANT)
  497. ON_EVENT(SimpleBrowser,AFX_IDW_PANE_FIRST,
  498. DISPID_DOWNLOADBEGIN,
  499. _OnDownloadBegin,
  500. VTS_NONE)
  501. ON_EVENT(SimpleBrowser,AFX_IDW_PANE_FIRST,
  502. DISPID_PROGRESSCHANGE,
  503. _OnProgressChange,
  504. VTS_I4 VTS_I4)
  505. ON_EVENT(SimpleBrowser,AFX_IDW_PANE_FIRST,
  506. DISPID_DOWNLOADCOMPLETE,
  507. _OnDownloadComplete,
  508. VTS_NONE)
  509. ON_EVENT(SimpleBrowser,AFX_IDW_PANE_FIRST,
  510. DISPID_NAVIGATECOMPLETE2,
  511. _OnNavigateComplete2,
  512. VTS_DISPATCH VTS_PVARIANT)
  513. ON_EVENT(SimpleBrowser,AFX_IDW_PANE_FIRST,
  514. DISPID_STATUSTEXTCHANGE,
  515. _OnStatusTextChange,
  516. VTS_BSTR)
  517. ON_EVENT(SimpleBrowser,AFX_IDW_PANE_FIRST,
  518. DISPID_TITLECHANGE,
  519. _OnTitleChange,
  520. VTS_BSTR)
  521. ON_EVENT(SimpleBrowser,AFX_IDW_PANE_FIRST,
  522. DISPID_PRINTTEMPLATEINSTANTIATION,
  523. _OnPrintTemplateInstantiation,
  524. VTS_DISPATCH)
  525. ON_EVENT(SimpleBrowser,AFX_IDW_PANE_FIRST,
  526. DISPID_PRINTTEMPLATETEARDOWN,
  527. _OnPrintTemplateTeardown,
  528. VTS_DISPATCH)
  529. END_EVENTSINK_MAP()
  530. SimpleBrowser::Notification::Notification(HWND hwnd,UINT ID,NotificationType type)
  531. {
  532. hdr.hwndFrom = hwnd;
  533. hdr.idFrom = ID;
  534. hdr.code = type;
  535. URL = _T("");
  536. frame = _T("");
  537. post_data = NULL;
  538. post_data_size = 0;
  539. headers = _T("");
  540. progress = 0;
  541. progress_max = 0;
  542. text = _T("");
  543. }
  544. SimpleBrowser::Notification::~Notification()
  545. {
  546. }
  547. // Called before navigation begins; application may cancel if required
  548. void SimpleBrowser::_OnBeforeNavigate2(LPDISPATCH lpDisp,
  549. VARIANT FAR *URL,
  550. VARIANT FAR *Flags,
  551. VARIANT FAR *TargetFrameName,
  552. VARIANT FAR *PostData,
  553. VARIANT FAR *Headers,
  554. VARIANT_BOOL *Cancel)
  555. {
  556. Unused(Flags); // Note: flags value is reserved
  557. if (lpDisp == _BrowserDispatch) {
  558. CString URL_string;
  559. CString frame;
  560. unsigned char *post_data = NULL;
  561. int post_data_size = 0;
  562. CString headers;
  563. if ((URL != NULL) &&
  564. (V_VT(URL) == VT_BSTR)) {
  565. URL_string = V_BSTR(URL);
  566. }
  567. if ((TargetFrameName != NULL) &&
  568. (V_VT(TargetFrameName) == VT_BSTR)) {
  569. frame = V_BSTR(TargetFrameName);
  570. }
  571. if ((PostData != NULL) &&
  572. (V_VT(PostData) == (VT_VARIANT | VT_BYREF))) {
  573. VARIANT *PostData_variant = V_VARIANTREF(PostData);
  574. if ((PostData_variant != NULL) &&
  575. (V_VT(PostData_variant) != VT_EMPTY)) {
  576. SAFEARRAY *PostData_safearray = V_ARRAY(PostData_variant);
  577. if (PostData_safearray != NULL) {
  578. char *post_data_array = NULL;
  579. SafeArrayAccessData(PostData_safearray,(void HUGEP **)&post_data_array);
  580. long lower_bound = 1;
  581. long upper_bound = 1;
  582. SafeArrayGetLBound(PostData_safearray,1,&lower_bound);
  583. SafeArrayGetUBound(PostData_safearray,1,&upper_bound);
  584. post_data_size = (int)(upper_bound - lower_bound + 1);
  585. post_data = new unsigned char[post_data_size];
  586. memcpy(post_data,post_data_array,post_data_size);
  587. SafeArrayUnaccessData(PostData_safearray);
  588. }
  589. }
  590. }
  591. if ((Headers != NULL) &&
  592. (V_VT(Headers) == VT_BSTR)) {
  593. headers = V_BSTR(Headers);
  594. }
  595. bool cancel = OnBeforeNavigate2(URL_string,
  596. frame,
  597. post_data,post_data_size,
  598. headers);
  599. if (Cancel != NULL) {
  600. if (cancel) *Cancel = VARIANT_TRUE;
  601. else *Cancel = VARIANT_FALSE;
  602. }
  603. delete []post_data;
  604. }
  605. }
  606. bool SimpleBrowser::OnBeforeNavigate2(CString URL,
  607. CString frame,
  608. void *post_data,int post_data_size,
  609. CString headers)
  610. {
  611. bool cancel = false;
  612. CWnd *parent = GetParent();
  613. if (parent != NULL) {
  614. Notification notification(m_hWnd,GetDlgCtrlID(),BeforeNavigate2);
  615. notification.URL = URL;
  616. notification.frame = frame;
  617. notification.post_data = post_data;
  618. notification.post_data_size = post_data_size;
  619. notification.headers = headers;
  620. LRESULT result = parent->SendMessage(WM_NOTIFY,
  621. notification.hdr.idFrom,
  622. (LPARAM)&notification);
  623. if (result) {
  624. cancel = true;
  625. }
  626. }
  627. return cancel;
  628. }
  629. bool SimpleBrowser::ParsePostData(CString post_data,
  630. CStringArray &names,
  631. CStringArray &values)
  632. {
  633. bool result = true;
  634. int size = 1;
  635. names.SetSize(size);
  636. values.SetSize(size);
  637. int offset = 0;
  638. bool parsing_name = true;
  639. CString hex(_T("0123456789ABCDEF"));
  640. while ((offset < post_data.GetLength()) && result) {
  641. if (post_data[offset] == _T('%')) {
  642. if ((offset + 2) < post_data.GetLength()) {
  643. int digit1 = hex.Find(_totupper(post_data[offset + 1]));
  644. int digit2 = hex.Find(_totupper(post_data[offset + 2]));
  645. if ((digit1 >= 0) && (digit2 >= 0)) {
  646. _TCHAR character = (_TCHAR)((digit1 << 4) + digit2);
  647. if (parsing_name) names[size - 1].AppendChar(character);
  648. else values[size - 1].AppendChar(character);
  649. }
  650. else {
  651. result = false;
  652. }
  653. offset += 2;
  654. }
  655. else {
  656. result = false;
  657. }
  658. }
  659. else if (post_data[offset] == _T('+')) {
  660. if (parsing_name) names[size - 1].AppendChar(_T(' '));
  661. else values[size - 1].AppendChar(_T(' '));
  662. }
  663. else if (post_data[offset] == _T('=')) {
  664. if (parsing_name) {
  665. parsing_name = false;
  666. }
  667. else {
  668. values[size - 1].AppendChar(post_data[offset]);
  669. }
  670. }
  671. else if (post_data[offset] == _T('&')) {
  672. if (!parsing_name) {
  673. parsing_name = true;
  674. size += 1;
  675. names.SetSize(size);
  676. values.SetSize(size);
  677. }
  678. else {
  679. values[size - 1].AppendChar(post_data[offset]);
  680. }
  681. }
  682. else {
  683. if (parsing_name) names[size - 1].AppendChar(post_data[offset]);
  684. else values[size - 1].AppendChar(post_data[offset]);
  685. }
  686. offset++;
  687. }
  688. if ((names[size - 1] == _T("")) &&
  689. (values[size - 1] == _T(""))) {
  690. names.SetSize(size - 1);
  691. values.SetSize(size - 1);
  692. }
  693. return result;
  694. }
  695. // Document loaded and initialized
  696. void SimpleBrowser::_OnDocumentComplete(LPDISPATCH lpDisp,VARIANT *URL)
  697. {
  698. if (lpDisp == _BrowserDispatch) {
  699. CString URL_string;
  700. if ((URL != NULL) &&
  701. (V_VT(URL) == VT_BSTR)) {
  702. URL_string = CString(V_BSTR(URL));
  703. }
  704. OnDocumentComplete(URL_string);
  705. }
  706. }
  707. void SimpleBrowser::OnDocumentComplete(CString URL)
  708. {
  709. CWnd *parent = GetParent();
  710. if (parent != NULL) {
  711. Notification notification(m_hWnd,GetDlgCtrlID(),DocumentComplete);
  712. notification.URL = URL;
  713. LRESULT result = parent->SendMessage(WM_NOTIFY,
  714. notification.hdr.idFrom,
  715. (LPARAM)&notification);
  716. }
  717. }
  718. // Navigation/download progress
  719. void SimpleBrowser::_OnDownloadBegin()
  720. {
  721. OnDownloadBegin();
  722. }
  723. void SimpleBrowser::OnDownloadBegin()
  724. {
  725. CWnd *parent = GetParent();
  726. if (parent != NULL) {
  727. Notification notification(m_hWnd,GetDlgCtrlID(),DownloadBegin);
  728. LRESULT result = parent->SendMessage(WM_NOTIFY,
  729. notification.hdr.idFrom,
  730. (LPARAM)&notification);
  731. }
  732. }
  733. void SimpleBrowser::_OnProgressChange(long progress,long progress_max)
  734. {
  735. OnProgressChange((int)progress,(int)progress_max);
  736. }
  737. void SimpleBrowser::OnProgressChange(int progress,int progress_max)
  738. {
  739. CWnd *parent = GetParent();
  740. if (parent != NULL) {
  741. Notification notification(m_hWnd,GetDlgCtrlID(),ProgressChange);
  742. notification.progress = progress;
  743. notification.progress_max = progress_max;
  744. LRESULT result = parent->SendMessage(WM_NOTIFY,
  745. notification.hdr.idFrom,
  746. (LPARAM)&notification);
  747. }
  748. }
  749. void SimpleBrowser::_OnDownloadComplete()
  750. {
  751. OnDownloadComplete();
  752. }
  753. void SimpleBrowser::OnDownloadComplete()
  754. {
  755. CWnd *parent = GetParent();
  756. if (parent != NULL) {
  757. Notification notification(m_hWnd,GetDlgCtrlID(),DownloadComplete);
  758. LRESULT result = parent->SendMessage(WM_NOTIFY,
  759. notification.hdr.idFrom,
  760. (LPARAM)&notification);
  761. }
  762. }
  763. // Navigation to a link has completed
  764. void SimpleBrowser::_OnNavigateComplete2(LPDISPATCH lpDisp,VARIANT *URL)
  765. {
  766. if (lpDisp == _BrowserDispatch) {
  767. // signal document ready
  768. _Ready = true;
  769. // write current content
  770. _ContentWrite();
  771. // inform user navigation complete
  772. CString URL_string;
  773. if ((URL != NULL) &&
  774. (V_VT(URL) == VT_BSTR)) {
  775. URL_string = V_BSTR(URL);
  776. }
  777. OnNavigateComplete2(URL_string);
  778. }
  779. }
  780. void SimpleBrowser::OnNavigateComplete2(CString URL)
  781. {
  782. CWnd *parent = GetParent();
  783. if (parent != NULL) {
  784. Notification notification(m_hWnd,GetDlgCtrlID(),NavigateComplete2);
  785. notification.URL = URL;
  786. LRESULT result = parent->SendMessage(WM_NOTIFY,
  787. notification.hdr.idFrom,
  788. (LPARAM)&notification);
  789. }
  790. }
  791. // Status text has changed
  792. void SimpleBrowser::_OnStatusTextChange(BSTR bstrText)
  793. {
  794. CString text;
  795. if (bstrText != NULL) {
  796. text = (LPCTSTR)bstrText;
  797. }
  798. OnStatusTextChange(text);
  799. }
  800. void SimpleBrowser::OnStatusTextChange(CString text)
  801. {
  802. CWnd *parent = GetParent();
  803. if (parent != NULL) {
  804. Notification notification(m_hWnd,GetDlgCtrlID(),StatusTextChange);
  805. notification.text = text;
  806. LRESULT result = parent->SendMessage(WM_NOTIFY,
  807. notification.hdr.idFrom,
  808. (LPARAM)&notification);
  809. }
  810. }
  811. // Title text has changed
  812. void SimpleBrowser::_OnTitleChange(BSTR bstrText)
  813. {
  814. CString text;
  815. if (bstrText != NULL) {
  816. text = (LPCTSTR)bstrText;
  817. }
  818. OnTitleChange(text);
  819. }
  820. void SimpleBrowser::OnTitleChange(CString text)
  821. {
  822. CWnd *parent = GetParent();
  823. if (parent != NULL) {
  824. Notification notification(m_hWnd,GetDlgCtrlID(),TitleChange);
  825. notification.text = text;
  826. LRESULT result = parent->SendMessage(WM_NOTIFY,
  827. notification.hdr.idFrom,
  828. (LPARAM)&notification);
  829. }
  830. }
  831. // Print template instantiation and teardown
  832. void SimpleBrowser::_OnPrintTemplateInstantiation(LPDISPATCH lpDisp)
  833. {
  834. OnPrintTemplateInstantiation();
  835. };
  836. void SimpleBrowser::OnPrintTemplateInstantiation()
  837. {
  838. CWnd *parent = GetParent();
  839. if (parent != NULL) {
  840. Notification notification(m_hWnd,GetDlgCtrlID(),PrintTemplateInstantiation);
  841. LRESULT result = parent->SendMessage(WM_NOTIFY,
  842. notification.hdr.idFrom,
  843. (LPARAM)&notification);
  844. }
  845. }
  846. void SimpleBrowser::_OnPrintTemplateTeardown(LPDISPATCH lpDisp)
  847. {
  848. OnPrintTemplateTeardown();
  849. };
  850. void SimpleBrowser::OnPrintTemplateTeardown()
  851. {
  852. CWnd *parent = GetParent();
  853. if (parent != NULL) {
  854. Notification notification(m_hWnd,GetDlgCtrlID(),PrintTemplateTeardown);
  855. LRESULT result = parent->SendMessage(WM_NOTIFY,
  856. notification.hdr.idFrom,
  857. (LPARAM)&notification);
  858. }
  859. }
  860. // Write deferred content
  861. void SimpleBrowser::_ContentWrite()
  862. {
  863. if (_Ready && (!_Content.IsEmpty())) {
  864. // get document interface
  865. IHTMLDocument2 *document = GetDocument();
  866. if (document != NULL) {
  867. // construct text to be written to browser as SAFEARRAY
  868. SAFEARRAY *safe_array = SafeArrayCreateVector(VT_VARIANT,0,1);
  869. VARIANT *variant;
  870. SafeArrayAccessData(safe_array,(LPVOID *)&variant);
  871. variant->vt = VT_BSTR;
  872. variant->bstrVal = _Content.AllocSysString();
  873. SafeArrayUnaccessData(safe_array);
  874. // write SAFEARRAY to browser document
  875. document->write(safe_array);
  876. // cleanup
  877. document->Release();
  878. document = NULL;
  879. ::SysFreeString(variant->bstrVal);
  880. variant->bstrVal = NULL;
  881. SafeArrayDestroy(safe_array);
  882. }
  883. }
  884. }