SimpleBrowser.cpp 26 KB

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