|
I have found some code in the MSDN to mark a control as safe for scripting. Here it is (slightly modified):
HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription)
{
ICatRegister* pcr = NULL ;
HRESULT hr = S_OK ;
hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
if (FAILED(hr))
return hr;
CATEGORYINFO catinfo;
catinfo.catid = catid;
catinfo.lcid = 0x0409 ;
int len = wcslen(catDescription);
if (len>127)
len = 127;
wcsncpy(catinfo.szDescription, catDescription, len);
catinfo.szDescription[len] = '\0';
hr = pcr->RegisterCategories(1, &catinfo);
pcr->Release();
return hr;
}
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
ICatRegister* pcr = NULL ;
HRESULT hr = S_OK ;
hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
if (SUCCEEDED(hr))
{
CATID rgcatid[1] ;
rgcatid[0] = catid;
hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
}
if (pcr != NULL)
pcr->Release();
return hr;
}
HRESULT CYourActiveXControl::RegisterSafetyCategories()
{
HRESULT hr = S_OK;
hr = CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data!");
if (FAILED(hr))
return hr;
hr = RegisterCLSIDInCategory(IID_YourActiveXControlHere, CATID_SafeForInitializing);
if (FAILED(hr))
return hr;
hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely scriptable!");
if (FAILED(hr))
return hr;
hr = RegisterCLSIDInCategory(IID_YourActiveXControlHere, CATID_SafeForScripting);
if (FAILED(hr))
return hr;
return hr;
}
Then you can just call the static member "CYourActiveXControl::RegisterSafetyCategories()" in your app's InitInstance function.
Chris Richardson
You can stash and you can seize
In dreams begin, responsibilities U2 - Acrobat[^]
Stop being PC and accounting for everyone and his momma's timeframe. Just enjoy your - Rohit Sinha in the content-challenged thread
|
|
|
|
|
Chris,
I added these and some AfxMessageBox calls for debugging. The OCX is in a cabinet file which is called by the HTML:
<br />
<OBJECT ID=fevis CLASSID="clsid:383680F6-54B7-4970-BB12-A41E7AC0B94B"<br />
HEIGHT=400 WIDTH=680 CODEBASE="http://localhost/controls/fevisactivex.cab#version=1,0,0,2"><br />
</OBJECT><br />
The AfxMessageBox's are never displayed when IE loads the control and tries to execute the VBscript:
<br />
<script language="vbscript"><br />
fevis.OpenFromURL "http://localhost/gallery/connectingrod.fvs"<br />
</script><br />
Any ideas?
Ted
|
|
|
|
|
I'm not sure. What you've done looks exactly like what I've done to host an ActiveX control in the browser, with the exception that my control was not in a CAB file, it was just in an OCX. Have you tried doing this:
<br />
Call fevis.OpenFromURL( "http://localhost/gallery/connectingrod.fvs" )<br />
That's how I wrote the calls into my OCX from the VBScript. Other than that, I can throw together a small sample of hosting a really simple control if it would help.
Chris Richardson
You can stash and you can seize
In dreams begin, responsibilities U2 - Acrobat[^]
Stop being PC and accounting for everyone and his momma's timeframe. Just enjoy your - Rohit Sinha in the content-challenged thread
|
|
|
|
|
Hello ! I have a simple COM component with an interface that exposes the following method:
[id(2), helpstring("method GetString2")] HRESULT GetString2([in] BSTR in, [out] BSTR* out, [out,retval] BSTR* ret);
The implementation :
STDMETHODIMP CTest::GetString2(BSTR in, BSTR* out, BSTR* ret)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
*out=in;
*ret=in;
return S_OK;
}
I call this method from asp:
Set business = CreateObject("COMTest.Test")
result=business.GetString2("Something", cstr(out))
Response.Write cstr(result)+cstr(out)
So result and out should be identical. ("Something") But out=="";
Any ideeas ?
|
|
|
|
|
I mean... how can I return two or more parameters from a method ?
|
|
|
|
|
A COM interface method can only have one [out, retval] parameter and it has to be the last parameter in the method. Your method could return a number of [out] only parameters but not all COM language mappings support [out] only parameters.
The solutions to your problem include the following:
1. Defining an IDL array as a method parameter or use a SAFEARRAY to be variant compliant.
2. Use a structure as a method parameter (define it in your IDL).
3. Use a COM interface as a method parameter
4. Use a COM enumerator - these provide a pattern to allow a client to get batches of items. Alternatively, use a COM collection if you need it to work with VB/VBS.
Best of luck
"The folly of man is that he dreams of what he can never achieve rather than dream of what he can."
"If you think education is expensive, try ignorance."
|
|
|
|
|
ASP as well as VBS has the basic type of parameter as VARIANT.
I suggest you to make some test:
[id(2), helpstring("method GetString2")]
HRESULT GetString2([in] BSTR inStr, [out] BSTR* outStr, [out] VARIANT* outStr2, [out,retval] BSTR* retStr);
and
STDMETHODIMP CTest::GetString2( BSTR inStr, BSTR* outStr, VARIANT* outStr2, BSTR* retStr)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
*outStr = SysAllocString(inStr);
*retStr = SysAllocString(inStr);
outStr2->vt = VT_BSTR;
outStr2->bstrVal = SysAllocString(inStr);
return S_OK;
}
and
Set business = CreateObject("COMTest.Test")
result=business.GetString2("Something", cstr(out), out2)
Response.Write "result=" & result & " out=" & out & " out2=" & out2
It's clearly that "cstr(out)" is not identical to "out".
"cstr(out)" expression means the temporary variable having the string type.
It can not be the receiver of any [out] data.
With best wishes,
Vita
|
|
|
|
|
do u really think that merely assigning/swapping the pointers would do? I think you should look into the marshalling issues.. The memory that you are returning to client needs to be marshalled and allocated...
HTH
|
|
|
|
|
Hi all,
I need to send an array of char via serial line and I have a method to do that. However the string I should send is a CComBSTR. How can I convert it into a "old C style" array of chars?
Thank you in advance.
|
|
|
|
|
|
With Win2003 we have the ability to set up partions for COM to run on. Hence set up different properties for the same COM object under each partition.
I want to know if there is any way for us to do similar stuff in win2k.
Thanks!!
|
|
|
|
|
I want to create a wrapper control to MSFlexGrid Control. I want my Wrapper FelxGrid Control editable. I have done this following example in msdn. Now what i want is to have all the events and properties of MSFlexGrid control inhereted in my Wrapper ActiveX Control.
Mean my wrapper control should be editable and also handle all other events which MSFlexGrid control can handle.
|
|
|
|
|
|
Thanks S.Rod for your suggestions. But the problem is i want to know how can i inherit all the properties, events and methods of activex control in my wrapper activex control. Someone told me to learn containment and aggregation but i couldnt find the solution that way as well.
|
|
|
|
|
Aggregation can be done for instance by using the ATL CComAggregateCreator helper.
|
|
|
|
|
What if you dont have XP or Office 2002? SOL?
|
|
|
|
|
The "Office Web Components" package has nothing to do with the XP, Office 2002 or the Challenger space shuttle. I know it is so since I am running OWC at home with only Office97 installed. RTFM!
|
|
|
|
|
Hi
My company has asked me to develop a COM object that would be able to use within ASP scripts using VBScript. The object spec briefly is to allow a search of PDF, word and various other well known document files for keywords passed to the object.
My two questions are:
1) Having never done any COM before I need to know whether I should develop this in a Win2000 Server enviornment using C++ or VB (C++ I guess would be better) or if doing it in an XP Prof. Environment using Managed C++ or C# would be the better option. My worries are backward compatibility. The COM object is to be used in ASP scripts only, not ASP.NET so I am assuming to use C++, but I was wanting to avoid the DLL Hell issues I've heard so much about by using the ASP.NET method of the BIN directory for DLL's for development purposes only and then moving the developed DLL across to the Win2000 server...
2) Where can I get documentation that would allow me to know how to get the object to search through these various file types. I am specifically interested in the PDF file format.
Any help in this regard would really be great, many thanks.
John Cogan
|
|
|
|
|
Hello,
I have a C++ dll that exports a single function. This function is called by a VB client.
The function takes around 40 mins to complete and returns a bunch of safearrays. In the mean time, I want to display a dialog via the VB client, where the user has the option to cancel the function execution.
What is the best way to implement this ? Iam a novice, and would appreciate you pointing me to the right resources. Thank you.
|
|
|
|
|
vikca wrote:
What is the best way to implement this ?
Do not use VB
On a serious note, you don't have any choice on the VB side, because it's a monothreaded client.
The best way would be implementing this as something like BeginJob/GetJobStatus/CancelJob/EndJob on the C++ side and do the actual job on a separate thread.
Unfortunately, multithreading under COM is not easy for a novice, sorry. You'll need to deal with things like marshalling and synchronization objects, which are actually easy to use, but quite scary until you get used to them.
It's not the fall that kills you: it's the sudden stop - Down by Law, Jim Jamursch (1986)
|
|
|
|
|
Please can you point me to an appropriate resource/reading for the same ?
Thank you very much.
|
|
|
|
|
Do not use VB
On a serious note, you don't have any choice on the VB side, because it's a monothreaded client.
It does not mean that the VB cannot use the multithreaded server (or DLL).
If the DLL has the multithreaded (or asynchronous) BeginJob/GetJobStatus/CancelJob/EndJob functions, then VB can use them.
With best wishes,
Vita
|
|
|
|
|
This may not be obvious to you, but if the DLL exports only one function, what function in the DLL do you plan on calling to cause the 40 minute operation to be stopped? What you are proposing is practical and a very good UI design, but if the coder of the DLL has not provided you with any interface to cancel or halt the operation, you wont be able to accomplish what you hope too.
Chris Meech
"what makes CP different is the people and sense of community, things people will only discover if they join up and join in." Christian Graus Nov 14, 2002.
"AAAAAAAAAHHHHHH!!!!! Those leaks are driving me crazy! How does one finds a memory leak in a garbage collected environment ??! Daniel Turini Nov. 2, 2002.
|
|
|
|
|
This may not be obvious to you, but if the DLL exports only one function, what function in the DLL do you plan on calling to cause the 40 minute operation to be stopped?
IMHO, there is a decision with usage of any Windows synchronization objects (e.g. Event) and mandatory Message Pump.
With best wishes,
Vita
|
|
|
|
|
last string question of the day, I swear!
void Create(BSTR strCaption, BSTR strMessage, BSTR strNoPrompt, int nIcon)
{
m_strNoPrompt = SysAllocString( strNoPrompt );
m_strNoPrompt is a CComBSTR. Is SysAllocString mandatory?
---------------
Tired of Spam? Introducing InboxShield® for Microsoft® Outlook®
http://www.edovia.com
|
|
|
|