Mercurial > dwindows
comparison win/browser.c @ 2018:663d79f28e46
Win: Fix dw_html_javascript_run() when using embedded IE browser widget.
Switched both the Edge and IE modules to use the main UTF8 conversion utils.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Fri, 08 Nov 2019 09:49:16 +0000 |
parents | 686b2d049056 |
children | 583c2d62845c |
comparison
equal
deleted
inserted
replaced
2017:686b2d049056 | 2018:663d79f28e46 |
---|---|
27 #include <mshtml.h> // Defines of stuff like IHTMLDocument2. This is an include file with Visual C 6 and above | 27 #include <mshtml.h> // Defines of stuff like IHTMLDocument2. This is an include file with Visual C 6 and above |
28 #include <mshtmhst.h> // Defines of stuff like IDocHostUIHandler. This is an include file with Visual C 6 and above | 28 #include <mshtmhst.h> // Defines of stuff like IDocHostUIHandler. This is an include file with Visual C 6 and above |
29 #include <crtdbg.h> // for _ASSERT() | 29 #include <crtdbg.h> // for _ASSERT() |
30 #include <initguid.h> | 30 #include <initguid.h> |
31 #include "dw.h" | 31 #include "dw.h" |
32 | |
33 /* Import the character conversion functions from dw.c */ | |
34 LPWSTR _myUTF8toWide(char *utf8string, void *outbuf); | |
35 char *_myWideToUTF8(LPWSTR widestring, void *outbuf); | |
36 #define UTF8toWide(a) _myUTF8toWide(a, a ? _alloca(MultiByteToWideChar(CP_UTF8, 0, a, -1, NULL, 0) * sizeof(WCHAR)) : NULL) | |
37 #define WideToUTF8(a) _myWideToUTF8(a, a ? _alloca(WideCharToMultiByte(CP_UTF8, 0, a, -1, NULL, 0, NULL, NULL)) : NULL) | |
38 LRESULT CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2); | |
32 | 39 |
33 // This is used by DisplayHTMLStr(). It can be global because we never change it. | 40 // This is used by DisplayHTMLStr(). It can be global because we never change it. |
34 static const SAFEARRAYBOUND ArrayBound = {1, 0}; | 41 static const SAFEARRAYBOUND ArrayBound = {1, 0}; |
35 | 42 |
36 // Our IStorage functions that the browser may call | 43 // Our IStorage functions that the browser may call |
1077 | 1084 |
1078 | 1085 |
1079 // The DWEventHandler object must be created by an application using IWebBRowser2, | 1086 // The DWEventHandler object must be created by an application using IWebBRowser2, |
1080 // and given to IWebBrowser2's IConnectPoint object (via | 1087 // and given to IWebBrowser2's IConnectPoint object (via |
1081 // IConnectPoint's Advise function). | 1088 // IConnectPoint's Advise function). |
1082 // {4115B8E2-1823-4bbc-B10D-3D33AAA12ACF} | |
1083 | 1089 |
1084 // DWEventHandler VTable's GUID | 1090 // DWEventHandler VTable's GUID |
1085 // {d2d531c4-83d7-48d7-b733-840245ea2b34} | 1091 // {d2d531c4-83d7-48d7-b733-840245ea2b34} |
1086 DEFINE_GUID(DIID_DWEventHandler, 0xd2d531c4, 0x83d7, 0x48d7, 0xb7, 0x33, 0x84, 0x2, 0x45, 0xea, 0x2b, 0x34); | 1092 DEFINE_GUID(DIID_DWEventHandler, 0xd2d531c4, 0x83d7, 0x48d7, 0xb7, 0x33, 0x84, 0x2, 0x45, 0xea, 0x2b, 0x34); |
1087 | 1093 |
1135 | 1141 |
1136 // This is the extra function for DWEventHandler. | 1142 // This is the extra function for DWEventHandler. |
1137 | 1143 |
1138 static void STDMETHODCALLTYPE DWEventHandler_DocumentComplete(DWEventHandler *this, IDispatch* pDisp, VARIANT* URL) | 1144 static void STDMETHODCALLTYPE DWEventHandler_DocumentComplete(DWEventHandler *this, IDispatch* pDisp, VARIANT* URL) |
1139 { | 1145 { |
1140 // Do a compare of the two elements. We happen to know that | |
1141 // we'll be passing an array of DWORD values to Sort() | |
1142 dw_debug("DocumentComplete() called!\n"); | 1146 dw_debug("DocumentComplete() called!\n"); |
1143 } | 1147 } |
1144 | 1148 |
1145 | 1149 |
1146 // Our DWEventHandler VTable. We need only one of these, so we can | 1150 // Our DWEventHandler VTable. We need only one of these, so we can |
1455 // nul-terminated C strings. So, by using a VARIENT, whose first field tells what sort of | 1459 // nul-terminated C strings. So, by using a VARIENT, whose first field tells what sort of |
1456 // data (ie, string, float, etc) is in the VARIENT, COM interfaces can be used by just about | 1460 // data (ie, string, float, etc) is in the VARIENT, COM interfaces can be used by just about |
1457 // any language. | 1461 // any language. |
1458 VariantInit(&myURL); | 1462 VariantInit(&myURL); |
1459 myURL.vt = VT_BSTR; | 1463 myURL.vt = VT_BSTR; |
1460 | 1464 myURL.bstrVal = SysAllocString(UTF8toWide(url)); |
1461 { | |
1462 wchar_t *buffer; | |
1463 DWORD size; | |
1464 | |
1465 size = MultiByteToWideChar(CP_ACP, 0, url, -1, 0, 0); | |
1466 if (!(buffer = (wchar_t *)GlobalAlloc(GMEM_FIXED, sizeof(wchar_t) * size))) goto badalloc; | |
1467 MultiByteToWideChar(CP_ACP, 0, url, -1, buffer, size); | |
1468 myURL.bstrVal = SysAllocString(buffer); | |
1469 GlobalFree(buffer); | |
1470 } | |
1471 if (!myURL.bstrVal) | 1465 if (!myURL.bstrVal) |
1472 { | 1466 { |
1473 badalloc: webBrowser2->lpVtbl->Release(webBrowser2); | 1467 webBrowser2->lpVtbl->Release(webBrowser2); |
1474 return(-6); | 1468 return(-6); |
1475 } | 1469 } |
1476 | 1470 |
1477 // Call the Navigate2() function to actually display the page. | 1471 // Call the Navigate2() function to actually display the page. |
1478 webBrowser2->lpVtbl->Navigate2(webBrowser2, &myURL, 0, 0, 0, 0); | 1472 webBrowser2->lpVtbl->Navigate2(webBrowser2, &myURL, 0, 0, 0, 0); |
1501 * scriptdata = Pointer to user data to be passed to the callback. | 1495 * scriptdata = Pointer to user data to be passed to the callback. |
1502 * | 1496 * |
1503 * RETURNS: 0 if success, or non-zero if an error. | 1497 * RETURNS: 0 if success, or non-zero if an error. |
1504 */ | 1498 */ |
1505 | 1499 |
1506 int _dw_html_javascript_run(HWND hwnd, LPCWSTR script, void *scriptdata) | 1500 int _dw_html_javascript_run(HWND hwnd, char *script, void *scriptdata) |
1507 { | 1501 { |
1502 IWebBrowser2 *webBrowser2; | |
1508 IHTMLWindow2 *htmlWindow2; | 1503 IHTMLWindow2 *htmlWindow2; |
1504 IHTMLDocument2 *htmlDocument2; | |
1509 IOleObject *browserObject; | 1505 IOleObject *browserObject; |
1510 VARIANT retVal; | 1506 VARIANT result; |
1507 int retval = DW_ERROR_UNKNOWN; | |
1511 | 1508 |
1512 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when | 1509 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when |
1513 // we initially attached the browser object to this window. | 1510 // we initially attached the browser object to this window. |
1514 browserObject = *((IOleObject **)dw_window_get_data(hwnd, "_dw_html")); | 1511 browserObject = *((IOleObject **)dw_window_get_data(hwnd, "_dw_html")); |
1515 | 1512 |
1516 // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser | 1513 // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser |
1517 // object, so we can call some of the functions in the former's table. | 1514 // object, so we can call some of the functions in the former's table. |
1518 if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IHTMLWindow2, (void**)&htmlWindow2)) | 1515 if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2)) |
1519 { | 1516 { |
1520 BSTR myscript = SysAllocString(script); | 1517 IDispatch *pDp; |
1521 if (myscript) | 1518 |
1519 if(!webBrowser2->lpVtbl->get_Document(webBrowser2, &pDp)) | |
1522 { | 1520 { |
1523 htmlWindow2->lpVtbl->execScript(htmlWindow2, myscript, NULL, &retVal); | 1521 if (!pDp->lpVtbl->QueryInterface(pDp, &IID_IHTMLDocument2, (void**)&htmlDocument2)) |
1524 SysFreeString(myscript); | 1522 { |
1523 if (!htmlDocument2->lpVtbl->get_parentWindow(htmlDocument2, &htmlWindow2)) | |
1524 { | |
1525 BSTR myscript = SysAllocString(UTF8toWide(script)); | |
1526 if (myscript) | |
1527 { | |
1528 HRESULT hr; | |
1529 | |
1530 VariantInit(&result); | |
1531 hr = htmlWindow2->lpVtbl->execScript(htmlWindow2, myscript, L"javascript", &result); | |
1532 /* Pass the result back for event handling */ | |
1533 _wndproc(hwnd, WM_USER+100, (WPARAM)(result.vt == VT_BSTR ? WideToUTF8(result.bstrVal) : NULL), (LPARAM)scriptdata); | |
1534 VariantClear(&result); | |
1535 SysFreeString(myscript); | |
1536 retval = DW_ERROR_NONE; | |
1537 } | |
1538 // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it, | |
1539 // so we can release our hold on it). Note that we'll still maintain our hold on the browser | |
1540 // object. | |
1541 htmlWindow2->lpVtbl->Release(htmlWindow2); | |
1542 } | |
1543 htmlDocument2->lpVtbl->Release(htmlDocument2); | |
1544 } | |
1545 pDp->lpVtbl->Release(pDp); | |
1525 } | 1546 } |
1526 // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it, | 1547 webBrowser2->lpVtbl->Release(webBrowser2); |
1527 // so we can release our hold on it). Note that we'll still maintain our hold on the browser | |
1528 // object. | |
1529 htmlWindow2->lpVtbl->Release(htmlWindow2); | |
1530 } | 1548 } |
1531 return DW_ERROR_UNKNOWN; | 1549 return retval; |
1532 } | 1550 } |
1551 | |
1533 | 1552 |
1534 | 1553 |
1535 /******************************* ResizeBrowser() **************************** | 1554 /******************************* ResizeBrowser() **************************** |
1536 * Resizes the browser object for the specified window to the specified | 1555 * Resizes the browser object for the specified window to the specified |
1537 * width and height. | 1556 * width and height. |