|
W2A uses stack, so size of BSTR is limited.
Use this code:
inline char* ConvertBSTRToString(BSTR pSrc)
{
if(!pSrc) return NULL;
DWORD cb,cwch = ::SysStringLen(pSrc);
char *szOut = NULL;
if(cb = ::WideCharToMultiByte(CP_ACP, 0, pSrc, cwch + 1, NULL, 0, 0, 0))
{
szOut = new char[cb];
if(szOut)
{
szOut[cb - 1] = '\0';
if(!::WideCharToMultiByte(CP_ACP, 0, pSrc, cwch + 1, szOut, cb, 0, 0))
{
delete []szOut;
szOut = NULL;
}
}
}
return szOut;
};
soptest
|
|
|
|
|
Wow! Thanks. That's a lot of code for a conversion.
Nish
p.s. Right now I won't have to use this, as I know the size of the BSTRs and they are rather small
Regards,
Nish
Native CPian.
Born and brought up on CP.
With the CP blood in him.
|
|
|
|
|
I created an ATL DLL server project and inserted a new ATL object as a simple one, named Inter. Next, i added a new BSTR-type property named Str.
I wrote:
STDMETHODIMP CInter::get_Str(BSTR *pVal)
{
_bstr_t x(*pVal, FALSE);
m_str=x.copy();
return S_OK;
}
This code links perfectly on debug versions but generates this error:
LIBCMT.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
on release versions.
Do you know how to handle it?
rechi
|
|
|
|
|
Taken from "INFO: Active Template Library (ATL) 2.0 Readme File" in MSDN, hope it helps...
<br />
_ATL_MIN_CRT and Link Error "unresolved external symbol _main"<br />
--------------------------------------------------------------<br />
<br />
When you build a Release version of an ATL project, you can get the<br />
following link error:<br />
<br />
LIBCMT.LIB(crt0.obj) : error LNK2001: unresolved external symbol _main<br />
<br />
This error occurs if you are using CRT functions that require CRT startup<br />
code. The Release configurations define _ATL_MIN_CRT, which excludes CRT<br />
startup code from your EXE or DLL. To avoid this error, do one of the<br />
following:<br />
<br />
- Remove _ATL_MIN_CRT from the list of preprocessor defines to allow CRT<br />
startup code to be included. On the Build menu, click Settings. Hold<br />
the ctrl key while selecting all Release configurations. On the C/C++<br />
tab, choose the General category, then remove _ATL_MIN_CRT from the<br />
preprocessor definitions edit box.<br />
<br />
- If possible, remove calls to CRT functions that require CRT startup<br />
code. Instead, use their Win32 equivalents. For example, use lstrcmp()<br />
instead of strcmp(). Known functions that require CRT startup code are<br />
some of the string and floating point functions.<br />
Dylan Kenneally
London, UK
|
|
|
|
|
I've an OLE automated project to convert MS Excel document to PDf file. I use the
void _Workbook::PrintOut(const VARIANT& From,
const VARIANT& To,
const VARIANT& Copies,
const VARIANT& Preview,
const VARIANT& ActivePrinter,
const VARIANT& PrintToFile,
const VARIANT& Collate,
const VARIANT& PrToFileName)
for printing into Acrobat PDFWriter. It runs, but the problem is that Acrobat appears. How can i do to avoid this, please ?
Thanks.
Aziz Rajim.
|
|
|
|
|
I think if you use Adobe PDFWriter, then Acrobat is gonna popup. Alternatively you could consider using LibPDF or other pdf writing libraries to write your pdf file?
sonork: 100:18407
|
|
|
|
|
I want to get HTML code from MSHTML Document.But I can't.
public Samples
//pDoc,IHTMLDocument2
IHTMLElement *elem;
BSTR* bstrVal;
pDoc->get_body(&elem);
elem->get_innerHTML(&bstrVal);
.....
But This Code can't get or ,etc.
For Example,
....
...
....
Please tell me how to get ALL HTML code.
|
|
|
|
|
try this:
IHTMLElementCollection *pEnum;
pDoc->get_all(&pEnum);
if(pEnum)
{
::IHTMLElement *pelem;
try
{
pelem = pEnum->item((long)0);
}catch(...){};
if(pelem)
{
BSTR wsHTML;
pelem->get_outerHTML(&wsHTML);
}
}
soptest
|
|
|
|
|
I want to put HTML code too.
I modified a little and I could get HTML code ,Thank you.
and,
pelem->put_outerHTML(&wsHTML);
But An error occurs,and I couldn't put HTML code.
But I tried use insertAdjacentHTML method and I could insert HTML code.
Please tell me to how to put HTML code.
|
|
|
|
|
i try to embed and automate a word document and an excel
worksheet with mfc and office 2000 using articles
howto (Q184663 for excel and Q238611 for word)
Working well for excel ,not working for word (com error
not registred).
word is well registred in my type librairies with the good UUID
|
|
|
|
|
Did you use the Application independant ProgID ???
--> 'Word.Application'
Dont use any predefined id's use 'CLSIDFromProgID' to get the clsid.
|
|
|
|
|
Thanks for your answer.
I user for word :
CLSID clsid;
CLSIDFromProgID(L"Word.Document",&clsid); //not working
for excel :
CLSIDFromProgID(L"Excel.Sheet" ,&clsid); //working good
|
|
|
|
|
Hi again,
now i have wrote a Excel VBS Script, to test my COM Server.
I can fire an Event within the called Method. Then an Event
in the Excel Macro is raised. So far so well...
Now i want to raise an event from outside of the called COM Method.
Step 1: Excel VBS Macro calls a Method from the Server
Step 2: the server sends the inquiry further (to Socket) and returns
- the VBS macro goes through the following Loop
* While iCounter <> 0
* DoEvents
* Wend
Step 3: The answer ( from socket ) is coming into the Server
Step 4: A Function calls the ComInterface-Eventmethod
Step 5: the Excel VBS macro should raise the event, but it doesn't
does any have an idea, why it does not function?
Marco
|
|
|
|
|
Are you marshalling the com event interface to the thread that does the server call correctly? Take a look at my async mailslot article as this deals with the problem of firing events from outside sources.
Len Holgate
www.jetbyte.com
The right code, right now.
|
|
|
|
|
Thanxs for the answer,
the Function uses a pointer of the event interface. Is this the problem ?
I will try your suggestion !
Marco
|
|
|
|
|
You need to either marshal the event interface into the thread that needs to call back (which I always found was unreliable) or have the thread that needs to call back do so via an interface that effectively marshals the callback into the thread that VB registered the event sink in. My article does it the second way and works fine.
Len Holgate
www.jetbyte.com
The right code, right now.
|
|
|
|
|
Hi,
i've tried to marshal the event interface from the Interface Impl. class.
// this is CPort ( implementation from "interface IPort : IDispatch" )
HRESULT hr = CoMarshalInterThreadInterfaceInStream(DIID__IPortEvents,(_IPortEvents*)this,&pStream);
But "(_IPortEvents*)this" doesn't get the Event Interface.
I can only marshal the IPort Interface. How can i get the pertinent Eventinterface ?
Marco
|
|
|
|
|
The code in the article explains what you need to do and what you need to be aware of.
Your impl class probably doesn't implement the event sink interface, there would be no reason for it to, after all the interface is for users of your class to implement so that they can sink your class's events. You either have to marshal the interface that the client registers with you (during advise), but this is made complex if you happen to be using the ATL stuff to do the connection point management for you. OR you need to implement a new interface that you use to communicate between your worker thread and your main object's thread. See the article for a complete implementation. It's non trivial (hence the need for an article).
Len Holgate
www.jetbyte.com
The right code, right now.
|
|
|
|
|
Hi again,
now it seems to work ! I've tried your first suggestion.
I take the "m_vec" to get the IDispatch Interfaces, like the EventProxy Code it does. Then I marshal these Interfaces to global Variables.
Finally i unmarshal these interfaces and call the "invoke" Funktion, to
fire the event.
Your 2. Solution seems to extensively for my program.
Marco
|
|
|
|
|
Koep wrote:
now it seems to work ! I've tried your first suggestion.
I take the "m_vec" to get the IDispatch Interfaces, like the EventProxy Code it does. Then I marshal these Interfaces to global Variables.
Finally i unmarshal these interfaces and call the "invoke" Funktion, to
fire the event.
Sounds good! Glad it works.
Len Holgate
www.jetbyte.com
The right code, right now.
|
|
|
|
|
Hi,
I want to return Binary data i've read from a file.
I know it can be done by safe array.. can nebody give me some hint on how to do that
Regards
Sameer
|
|
|
|
|
Use the type VT_U1 to store the binary data.
|
|
|
|
|
|
I do something similar (return binary data in a safe array) in my COM Mailslots article. The code in question is:
STDMETHODIMP CMailslotData::Read(VARIANT *ppResults)
{
if (!ppResults)
{
return E_POINTER;
}
return CreateSafeArray(m_pData, m_length, ppResults);
}
where m_pData points to the bytes of data and m_length is the number of bytes we have.
HRESULT CreateSafeArray(
BYTE *pData,
DWORD dataLength,
VARIANT *ppResults)
{
SAFEARRAYBOUND sab;
sab.cElements = dataLength;
sab.lLbound = 0;
SAFEARRAY *pSa = SafeArrayCreateEx(VT_UI1, 1, &sab, 0);
PVOID pvData;
HRESULT hr = SafeArrayAccessData(pSa, &pvData);
if (SUCCEEDED(hr))
{
::CopyMemory(pvData, pData, dataLength);
hr = ::SafeArrayUnaccessData(pSa);
}
if (SUCCEEDED(hr))
{
::VariantInit(ppResults);
(*ppResults).parray = pSa;
(*ppResults).vt = VT_ARRAY | VT_UI1;
}
return hr;
}
Hope this helps.
Len Holgate
www.jetbyte.com
The right code, right now.
|
|
|
|
|
Hello,
i have to raise an event from outside the COM Class.
The Eventnotifier is a CObject MFC Class und should
raise the event in the COM Server Class. I have no
idea which header i should include to make this
possible.
MFC-Class should call CProxy_IXXXEvents ( Fire_OnXXXX )
Can anybody help me ?
Marco
|
|
|
|