如何在 c++winapi 中将 PayPal 的结帐与 IWebBrowser2 连接起来?
How to connect checkout of PayPal with IWebBrowser2 in c++winapi?
所以我在 c++ winapi 中为 paypal 结账。从立即购买按钮 link 结帐 link。为此,我使用了 CLSID_WEBBROWSER 新的 WebBrowser 类型 (COM IWebBrowser2)。因此,当我将其导航至 PayPal 网站时。它说网络浏览器是旧版本。我如何使用此 WebBrowser
导航到此站点
WebBrowser.h:
#include <comdef.h>
#include <Exdisp.h>
#include <string>
#include <tchar.h>
#include <Windows.h>
using namespace std;
class WebBrowser :
public IOleClientSite,
public IOleInPlaceSite,
public IStorage
{
public:
WebBrowser(HWND hWndParent);
bool CreateBrowser();
RECT PixelToHiMetric(const RECT& _rc);
virtual void SetRect(const RECT& _rc);
// ----- Control methods -----
void GoBack();
void GoForward();
void Refresh();
void Navigate(wstring szUrl);
// ----- IUnknown -----
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,
void** ppvObject) override;
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
// ---------- IOleWindow ----------
virtual HRESULT STDMETHODCALLTYPE GetWindow(
__RPC__deref_out_opt HWND* phwnd) override;
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(
BOOL fEnterMode) override;
// ---------- IOleInPlaceSite ----------
virtual HRESULT STDMETHODCALLTYPE CanInPlaceActivate(void) override;
virtual HRESULT STDMETHODCALLTYPE OnInPlaceActivate(void) override;
virtual HRESULT STDMETHODCALLTYPE OnUIActivate(void) override;
virtual HRESULT STDMETHODCALLTYPE GetWindowContext(
__RPC__deref_out_opt IOleInPlaceFrame** ppFrame,
__RPC__deref_out_opt IOleInPlaceUIWindow** ppDoc,
__RPC__out LPRECT lprcPosRect,
__RPC__out LPRECT lprcClipRect,
__RPC__inout LPOLEINPLACEFRAMEINFO lpFrameInfo) override;
virtual HRESULT STDMETHODCALLTYPE Scroll(
SIZE scrollExtant) override;
virtual HRESULT STDMETHODCALLTYPE OnUIDeactivate(
BOOL fUndoable) override;
virtual HWND GetControlWindow();
virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate(void) override;
virtual HRESULT STDMETHODCALLTYPE DiscardUndoState(void) override;
virtual HRESULT STDMETHODCALLTYPE DeactivateAndUndo(void) override;
virtual HRESULT STDMETHODCALLTYPE OnPosRectChange(
__RPC__in LPCRECT lprcPosRect) override;
// ---------- IOleClientSite ----------
virtual HRESULT STDMETHODCALLTYPE SaveObject(void) override;
virtual HRESULT STDMETHODCALLTYPE GetMoniker(
DWORD dwAssign,
DWORD dwWhichMoniker,
__RPC__deref_out_opt IMoniker** ppmk) override;
virtual HRESULT STDMETHODCALLTYPE GetContainer(
__RPC__deref_out_opt IOleContainer** ppContainer) override;
virtual HRESULT STDMETHODCALLTYPE ShowObject(void) override;
virtual HRESULT STDMETHODCALLTYPE OnShowWindow(
BOOL fShow) override;
virtual HRESULT STDMETHODCALLTYPE RequestNewObjectLayout(void) override;
// ----- IStorage -----
virtual HRESULT STDMETHODCALLTYPE CreateStream(
__RPC__in_string const OLECHAR* pwcsName,
DWORD grfMode,
DWORD reserved1,
DWORD reserved2,
__RPC__deref_out_opt IStream** ppstm) override;
virtual HRESULT STDMETHODCALLTYPE OpenStream(
const OLECHAR* pwcsName,
void* reserved1,
DWORD grfMode,
DWORD reserved2,
IStream** ppstm) override;
virtual HRESULT STDMETHODCALLTYPE CreateStorage(
__RPC__in_string const OLECHAR* pwcsName,
DWORD grfMode,
DWORD reserved1,
DWORD reserved2,
__RPC__deref_out_opt IStorage** ppstg) override;
virtual HRESULT STDMETHODCALLTYPE OpenStorage(
__RPC__in_opt_string const OLECHAR* pwcsName,
__RPC__in_opt IStorage* pstgPriority,
DWORD grfMode,
__RPC__deref_opt_in_opt SNB snbExclude,
DWORD reserved,
__RPC__deref_out_opt IStorage** ppstg) override;
virtual HRESULT STDMETHODCALLTYPE CopyTo(
DWORD ciidExclude,
const IID* rgiidExclude,
__RPC__in_opt SNB snbExclude,
IStorage* pstgDest) override;
virtual HRESULT STDMETHODCALLTYPE MoveElementTo(
__RPC__in_string const OLECHAR* pwcsName,
__RPC__in_opt IStorage* pstgDest,
__RPC__in_string const OLECHAR* pwcsNewName,
DWORD grfFlags) override;
virtual HRESULT STDMETHODCALLTYPE Commit(
DWORD grfCommitFlags) override;
virtual HRESULT STDMETHODCALLTYPE Revert(void) override;
virtual HRESULT STDMETHODCALLTYPE EnumElements(
DWORD reserved1,
void* reserved2,
DWORD reserved3,
IEnumSTATSTG** ppenum) override;
virtual HRESULT STDMETHODCALLTYPE DestroyElement(
__RPC__in_string const OLECHAR* pwcsName) override;
virtual HRESULT STDMETHODCALLTYPE RenameElement(
__RPC__in_string const OLECHAR* pwcsOldName,
__RPC__in_string const OLECHAR* pwcsNewName) override;
virtual HRESULT STDMETHODCALLTYPE SetElementTimes(
__RPC__in_opt_string const OLECHAR* pwcsName,
__RPC__in_opt const FILETIME* pctime,
__RPC__in_opt const FILETIME* patime,
__RPC__in_opt const FILETIME* pmtime) override;
virtual HRESULT STDMETHODCALLTYPE SetClass(
__RPC__in REFCLSID clsid) override;
virtual HRESULT STDMETHODCALLTYPE SetStateBits(
DWORD grfStateBits,
DWORD grfMask) override;
virtual HRESULT STDMETHODCALLTYPE Stat(
__RPC__out STATSTG* pstatstg,
DWORD grfStatFlag) override;
protected:
IOleObject* oleObject;
IOleInPlaceObject* oleInPlaceObject;
IWebBrowser2* webBrowser2;
LONG iComRefCount;
RECT rObject;
HWND hWndParent;
HWND hWndControl;
};
Resource.cpp:
#include "WebBrowser.h"
WebBrowser::WebBrowser(HWND _hWndParent)
{
iComRefCount = 0;
::SetRect(&rObject, -300, -300, 300, 300);
hWndParent = _hWndParent;
if (CreateBrowser() == FALSE)
{
return;
}
ShowWindow(GetControlWindow(), SW_SHOW);
this->Navigate(_T("about:blank"));
}
bool WebBrowser::CreateBrowser()
{
HRESULT hr;
hr = ::OleCreate(CLSID_WebBrowser,
IID_IOleObject, OLERENDER_DRAW, 0, this, this,
(void**)& oleObject);
if (FAILED(hr))
{
MessageBox(NULL, _T("Cannot create oleObject CLSID_WebBrowser"),
_T("Error"),
MB_ICONERROR);
return FALSE;
}
hr = oleObject->SetClientSite(this);
hr = OleSetContainedObject(oleObject, TRUE);
RECT posRect;
::SetRect(&posRect, -300, -300, 300, 300);
hr = oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE,
NULL, this, -1, hWndParent, &posRect);
if (FAILED(hr))
{
MessageBox(NULL, _T("oleObject->DoVerb() failed"),
_T("Error"),
MB_ICONERROR);
return FALSE;
}
hr = oleObject->QueryInterface(&webBrowser2);
if (FAILED(hr))
{
MessageBox(NULL, _T("oleObject->QueryInterface(&webBrowser2) failed"),
_T("Error"),
MB_ICONERROR);
return FALSE;
}
return TRUE;
}
RECT WebBrowser::PixelToHiMetric(const RECT& _rc)
{
static bool s_initialized = false;
static int s_pixelsPerInchX, s_pixelsPerInchY;
if (!s_initialized)
{
HDC hdc = ::GetDC(0);
s_pixelsPerInchX = ::GetDeviceCaps(hdc, LOGPIXELSX);
s_pixelsPerInchY = ::GetDeviceCaps(hdc, LOGPIXELSY);
::ReleaseDC(0, hdc);
s_initialized = true;
}
RECT rc;
rc.left = MulDiv(2540, _rc.left, s_pixelsPerInchX);
rc.top = MulDiv(2540, _rc.top, s_pixelsPerInchY);
rc.right = MulDiv(2540, _rc.right, s_pixelsPerInchX);
rc.bottom = MulDiv(2540, _rc.bottom, s_pixelsPerInchY);
return rc;
}
void WebBrowser::SetRect(const RECT& _rc)
{
rObject = _rc;
{
RECT hiMetricRect = PixelToHiMetric(rObject);
SIZEL sz;
sz.cx = hiMetricRect.right - hiMetricRect.left;
sz.cy = hiMetricRect.bottom - hiMetricRect.top;
oleObject->SetExtent(DVASPECT_CONTENT, &sz);
}
if (oleInPlaceObject != 0)
{
oleInPlaceObject->SetObjectRects(&rObject, &rObject);
}
}
// ----- Control methods -----
void WebBrowser::GoBack()
{
this->webBrowser2->GoBack();
}
void WebBrowser::GoForward()
{
this->webBrowser2->GoForward();
}
void WebBrowser::Refresh()
{
this->webBrowser2->Refresh();
}
void WebBrowser::Navigate(wstring szUrl)
{
bstr_t url(szUrl.c_str());
variant_t flags(0x02u); //navNoHistory
this->webBrowser2->Navigate(url, &flags, 0, 0, 0);
}
// ----- IUnknown -----
HRESULT STDMETHODCALLTYPE WebBrowser::QueryInterface(REFIID riid,
void** ppvObject)
{
if (riid == __uuidof(IUnknown))
{
(*ppvObject) = static_cast<IOleClientSite*>(this);
}
else if (riid == __uuidof(IOleInPlaceSite))
{
(*ppvObject) = static_cast<IOleInPlaceSite*>(this);
}
else
{
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE WebBrowser::AddRef(void)
{
iComRefCount++;
return iComRefCount;
}
ULONG STDMETHODCALLTYPE WebBrowser::Release(void)
{
iComRefCount--;
return iComRefCount;
}
// ---------- IOleWindow ----------
HRESULT STDMETHODCALLTYPE WebBrowser::GetWindow(
__RPC__deref_out_opt HWND* phwnd)
{
(*phwnd) = hWndParent;
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::ContextSensitiveHelp(
BOOL fEnterMode)
{
return E_NOTIMPL;
}
// ---------- IOleInPlaceSite ----------
HRESULT STDMETHODCALLTYPE WebBrowser::CanInPlaceActivate(void)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OnInPlaceActivate(void)
{
OleLockRunning(oleObject, TRUE, FALSE);
oleObject->QueryInterface(&oleInPlaceObject);
oleInPlaceObject->SetObjectRects(&rObject, &rObject);
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OnUIActivate(void)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::GetWindowContext(
__RPC__deref_out_opt IOleInPlaceFrame** ppFrame,
__RPC__deref_out_opt IOleInPlaceUIWindow** ppDoc,
__RPC__out LPRECT lprcPosRect,
__RPC__out LPRECT lprcClipRect,
__RPC__inout LPOLEINPLACEFRAMEINFO lpFrameInfo)
{
HWND hwnd = hWndParent;
(*ppFrame) = NULL;
(*ppDoc) = NULL;
(*lprcPosRect).left = rObject.left;
(*lprcPosRect).top = rObject.top;
(*lprcPosRect).right = rObject.right;
(*lprcPosRect).bottom = rObject.bottom;
*lprcClipRect = *lprcPosRect;
lpFrameInfo->fMDIApp = false;
lpFrameInfo->hwndFrame = hwnd;
lpFrameInfo->haccel = NULL;
lpFrameInfo->cAccelEntries = 0;
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::Scroll(
SIZE scrollExtant)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OnUIDeactivate(
BOOL fUndoable)
{
return S_OK;
}
HWND WebBrowser::GetControlWindow()
{
if (hWndControl != 0)
return hWndControl;
if (oleInPlaceObject == 0)
return 0;
oleInPlaceObject->GetWindow(&hWndControl);
return hWndControl;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OnInPlaceDeactivate(void)
{
hWndControl = 0;
oleInPlaceObject = 0;
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::DiscardUndoState(void)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::DeactivateAndUndo(void)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OnPosRectChange(
__RPC__in LPCRECT lprcPosRect)
{
return E_NOTIMPL;
}
// ---------- IOleClientSite ----------
HRESULT STDMETHODCALLTYPE WebBrowser::SaveObject(void)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::GetMoniker(
DWORD dwAssign,
DWORD dwWhichMoniker,
__RPC__deref_out_opt IMoniker** ppmk)
{
if ((dwAssign == OLEGETMONIKER_ONLYIFTHERE) &&
(dwWhichMoniker == OLEWHICHMK_CONTAINER))
return E_FAIL;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::GetContainer(
__RPC__deref_out_opt IOleContainer** ppContainer)
{
return E_NOINTERFACE;
}
HRESULT STDMETHODCALLTYPE WebBrowser::ShowObject(void)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OnShowWindow(
BOOL fShow)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::RequestNewObjectLayout(void)
{
return E_NOTIMPL;
}
// ----- IStorage -----
HRESULT STDMETHODCALLTYPE WebBrowser::CreateStream(
__RPC__in_string const OLECHAR* pwcsName,
DWORD grfMode,
DWORD reserved1,
DWORD reserved2,
__RPC__deref_out_opt IStream** ppstm)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OpenStream(
const OLECHAR* pwcsName,
void* reserved1,
DWORD grfMode,
DWORD reserved2,
IStream** ppstm)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::CreateStorage(
__RPC__in_string const OLECHAR* pwcsName,
DWORD grfMode,
DWORD reserved1,
DWORD reserved2,
__RPC__deref_out_opt IStorage** ppstg)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OpenStorage(
__RPC__in_opt_string const OLECHAR* pwcsName,
__RPC__in_opt IStorage* pstgPriority,
DWORD grfMode,
__RPC__deref_opt_in_opt SNB snbExclude,
DWORD reserved,
__RPC__deref_out_opt IStorage** ppstg)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::CopyTo(
DWORD ciidExclude,
const IID* rgiidExclude,
__RPC__in_opt SNB snbExclude,
IStorage* pstgDest)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::MoveElementTo(
__RPC__in_string const OLECHAR* pwcsName,
__RPC__in_opt IStorage* pstgDest,
__RPC__in_string const OLECHAR* pwcsNewName,
DWORD grfFlags)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::Commit(
DWORD grfCommitFlags)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::Revert(void)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::EnumElements(
DWORD reserved1,
void* reserved2,
DWORD reserved3,
IEnumSTATSTG** ppenum)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::DestroyElement(
__RPC__in_string const OLECHAR* pwcsName)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::RenameElement(
__RPC__in_string const OLECHAR* pwcsOldName,
__RPC__in_string const OLECHAR* pwcsNewName)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::SetElementTimes(
__RPC__in_opt_string const OLECHAR* pwcsName,
__RPC__in_opt const FILETIME* pctime,
__RPC__in_opt const FILETIME* patime,
__RPC__in_opt const FILETIME* pmtime)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::SetClass(
__RPC__in REFCLSID clsid)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::SetStateBits(
DWORD grfStateBits,
DWORD grfMask)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::Stat(
__RPC__out STATSTG* pstatstg,
DWORD grfStatFlag)
{
return E_NOTIMPL;
}
Testing.cpp:
WebBrowser* pBrowser2;
if (SUCCEEDED(OleInitialize(NULL)))
{
MoneyHWND = CreateDialog(GetModuleHandle(0), MAKEINTRESOURCE(IDD_FORMVIEW1), hWnd, MoneyProc);
pBrowser2 = new WebBrowser(MoneyHWND);
RECT rc;
GetClientRect(MoneyHWND, &rc);
pBrowser2->SetRect(rc);
pBrowser2->Navigate(L"Paypal site");
OleUninitialize();
}
每个应用程序注册表设置使 IWebBrowser2 使用较新的 IE 版本。您可以使用 IE 11 仿真模式。
检查this。
HKEY_LOCAL_MACHINE (or HKEY_CURRENT_USER)
SOFTWARE
Microsoft
Internet Explorer
Main
FeatureControl
FEATURE_BEHAVIORS
appname.exe = (DWORD) 00000000
将单词更改为所需的 IE 版本。我的示例代码 registry wrapper:
// Browser Emulation
vector<wchar_t> fn(1000);
GetModuleFileName(0, fn.data(), 1000);
PathStripPath(fn.data());
RKEY k(HKEY_CURRENT_USER, L"SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION");
k[fn.data()] = 11001UL; // Use IE 11
请注意,UWP 允许使用 MapView(Edge 引擎),但这仅适用于 UWP,不适用于桌面应用程序(即使是 Xaml Islands)。
我建议改用 WinHttpClient,当您将用户重定向到 PayPal 登录页面时,将打开默认浏览器。
WinHttpClient class 由 shicheng and can be found in this 文章开发。
Here is 我自己关于实施 PayPal 快速结帐的文章。
将字符串发送到 PayPal 服务器
WinHttpClient WinClient1(ExpChkoutStr.GetBuffer());
WinClient1.SetRequireValidSslCertificates(false);
现在我们得到 PayPal 的回复:
WinClient1.SendHttpRequest(L"GET");
httpResponseContent1 = WinClient1.GetResponseContent();
CString strTransactionRet = UrlDecode(httpResponseContent1.c_str());
使用以下代码解析响应:
// Extract token from response
CString sToken = ExtractElement(strTransactionRet, L"TOKEN");
if (sToken == L"")
{
wprintf(L"Internal error: (Paypal): no token was generated (%s)", strTransactionRet);
MessageBox(NULL, L"Internal payment processing error", L"", MB_OK);
return FALSE;
}
CString LinkToOpen = (m_sandbox) ? SANDBOX_PAYPAL_CHECKOUT : REAL_PAYPAL_CHECKOUT;
LinkToOpen += L"&token=";
LinkToOpen += sToken;
所以我在 c++ winapi 中为 paypal 结账。从立即购买按钮 link 结帐 link。为此,我使用了 CLSID_WEBBROWSER 新的 WebBrowser 类型 (COM IWebBrowser2)。因此,当我将其导航至 PayPal 网站时。它说网络浏览器是旧版本。我如何使用此 WebBrowser
导航到此站点WebBrowser.h:
#include <comdef.h>
#include <Exdisp.h>
#include <string>
#include <tchar.h>
#include <Windows.h>
using namespace std;
class WebBrowser :
public IOleClientSite,
public IOleInPlaceSite,
public IStorage
{
public:
WebBrowser(HWND hWndParent);
bool CreateBrowser();
RECT PixelToHiMetric(const RECT& _rc);
virtual void SetRect(const RECT& _rc);
// ----- Control methods -----
void GoBack();
void GoForward();
void Refresh();
void Navigate(wstring szUrl);
// ----- IUnknown -----
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,
void** ppvObject) override;
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
// ---------- IOleWindow ----------
virtual HRESULT STDMETHODCALLTYPE GetWindow(
__RPC__deref_out_opt HWND* phwnd) override;
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(
BOOL fEnterMode) override;
// ---------- IOleInPlaceSite ----------
virtual HRESULT STDMETHODCALLTYPE CanInPlaceActivate(void) override;
virtual HRESULT STDMETHODCALLTYPE OnInPlaceActivate(void) override;
virtual HRESULT STDMETHODCALLTYPE OnUIActivate(void) override;
virtual HRESULT STDMETHODCALLTYPE GetWindowContext(
__RPC__deref_out_opt IOleInPlaceFrame** ppFrame,
__RPC__deref_out_opt IOleInPlaceUIWindow** ppDoc,
__RPC__out LPRECT lprcPosRect,
__RPC__out LPRECT lprcClipRect,
__RPC__inout LPOLEINPLACEFRAMEINFO lpFrameInfo) override;
virtual HRESULT STDMETHODCALLTYPE Scroll(
SIZE scrollExtant) override;
virtual HRESULT STDMETHODCALLTYPE OnUIDeactivate(
BOOL fUndoable) override;
virtual HWND GetControlWindow();
virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate(void) override;
virtual HRESULT STDMETHODCALLTYPE DiscardUndoState(void) override;
virtual HRESULT STDMETHODCALLTYPE DeactivateAndUndo(void) override;
virtual HRESULT STDMETHODCALLTYPE OnPosRectChange(
__RPC__in LPCRECT lprcPosRect) override;
// ---------- IOleClientSite ----------
virtual HRESULT STDMETHODCALLTYPE SaveObject(void) override;
virtual HRESULT STDMETHODCALLTYPE GetMoniker(
DWORD dwAssign,
DWORD dwWhichMoniker,
__RPC__deref_out_opt IMoniker** ppmk) override;
virtual HRESULT STDMETHODCALLTYPE GetContainer(
__RPC__deref_out_opt IOleContainer** ppContainer) override;
virtual HRESULT STDMETHODCALLTYPE ShowObject(void) override;
virtual HRESULT STDMETHODCALLTYPE OnShowWindow(
BOOL fShow) override;
virtual HRESULT STDMETHODCALLTYPE RequestNewObjectLayout(void) override;
// ----- IStorage -----
virtual HRESULT STDMETHODCALLTYPE CreateStream(
__RPC__in_string const OLECHAR* pwcsName,
DWORD grfMode,
DWORD reserved1,
DWORD reserved2,
__RPC__deref_out_opt IStream** ppstm) override;
virtual HRESULT STDMETHODCALLTYPE OpenStream(
const OLECHAR* pwcsName,
void* reserved1,
DWORD grfMode,
DWORD reserved2,
IStream** ppstm) override;
virtual HRESULT STDMETHODCALLTYPE CreateStorage(
__RPC__in_string const OLECHAR* pwcsName,
DWORD grfMode,
DWORD reserved1,
DWORD reserved2,
__RPC__deref_out_opt IStorage** ppstg) override;
virtual HRESULT STDMETHODCALLTYPE OpenStorage(
__RPC__in_opt_string const OLECHAR* pwcsName,
__RPC__in_opt IStorage* pstgPriority,
DWORD grfMode,
__RPC__deref_opt_in_opt SNB snbExclude,
DWORD reserved,
__RPC__deref_out_opt IStorage** ppstg) override;
virtual HRESULT STDMETHODCALLTYPE CopyTo(
DWORD ciidExclude,
const IID* rgiidExclude,
__RPC__in_opt SNB snbExclude,
IStorage* pstgDest) override;
virtual HRESULT STDMETHODCALLTYPE MoveElementTo(
__RPC__in_string const OLECHAR* pwcsName,
__RPC__in_opt IStorage* pstgDest,
__RPC__in_string const OLECHAR* pwcsNewName,
DWORD grfFlags) override;
virtual HRESULT STDMETHODCALLTYPE Commit(
DWORD grfCommitFlags) override;
virtual HRESULT STDMETHODCALLTYPE Revert(void) override;
virtual HRESULT STDMETHODCALLTYPE EnumElements(
DWORD reserved1,
void* reserved2,
DWORD reserved3,
IEnumSTATSTG** ppenum) override;
virtual HRESULT STDMETHODCALLTYPE DestroyElement(
__RPC__in_string const OLECHAR* pwcsName) override;
virtual HRESULT STDMETHODCALLTYPE RenameElement(
__RPC__in_string const OLECHAR* pwcsOldName,
__RPC__in_string const OLECHAR* pwcsNewName) override;
virtual HRESULT STDMETHODCALLTYPE SetElementTimes(
__RPC__in_opt_string const OLECHAR* pwcsName,
__RPC__in_opt const FILETIME* pctime,
__RPC__in_opt const FILETIME* patime,
__RPC__in_opt const FILETIME* pmtime) override;
virtual HRESULT STDMETHODCALLTYPE SetClass(
__RPC__in REFCLSID clsid) override;
virtual HRESULT STDMETHODCALLTYPE SetStateBits(
DWORD grfStateBits,
DWORD grfMask) override;
virtual HRESULT STDMETHODCALLTYPE Stat(
__RPC__out STATSTG* pstatstg,
DWORD grfStatFlag) override;
protected:
IOleObject* oleObject;
IOleInPlaceObject* oleInPlaceObject;
IWebBrowser2* webBrowser2;
LONG iComRefCount;
RECT rObject;
HWND hWndParent;
HWND hWndControl;
};
Resource.cpp:
#include "WebBrowser.h"
WebBrowser::WebBrowser(HWND _hWndParent)
{
iComRefCount = 0;
::SetRect(&rObject, -300, -300, 300, 300);
hWndParent = _hWndParent;
if (CreateBrowser() == FALSE)
{
return;
}
ShowWindow(GetControlWindow(), SW_SHOW);
this->Navigate(_T("about:blank"));
}
bool WebBrowser::CreateBrowser()
{
HRESULT hr;
hr = ::OleCreate(CLSID_WebBrowser,
IID_IOleObject, OLERENDER_DRAW, 0, this, this,
(void**)& oleObject);
if (FAILED(hr))
{
MessageBox(NULL, _T("Cannot create oleObject CLSID_WebBrowser"),
_T("Error"),
MB_ICONERROR);
return FALSE;
}
hr = oleObject->SetClientSite(this);
hr = OleSetContainedObject(oleObject, TRUE);
RECT posRect;
::SetRect(&posRect, -300, -300, 300, 300);
hr = oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE,
NULL, this, -1, hWndParent, &posRect);
if (FAILED(hr))
{
MessageBox(NULL, _T("oleObject->DoVerb() failed"),
_T("Error"),
MB_ICONERROR);
return FALSE;
}
hr = oleObject->QueryInterface(&webBrowser2);
if (FAILED(hr))
{
MessageBox(NULL, _T("oleObject->QueryInterface(&webBrowser2) failed"),
_T("Error"),
MB_ICONERROR);
return FALSE;
}
return TRUE;
}
RECT WebBrowser::PixelToHiMetric(const RECT& _rc)
{
static bool s_initialized = false;
static int s_pixelsPerInchX, s_pixelsPerInchY;
if (!s_initialized)
{
HDC hdc = ::GetDC(0);
s_pixelsPerInchX = ::GetDeviceCaps(hdc, LOGPIXELSX);
s_pixelsPerInchY = ::GetDeviceCaps(hdc, LOGPIXELSY);
::ReleaseDC(0, hdc);
s_initialized = true;
}
RECT rc;
rc.left = MulDiv(2540, _rc.left, s_pixelsPerInchX);
rc.top = MulDiv(2540, _rc.top, s_pixelsPerInchY);
rc.right = MulDiv(2540, _rc.right, s_pixelsPerInchX);
rc.bottom = MulDiv(2540, _rc.bottom, s_pixelsPerInchY);
return rc;
}
void WebBrowser::SetRect(const RECT& _rc)
{
rObject = _rc;
{
RECT hiMetricRect = PixelToHiMetric(rObject);
SIZEL sz;
sz.cx = hiMetricRect.right - hiMetricRect.left;
sz.cy = hiMetricRect.bottom - hiMetricRect.top;
oleObject->SetExtent(DVASPECT_CONTENT, &sz);
}
if (oleInPlaceObject != 0)
{
oleInPlaceObject->SetObjectRects(&rObject, &rObject);
}
}
// ----- Control methods -----
void WebBrowser::GoBack()
{
this->webBrowser2->GoBack();
}
void WebBrowser::GoForward()
{
this->webBrowser2->GoForward();
}
void WebBrowser::Refresh()
{
this->webBrowser2->Refresh();
}
void WebBrowser::Navigate(wstring szUrl)
{
bstr_t url(szUrl.c_str());
variant_t flags(0x02u); //navNoHistory
this->webBrowser2->Navigate(url, &flags, 0, 0, 0);
}
// ----- IUnknown -----
HRESULT STDMETHODCALLTYPE WebBrowser::QueryInterface(REFIID riid,
void** ppvObject)
{
if (riid == __uuidof(IUnknown))
{
(*ppvObject) = static_cast<IOleClientSite*>(this);
}
else if (riid == __uuidof(IOleInPlaceSite))
{
(*ppvObject) = static_cast<IOleInPlaceSite*>(this);
}
else
{
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE WebBrowser::AddRef(void)
{
iComRefCount++;
return iComRefCount;
}
ULONG STDMETHODCALLTYPE WebBrowser::Release(void)
{
iComRefCount--;
return iComRefCount;
}
// ---------- IOleWindow ----------
HRESULT STDMETHODCALLTYPE WebBrowser::GetWindow(
__RPC__deref_out_opt HWND* phwnd)
{
(*phwnd) = hWndParent;
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::ContextSensitiveHelp(
BOOL fEnterMode)
{
return E_NOTIMPL;
}
// ---------- IOleInPlaceSite ----------
HRESULT STDMETHODCALLTYPE WebBrowser::CanInPlaceActivate(void)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OnInPlaceActivate(void)
{
OleLockRunning(oleObject, TRUE, FALSE);
oleObject->QueryInterface(&oleInPlaceObject);
oleInPlaceObject->SetObjectRects(&rObject, &rObject);
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OnUIActivate(void)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::GetWindowContext(
__RPC__deref_out_opt IOleInPlaceFrame** ppFrame,
__RPC__deref_out_opt IOleInPlaceUIWindow** ppDoc,
__RPC__out LPRECT lprcPosRect,
__RPC__out LPRECT lprcClipRect,
__RPC__inout LPOLEINPLACEFRAMEINFO lpFrameInfo)
{
HWND hwnd = hWndParent;
(*ppFrame) = NULL;
(*ppDoc) = NULL;
(*lprcPosRect).left = rObject.left;
(*lprcPosRect).top = rObject.top;
(*lprcPosRect).right = rObject.right;
(*lprcPosRect).bottom = rObject.bottom;
*lprcClipRect = *lprcPosRect;
lpFrameInfo->fMDIApp = false;
lpFrameInfo->hwndFrame = hwnd;
lpFrameInfo->haccel = NULL;
lpFrameInfo->cAccelEntries = 0;
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::Scroll(
SIZE scrollExtant)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OnUIDeactivate(
BOOL fUndoable)
{
return S_OK;
}
HWND WebBrowser::GetControlWindow()
{
if (hWndControl != 0)
return hWndControl;
if (oleInPlaceObject == 0)
return 0;
oleInPlaceObject->GetWindow(&hWndControl);
return hWndControl;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OnInPlaceDeactivate(void)
{
hWndControl = 0;
oleInPlaceObject = 0;
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::DiscardUndoState(void)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::DeactivateAndUndo(void)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OnPosRectChange(
__RPC__in LPCRECT lprcPosRect)
{
return E_NOTIMPL;
}
// ---------- IOleClientSite ----------
HRESULT STDMETHODCALLTYPE WebBrowser::SaveObject(void)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::GetMoniker(
DWORD dwAssign,
DWORD dwWhichMoniker,
__RPC__deref_out_opt IMoniker** ppmk)
{
if ((dwAssign == OLEGETMONIKER_ONLYIFTHERE) &&
(dwWhichMoniker == OLEWHICHMK_CONTAINER))
return E_FAIL;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::GetContainer(
__RPC__deref_out_opt IOleContainer** ppContainer)
{
return E_NOINTERFACE;
}
HRESULT STDMETHODCALLTYPE WebBrowser::ShowObject(void)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OnShowWindow(
BOOL fShow)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::RequestNewObjectLayout(void)
{
return E_NOTIMPL;
}
// ----- IStorage -----
HRESULT STDMETHODCALLTYPE WebBrowser::CreateStream(
__RPC__in_string const OLECHAR* pwcsName,
DWORD grfMode,
DWORD reserved1,
DWORD reserved2,
__RPC__deref_out_opt IStream** ppstm)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OpenStream(
const OLECHAR* pwcsName,
void* reserved1,
DWORD grfMode,
DWORD reserved2,
IStream** ppstm)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::CreateStorage(
__RPC__in_string const OLECHAR* pwcsName,
DWORD grfMode,
DWORD reserved1,
DWORD reserved2,
__RPC__deref_out_opt IStorage** ppstg)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::OpenStorage(
__RPC__in_opt_string const OLECHAR* pwcsName,
__RPC__in_opt IStorage* pstgPriority,
DWORD grfMode,
__RPC__deref_opt_in_opt SNB snbExclude,
DWORD reserved,
__RPC__deref_out_opt IStorage** ppstg)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::CopyTo(
DWORD ciidExclude,
const IID* rgiidExclude,
__RPC__in_opt SNB snbExclude,
IStorage* pstgDest)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::MoveElementTo(
__RPC__in_string const OLECHAR* pwcsName,
__RPC__in_opt IStorage* pstgDest,
__RPC__in_string const OLECHAR* pwcsNewName,
DWORD grfFlags)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::Commit(
DWORD grfCommitFlags)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::Revert(void)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::EnumElements(
DWORD reserved1,
void* reserved2,
DWORD reserved3,
IEnumSTATSTG** ppenum)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::DestroyElement(
__RPC__in_string const OLECHAR* pwcsName)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::RenameElement(
__RPC__in_string const OLECHAR* pwcsOldName,
__RPC__in_string const OLECHAR* pwcsNewName)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::SetElementTimes(
__RPC__in_opt_string const OLECHAR* pwcsName,
__RPC__in_opt const FILETIME* pctime,
__RPC__in_opt const FILETIME* patime,
__RPC__in_opt const FILETIME* pmtime)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::SetClass(
__RPC__in REFCLSID clsid)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebBrowser::SetStateBits(
DWORD grfStateBits,
DWORD grfMask)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE WebBrowser::Stat(
__RPC__out STATSTG* pstatstg,
DWORD grfStatFlag)
{
return E_NOTIMPL;
}
Testing.cpp:
WebBrowser* pBrowser2;
if (SUCCEEDED(OleInitialize(NULL)))
{
MoneyHWND = CreateDialog(GetModuleHandle(0), MAKEINTRESOURCE(IDD_FORMVIEW1), hWnd, MoneyProc);
pBrowser2 = new WebBrowser(MoneyHWND);
RECT rc;
GetClientRect(MoneyHWND, &rc);
pBrowser2->SetRect(rc);
pBrowser2->Navigate(L"Paypal site");
OleUninitialize();
}
每个应用程序注册表设置使 IWebBrowser2 使用较新的 IE 版本。您可以使用 IE 11 仿真模式。
检查this。
HKEY_LOCAL_MACHINE (or HKEY_CURRENT_USER)
SOFTWARE
Microsoft
Internet Explorer
Main
FeatureControl
FEATURE_BEHAVIORS
appname.exe = (DWORD) 00000000
将单词更改为所需的 IE 版本。我的示例代码 registry wrapper:
// Browser Emulation
vector<wchar_t> fn(1000);
GetModuleFileName(0, fn.data(), 1000);
PathStripPath(fn.data());
RKEY k(HKEY_CURRENT_USER, L"SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION");
k[fn.data()] = 11001UL; // Use IE 11
请注意,UWP 允许使用 MapView(Edge 引擎),但这仅适用于 UWP,不适用于桌面应用程序(即使是 Xaml Islands)。
我建议改用 WinHttpClient,当您将用户重定向到 PayPal 登录页面时,将打开默认浏览器。 WinHttpClient class 由 shicheng and can be found in this 文章开发。
Here is 我自己关于实施 PayPal 快速结帐的文章。
将字符串发送到 PayPal 服务器
WinHttpClient WinClient1(ExpChkoutStr.GetBuffer());
WinClient1.SetRequireValidSslCertificates(false);
现在我们得到 PayPal 的回复:
WinClient1.SendHttpRequest(L"GET");
httpResponseContent1 = WinClient1.GetResponseContent();
CString strTransactionRet = UrlDecode(httpResponseContent1.c_str());
使用以下代码解析响应:
// Extract token from response
CString sToken = ExtractElement(strTransactionRet, L"TOKEN");
if (sToken == L"")
{
wprintf(L"Internal error: (Paypal): no token was generated (%s)", strTransactionRet);
MessageBox(NULL, L"Internal payment processing error", L"", MB_OK);
return FALSE;
}
CString LinkToOpen = (m_sandbox) ? SANDBOX_PAYPAL_CHECKOUT : REAL_PAYPAL_CHECKOUT;
LinkToOpen += L"&token=";
LinkToOpen += sToken;