|
Having trouble adding a method or property using Visual Studio IDE.
The Steps I followed:
1. Highlight interface "IMyInter" in the workspace
2. Right click and chose to add a method..
3. After inputs for method name etc. On Ok, I am getting an error "Unable to create the function because the header file or the implementation file could not be found"
Any pointers please. Thanks
|
|
|
|
|
delet the .ncb file for the solution and everything would be back to normal
|
|
|
|
|
No didnt fix it..
I deleted .ncb and recompiled it. I see the file created but now I can find my interface "IMyInter" in the workspace..
|
|
|
|
|
One thing that I found is that all files need to be in the project (header and code) or strange things may happen.
I had problems where I my header files were not added to the project, so my classes would not show up in the class view.
Francisco
|
|
|
|
|
Is the IDL file in the project?
|
|
|
|
|
Solution:
I am not sure if the .OPT file is any way related to this problem. But when I deleted .OPT file, everthing worked fine.
Thanks gentlemen for your help..
|
|
|
|
|
I have a problem while adding a combobox to a toolbar. I am creating a customize toolbar and associating it with Internet explorer. I have done it in ATL using Ideskband interface. Now when the toolbar is enabled in Internet Explorer, I close that instance and when again launhing internet explorer instance the drop down list for the combo placed in toolbar is not coming Plz help
|
|
|
|
|
Hi,
I have a ATL Server (EXE). I am able to access it from a C++ client, but I tried using it from VBScript and I get an Error 424 : Object Required.
What could I be doing wrong ? (I am a newbie in VBScript)
Thanks
Vivek
Here is the VBS Code
<HTML>
<HEAD>
<TITLE>Working With VBScript</TITLE>
<SCRIPT LANGUAGE="VBScript">
' -------------------------------------
' Subroutine for testing Pinger
'
' Author: Vivekr
' -------------------------------------
Sub cmdClickMe_OnClick
Dim TPinger 'Pinger COM Object
Dim Message
Dim Error
On Error Resume Next 'Proceed after error
'--------------------------------
'Create the ATL COM Pinger Object
'--------------------------------
Set TPinger = Atutils.VPinger4
MsgBox Err.Description
Message = "Error = " & Err.number
MsgBox "Created Object" & Message
End Sub
</SCRIPT>
<BODY>
<H1>VBScript Testbed</H1>
<P> By utilizing VBScript you can give your Web pages actions.
Click on the button below to see what we mean. </P>
<FORM NAME="frmExercise1">
<INPUT TYPE="Button" NAME="cmdClickMe" VALUE="Create Object">
</FORM>
</BODY>
</HTML>
|
|
|
|
|
You must call "CreateObject"
soptest
|
|
|
|
|
soptest-
Thanks for the tip. I will give it a shot
Vivek
|
|
|
|
|
Also (you may already know this) all your interfaces MUST derive from IDispatch, not just IUnknown.
|
|
|
|
|
Thanks Jim,
All my interfaces derive from IDispatch.
Is VARIANT the only type of argument allowed ? Will BSTR, short work with VB Script ?
I am still strugglinh with this. I keep getting the same error 424
Thanks-
Vivek
|
|
|
|
|
BSTR will work, I think the basic primitive types will work like short, long.
Collections need to use the IEnumXXX interfaces or something similar (I think - not a 100% sure on this one). Wrapping things in variants probably is a good idea though, even if it is more work.
|
|
|
|
|
I think that it must be
Set TPinger = New Atutils.VPinger4
or
Set TPinger = CreateObject("Atutils.VPinger4")
With best wishes,
Vita
|
|
|
|
|
--->>???? Set TPinger = New Atutils.VPinger4 !!!!
Will not work
soptest
|
|
|
|
|
I have created an ATL COM object in its interface I have a method that receives another interface of the same type and wish to modify some of its properties, however I do not want these properties to be exposed by its interface i.e. equivalent of protected member in C++ class.
I have the following code:
in header:
//this class ultimately derives from IMyComObject so
// I cast a IMyComObject* to CMyComObject*
class ATL_NO_VTABLE CMyComObject :
public CComObjectRootEx<ccomsinglethreadmodel>,
public CComCoClass<cmycomobject, &clsid_mycomobject="">,
public IDispatchImpl<imycomobject, &iid_imycomobject,="" &libid_mylib="">
{
....
protected:
IMyComObjectPtr m_pConnectedTo;
}
in method implementation:
STDMETHODIMP CMyComObject::ConnectTo(IMyComObject *pMyComObject)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
IMyComObjectPtr pMyComObjectPtr = pMyComObject;
if ( m_pConnectedTo )
Disconnect();
if ( pMyComObjectPtr->IsConnected )
pMyComObjectPtr->Disconnect();
//////////this is the 'nasty' part it does work but I dont like it!!
//////////is there a more elegant way to achieve this or is what I am doing OK?
CMyComObject* pMyBodgeCast = dynamic_cast<cmycomobject*>(pMyComObject);
pMyBodgeCast->m_pConnectedTo = this;
//////////////////////////////////////////////////////////////////////////
m_pConnectedTo = pMyComObject;
return S_OK;
}
If anyone has any comments I would really like to hear them. Thanks.
|
|
|
|
|
Anonymous wrote:
//////////this is the 'nasty' part it does work but I dont like it!!
//////////is there a more elegant way to achieve this or is what I am doing OK?
CMyComObject* pMyBodgeCast = dynamic_cast(pMyComObject);
pMyBodgeCast->m_pConnectedTo = this;
//////////////////////////////////////////////////////////////////////////
Hi -
What you are doing is clearly bad !! I think casting an interface to an implementation goes against the very princple of COM (separation of impl and interface).
It works for you because
(a) you have an INPROC DLL, so there is no marshalling
(b) you guarantee that the only implementaton of IMYComObject is CMyCOMObject.
I had a similar problem when I wanted prvate interfaces. I think this is a major limitation of COM interfaces. You can use the [hidden] or [restricted] keywords in IDL. But that wouldnt prevent C++ users from using it. If you dont include it in the typelib,or register it, then it wont be marshalled across apartments. The solution I used is kludgy, have a private token or key as a parameter for each of the interface methods. So, the private interface would be visible, but not usable by others because they dont know the secret key.
Here is how you might do this.
1) Specify the [hidden] or [restricted] keyword in the IDL for the IMyComObjectPrivateUse, so VB cant use it.
2) Create a private interface IMyComObjectPrivateUse, add the method SetConnectedObject(DWORD token,IMyComObject *)
3) Implement IMyComObjectPrivateUse in CMyComObject, the method looks like
STDMETHODIMP CMyComObject::SetConnectedObject(DWORD token,IMyComObject *pObj)
{
if(token!=0xfeedf00d) {
return E_NOTIMPL;
}
pObj->AddRef();
m_pConnectedTo=pObj;
return S_OK;
}
4) In your ConnectTo implementation, just QI for IMyComObjectPrivateUse and call the set method with the correct key
IMyComObjectPrivateUse * pPriv;
pMyComObject->QI(IID_IMYComObjcetPrivateUse,(LPVOID*)&pPriv)
pPriv->SetConnected(0xfeedf00d,pMyComObject);
I would love to hear anyone who has other ideas. I am currently using the above mechanism.
Hope that helps -
Vivek
|
|
|
|
|
Just declare implemented interface IMyInterface *_pi;
then assign incomming to _pi
_pi = pIn;
If incomming interface is different then you need just typecast incomming interface. (COM object must implement all of those interfaces)
And that is it. You do not need to do QueryInterface because vtlb has all pointers to all methods of all implemented interfaces.
P.S. Typecasting interface to class which implements this interface is bad idea (because the class may have other functions implemented which are not exposed by implemented interface/s, and data members), never do this.
soptest
|
|
|
|
|
soptest wrote:
then assign incomming to _pi
_pi = pIn;
If incomming interface is different then you need just typecast incomming interface. (COM object must implement all of those interfaces)
This approach is not recommended because, it wouldnt work for aggregated & tearoff interfaces.
Thanks-
Vivek
|
|
|
|
|
It has nothing to do with it. COM object does not implement them through vtlb, so it is the same thing as this example:
struct _tearoffObj{};
struct _A
{
void GetObj(void** pObj)
{
*pObj = new _tearoffObj();
}
}
_A does not implement _tearoffObj.
So the statement "_pi = pIn;" is 100% correct.
soptest
|
|
|
|
|
soptest wrote:
So the statement "_pi = pIn;" is 100% correct.
Sorry, that wont work.
If CoClass A implements 20 interfaces(10 interface via vtbl and 10 via tear off), you cannot get to the tear offs by assignment, you must use a QI. Same thing for aggregation.
In the world of COM, getting from one interface to another requires you to use QI. It is possible to ignore that rule and typecast, but that is asking for trouble and very poor COM practice.
|
|
|
|
|
Blah blah blah. When your COM object provides tearoff interface/s that object is not based on that interface. Vtbl is dynamicaly created for that tearoff object.
*** STOP: 0x0000001E (0xC0000005,0x8016A950,0x00000001,0x00000086)
KMODE_EXCEPTION_NOT_HANDLED*** Address 8016a950 has base at 80100000 - ntoskrnl.exe
CPUID:x86 5.6.2 irql:1f SYSVER 0xf0000565
Dll Base DateStmp - Name Dll Base DateStmp - Name
80100000 337546bf - ntoskrnl.exe 80010000 33247f88 - hal.dll
80001000 334d3a53 - atapi.sys 80007000 33248043 - SCSIPORT.SYS
801d7000 336016a2 - Disk.sys 801db000 336015af - CLASS2.SYS
801df000 3356d637 - Ntfs.sys 80237000 344eeb44 - Siwvid.sys
8056e000 344eebdc - NTice.sys f1f48000 31ec6c8d - Floppy.SYS
f1f58000 31ec6ca1 - Cdrom.SYS f228c000 31ec6c99 - Null.SYS
f208c000 31ed868b - KSecDD.SYS f2290000 335e60cf - Beep.SYS
f1f88000 335bc82a - i8042prt.sys f2094000 3324806f - mouclass.sys
f209c000 31ec6c94 - kbdclass.sys f229e000 3373c39d - ctrl2cap.SYS
f1fa0000 33248011 - VIDEOPRT.SYS fe1a4000 349a9c93 - mga64.sys
f20cc000 31ec6c6d - vga.sys f1eb0000 332480dd - Msfs.SYS
f1d50000 332480d0 - Npfs.SYS fe164000 3356da41 - NDIS.SYS
f2124000 3593d4f4 - bluesave.SYS fe141000 335bd30e - Fastfat.SYS
a0000000 336157ac - win32k.sys fe0c2000 349a9cdd - mga64.dll
f1ce0000 332483b0 - Cdfs.SYS fdca2000 31ec6e6c - TDI.SYS
fdc59000 31ed0754 - nbf.sys fdc35000 337390ef - tcpip.sys
fdc18000 3362a53a - netbt.sys f1f68000 33644efb - ibmfent.sys
f1d70000 334d3add - afd.sys f2008000 33248371 - netbios.sys
f207c000 31ec6c9b - Parport.SYS fdc14000 31ec6c9b - Parallel.SYS
f2136000 31ec6c9d - ParVdm.SYS f1dd0000 332480ab - Serial.SYS
fdbaf000 3339777c - rdr.sys fdb9e000 332483b5 - mup.sys
fdaec000 3360f103 - srv.sys
Address dword dump Build [1381] - Name
f206fba4 8016a950 8016a950 00000001 00000086 00000086 00000086 - ntoskrnl.exe
f206fbd0 80115d86 80115d86 00000000 ff87a400 ff87a3f0 ff810408 - ntoskrnl.exe
f206fbec 8019d98f 8019d98f ffffffff 80139a54 80143378 00000000 - ntoskrnl.exe
f206fbf4 80139a54 80139a54 80143378 00000000 230edb30 3c8ca3b0 - ntoskrnl.exe
f206fbf8 80143378 80143378 00000000 230edb30 3c8ca3b0 26448761 - ntoskrnl.exe
f206fc10 8011bd6a 8011bd6a ff676980 ffffffff 34f9ad10 00000000 - ntoskrnl.exe
f206fc38 8011bcce 8011bcce ff676980 ffffffff 34f9ad10 00000000 - ntoskrnl.exe
f206fc60 8016a94e 8016a94e f206fee8 00000000 00000086 f206fe70 - ntoskrnl.exe
f206fc74 8016a950 8016a950 00000008 00000346 f206fe48 00000010 - ntoskrnl.exe
f206fc88 801163e3 801163e3 ff876f58 ff676980 ffffffff 00000000 - ntoskrnl.exe
f206fca4 f1f88825 f1f88825 ff876f58 ff676980 ffffffff ff876f38 - i8042prt.sys
f206fcc8 80117f93 80117f93 ff6c7328 ff876bf0 00000000 801126af - ntoskrnl.exe
f206fcd8 801126af 801126af 00000246 80112717 ff6c7328 00000103 - ntoskrnl.exe
soptest
|
|
|
|
|
Cute, you frigging moron...
|
|
|
|
|
Thanks for the suggestion. I had thought of doing something similar myself, I am fairly new to ATL / COM programming and I find it all very slow going and the lack of good examples (that I could find anyway) make things even harder, all of the books I have read give only very simple example code....
moan
moan
|
|
|
|
|
Another tip, if you can be sure that all access is within the same apartment (usually this means no inter-thread or inter-process access), add the [local] attribute to your IDL.
I know how you are feeling, the trick is to not give up. The road to COM enlightenment is mainly via hard-knocks
HTH
Vivek
|
|
|
|