我继承了一个使用CppWebBrowser控件的旧应用程序。
应用程序一直对GET请求使用::导航方法,但现在我需要开始将它用于POST;但是,现有的代码不适用于POST。我对处理这些数据类型的知识有限,但我怀疑这与CString到VT_ARRAY|VT_UI1的转换有关。
void WebPostData(TCppWebBrowser *CppWebBrowser, CString sURL, CString sPostData)
{
BSTR bstrHeaders = NULL;
TVariant vFlags = { 0 }, vTargetFrameName = { 0 }, vPostData = { 0 }, vHeaders = { 0 };
LPSAFEARRAY psa;
LPCTSTR cszPostData = sPostData;
UINT cElems = lstrlen(cszPostData);
LPSTR pPostData;
LPVARIANT pvPostData;
bstrHeaders = SysAllocString(L"Content-Type: application/x-www-form-urlencodedrn");
if (!bstrHeaders){
Application->MessageBox("Could not allocate bstrHeaders", "Warning", MB_OK | MB_ICONWARNING);
return;
}
V_VT(&vHeaders) = VT_BSTR;
V_BSTR(&vHeaders) = bstrHeaders;
pvPostData = vPostData;
if (pvPostData){
VariantInit(pvPostData);
psa = SafeArrayCreateVector(VT_UI1, 0, cElems);
if (!psa){
return;
}
SafeArrayAccessData(psa, (LPVOID*)&pPostData);
memcpy(pPostData, cszPostData, cElems);
SafeArrayUnaccessData(psa);
V_VT(pvPostData) = VT_ARRAY | VT_UI1;
V_ARRAY(pvPostData) = psa;
}
CppWebBrowser->Navigate((TVariant)sURL, &vFlags, &vTargetFrameName, &vPostData, &vHeaders);
}发布于 2015-05-29 01:41:35
您显示的代码是从这个C++Builder示例中复制的:
如何使用TCppWebBrowser在C++Builder中发布数据
CString是MFC类,但C++Builder不支持MFC。原始代码使用System::String,这是一个C++Builder类。那么,您是否试图将此代码转换为Visual?或者你真的在使用C++Builder?你没说。
我将假设您使用的是C++Builder,否则您必须重写Visual类的代码。
因此,首先让我们将CString改为String。现在,取决于您使用的C++Builder的哪个版本,String要么是ANSI (C++Builder 3-2007),要么是UTF-16 (C++Builder 2009+)。在后一种情况下,有一个_DELPHI_STRING_UNICODE预编译器定义。
application/x-www-form-urlencoded类型通常不是以UTF-16的形式发送的,也不能保证web服务器能够处理它。因此,我建议您将sPostData数据转换为UTF-8,然后可以创建一个UTF-8字节的VT_UI1数组:
#ifndef _DELPHI_STRING_UNICODE
inline bool NeedsUTF8(String s)
{
// String is 1-indexed
for (int i = 1; i <= s.Length(); ++i)
{
int ch = s[i];
if (ch > 0x7F) return true;
}
return false;
}
#endif
void WebPostData(TCppWebBrowser *CppWebBrowser, String sURL, String sPostData)
{
TVariant vFlags, vTargetFrameName, vPostData, vHeaders;
// note: UTF8String was added in C++Builder 6,
// use AnsiString in C++Builder 3-5 instead
UTF8String utf8;
#ifdef _DELPHI_STRING_UNICODE
// C++Builder 2009+, convert from UTF-16 to UTF-8 directly
utf8 = sPostData;
#else
// C++Builder 3-2007, check if ASCII or ANSI
if (NeedsUTF8(sPostData))
{
// ANSI, so convert from ANSI to UTF-16 to UTF-8,
// but you have to do the last step manually
WideString wPostData(sPostData);
int len = WideCharToMultiByte(CP_UTF8, wPostData.c_bstr(), wPostData.Length(), NULL, 0, NULL, NULL);
utf8.SetLength(len);
WideCharToMultiByte(CP_UTF8, wPostData.c_bstr(), wPostData.Length(), utf8.c_str(), len, NULL, NULL);
}
else
{
// ASCII, compatible with UTF-8 as-is
utf8 = sPostData;
}
#endif
LPSAFEARRAY psa = SafeArrayCreateVector(VT_UI1, 0, utf8.Length());
if (!psa)
return;
// TVariant takes ownership of a safearray
vPostData = psa;
// TVariant takes ownership of a copy of a WideString's BSTR
vHeaders = WideString("Content-Type: application/x-www-form-urlencoded;charset=utf-8\r\n");
LPVOID pPostData;
if (FAILED(SafeArrayAccessData(psa, &pPostData)))
return;
memcpy(pPostData, utf8.c_str(), utf8.Length());
SafeArrayUnaccessData(psa);
CppWebBrowser->Navigate((TVariant)sURL, &vFlags, &vTargetFrameName, &vPostData, &vHeaders);
}https://stackoverflow.com/questions/30515774
复制相似问题