Загрузка "объемного" HTML кода в TCppWebBrowser
26. Как в компонент TWebBrowser загрузить HTML код из строки?. Пока я использовал небольшой размер кода ошибок не возникало, но на строке в 60Кбайт возникла ошибка нарушения доступа.
Если я не ошибаюсь, то корни этого в строке:
(см. WideString не пойму логику работы).
Вопрос: как обойтись без WideString?
PS: в MSDN приведен такой пример:
Здесь приведен пример:
Если я не ошибаюсь, то корни этого в строке:
Код:
param->bstrVal = WideString(str->DataString);
Вопрос: как обойтись без WideString?
PS: в MSDN приведен такой пример:
Код:
BSTR bstr =
SysAllocString(OLESTR("Written by IHTMLDocument2::write()."));
...
param->bstrVal = bstr;
SysAllocString(OLESTR("Written by IHTMLDocument2::write()."));
...
param->bstrVal = bstr;
Цитата: Dmitryl
Вопрос: как обойтись без WideString?
Вам бы стоило переформулировать вопрос - как правильно выделить память - а как правильно ее выделить - вы собственно и сами показали ( в коде из МСДН) :) Не забывая при этом о необходимости так же вызывать SysFreeString
Код:
sfArray = SafeArrayCreateVector(VT_VARIANT, 0, 1);
if (sfArray)
{
BSTR bstr;
int tempSize;
SafeArrayAccessData(sfArray, (LPVOID*) ¶m);
param->vt = VT_BSTR;
tempSize = str->DataString.WideCharBufSize();
bstr = new wchar_t[tempSize];
bstr = str->DataString.WideChar(bstr, tempSize);
param->bstrVal = bstr;
SafeArrayUnaccessData(sfArray);
docInterface->write(sfArray);
delete [] bstr;
if (sfArray != NULL)
{
try
{
SafeArrayDestroy(sfArray);
}
catch(...)
{
;
}
}
}
if (sfArray)
{
BSTR bstr;
int tempSize;
SafeArrayAccessData(sfArray, (LPVOID*) ¶m);
param->vt = VT_BSTR;
tempSize = str->DataString.WideCharBufSize();
bstr = new wchar_t[tempSize];
bstr = str->DataString.WideChar(bstr, tempSize);
param->bstrVal = bstr;
SafeArrayUnaccessData(sfArray);
docInterface->write(sfArray);
delete [] bstr;
if (sfArray != NULL)
{
try
{
SafeArrayDestroy(sfArray);
}
catch(...)
{
;
}
}
}
Без try, catch "Access violation ... in OLEAUT32.dll.".
Цитата: kot_
а как правильно ее выделить - вы собственно и сами показали
Для того, чтобы выделить память с помощью SysAllocString надо иметь wchar_t*, а его нет. Но даже если его получить с помощью bstr = str->DataString.WideChar(bstr, tempSize); и использовать SysAllocString и SysFreeString, то AV так и будет появляться.
Цитата: oxotnik333
http://forum.codenet.ru/showpost.php...27&postcount=4
Для записи char* мне следует использовать IID_IPersistStreamInit?
Цитата: Dmitryl
Для того, чтобы выделить память с помощью SysAllocString надо иметь wchar_t*, а его нет. Но даже если его получить с помощью bstr = str->DataString.WideChar(bstr, tempSize); и использовать SysAllocString и SysFreeString, то AV так и будет появляться.
используйте функцию mbstowcs_s для получения wchar_t*. Это же вроде бы очевидно. Зачем все эти танцы с бубном?
пример подобных преобразований.
Вот вам
С ней та же ошибка.
Ошибка всегда возникает на SafeArrayDestroy(sfArray);
Пример о котором говорил выше из MSDN в котором изменить требуется выделение, инициализацию и освобождение памяти для bstr (исходные данные: строка AnsiString длиной 117168):
Код:
IHTMLDocument2 *document; // Declared earlier in the code
HRESULT hresult = S_OK;
VARIANT *param;
SAFEARRAY *sfArray;
BSTR bstr = SysAllocString(OLESTR("Written by IHTMLDocument2::write()."));
// Creates a new one-dimensional array
sfArray = SafeArrayCreateVector(VT_VARIANT, 0, 1);
if (sfArray == NULL || document == NULL) {
goto cleanup;
}
hresult = SafeArrayAccessData(sfArray,(LPVOID*) & param);
param->vt = VT_BSTR;
param->bstrVal = bstr;
hresult = SafeArrayUnaccessData(sfArray);
hresult = document->write(sfArray);
cleanup:
SysFreeString(bstr);
if (sfArray != NULL) {
SafeArrayDestroy(sfArray);
}
HRESULT hresult = S_OK;
VARIANT *param;
SAFEARRAY *sfArray;
BSTR bstr = SysAllocString(OLESTR("Written by IHTMLDocument2::write()."));
// Creates a new one-dimensional array
sfArray = SafeArrayCreateVector(VT_VARIANT, 0, 1);
if (sfArray == NULL || document == NULL) {
goto cleanup;
}
hresult = SafeArrayAccessData(sfArray,(LPVOID*) & param);
param->vt = VT_BSTR;
param->bstrVal = bstr;
hresult = SafeArrayUnaccessData(sfArray);
hresult = document->write(sfArray);
cleanup:
SysFreeString(bstr);
if (sfArray != NULL) {
SafeArrayDestroy(sfArray);
}
потоком то чего не делается? проще ж...
Цитата:
потоком то чего не делается? проще ж...
Сделал! Заработало! Спасибо!
Код:
TStringStream *str = new TStringStream("");
// ...
IPersistStreamInit* pPersistStreamInit = NULL;
TStreamAdapter *sa;
HRESULT hr = S_OK;
str->Seek(0, soFromBeginning);
sa = new TStreamAdapter(str, soReference);
hr = DocDispatch->QueryInterface( IID_IPersistStreamInit, (void**)&pPersistStreamInit );
if (!SUCCEEDED(hr))
{
return;
}
hr = pPersistStreamInit->InitNew();
if (!SUCCEEDED(hr))
{
return;
}
pPersistStreamInit->Load(*sa);
delete str;
// ...
IPersistStreamInit* pPersistStreamInit = NULL;
TStreamAdapter *sa;
HRESULT hr = S_OK;
str->Seek(0, soFromBeginning);
sa = new TStreamAdapter(str, soReference);
hr = DocDispatch->QueryInterface( IID_IPersistStreamInit, (void**)&pPersistStreamInit );
if (!SUCCEEDED(hr))
{
return;
}
hr = pPersistStreamInit->InitNew();
if (!SUCCEEDED(hr))
{
return;
}
pPersistStreamInit->Load(*sa);
delete str;