Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I implement an interface from a COM object?

Status
Not open for further replies.

wcglorioso

Programmer
Jul 23, 2003
30
PH
"I am creating an event handler for a COM server."

"Here is my class definition in Visual Foxpro 7:"

DEFINE CLASS KeyEVH as Session OLEPUBLIC
IMPLEMENTS IAppEventHandler IN "dataentry.exe"
PROCEDURE IAppEventHandler_EventNotify( ;
evtID As Long, ;
fdt As Long, ;
hwindow As Long, ;
FieldName As String, ;
FieldData As Variant, ;
p1 As Variant, ;
p2 As Variant, ;
evtDisposition As Long @, ;
R1 As Variant @, ;
R2 As Variant @)

ENDPROC
ENDEFINE

"It is based on both a Visual Basic 6 and Visual C++ 6 class definition which worked as expected but which faile.d"

"Here is an equivalent class module definition in Visual Basic 6:"

Option Explicit
Implements IAppEventHandler

Private Sub IAppEventHandler_EventNotify( _
ByVal evtID As Long, _
ByVal fdt As Long, _
ByVal hwnd As Long, _
ByVal FieldName As String, _
ByVal FieldData As Variant, _
ByVal p1 As Variant, _
ByVal p2 As Variant, _
evtDisposition As Long, _
R1 As Variant, _
R2 As Variant)

EndSub

"A memory read access violation is generated when I use the Visual Foxpro version which does not occur in Visual Basic and Visual C++ (compile time error is negative, just this runtime error)"

"I removed all other properties and methods not related to implementing the interface and merely declared the only method defined by the interface (to prevent compilation error) but still the error persist when I open the COM server with the external event handler."

"What do you think was happening?"

"What might I have done wrong?"

"Don't want to learn another programming language just for this."

"Hope you can enlighten me on this."

"If my details are insufficient please let me know."

"Thanks in advance."
 
wcgglorioso

I'm not sure, but is any of these properties supported in VFP?
evtID As Long, ;
fdt As Long, ;
hwindow As Long, ;
FieldName As String, ;
FieldData As Variant, ;
p1 As Variant, ;
p2 As Variant, ;
evtDisposition As Long @, ;
R1 As Variant @, ;
R2 As Variant @)




Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
mgagnon,

No compile time error occurs in building my COM server DLL.
Intellisense popped out as I declare my variables hence it should be supported.
The @ sign after the data type indicates you are passing the variable by reference (by value otherwise).
I am using Visual Foxpro 7 COM technology features.
Do you think my declaration was the problem?
 
I'm not sure where the "interface" part would come in, as your title suggests, and just to clear things up a COM server DLL in VFP does not support any interface of any kind., you would have to use a COM exe.

Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
"Here is the actual type library of the COM server I am building an event handler for:"

// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: dataentry.exe

[
uuid(781FD662-A607-11D2-906E-00A0C926DC9D),
version(1.2),
helpstring("IDWorks DataEntry SDK 2.2 Type Library")
]
library DataEntrySDK
{
// TLib : // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
importlib("StdOle2.Tlb");

// Forward declare all types defined in this typelib
dispinterface IDataEntry;
dispinterface IDataEntry2;
interface IIDWorksEventHandler;

typedef enum {
EV_START = 0,
EV_CLEAR = 1,
EV_DELETE_POST = 2,
EV_DELETE_PRE = 3,
EV_ENTER_FIELD = 4,
EV_EXIT_FIELD = 5,
EV_FIRST_PRE = 6,
EV_FIRST_POST = 7,
EV_INSERT_POST = 8,
EV_INSERT_PRE = 9,
EV_KEY_PRESS = 10,
EV_LAST_PRE = 11,
EV_LAST_POST = 12,
EV_LBUTTON_DBLCLK = 13,
EV_NEW_POST = 14,
EV_NEW_PRE = 15,
EV_NEXT_PRE = 16,
EV_NEXT_POST = 17,
EV_PREV_PRE = 18,
EV_PREV_POST = 19,
EV_PRINT_POST = 20,
EV_PRINT_PRE = 21,
EV_RBUTTON_DOWN = 22,
EV_REFRESH_POST = 23,
EV_REFRESH_PRE = 24,
EV_UPDATE_POST = 25,
EV_UPDATE_PRE = 26,
EV_SEARCH_PRE = 27,
EV_SEARCH_POST = 28,
EV_PROJECT_LOAD = 29,
EV_PROJECT_UNLOAD = 30,
EV_PRINTALL_PRE = 31,
EV_PRINTALL_POST = 32,
EV_CANCELNEW_PRE = 33,
EV_CANCELNEW_POST = 34,
EV_ADVANCEDSEARCH_PRE = 35,
EV_ADVANCEDSEARCH_POST = 36,
EV_RUNSTOREDSEARCH_PRE = 37,
EV_RUNSTOREDSEARCH_POST = 38,
EV_PROJECT_READY = 39,
EV_PRINTALL_CANCEL = 40,
EV_EVENT_BUTTON = 41,
EV_VERIFY_POST = 42,
EV_VERIFY_PRE = 43,
EV_CAPTURE_POST = 44,
EV_CAPTURE_PRE = 45,
EV_END = 46
} EVENT_ID;

typedef enum {
ED_CONTINUE = 0,
ED_NOCONTINUE = 1,
ED_CHANGE_DATA = 2,
ED_NOPROCESS = 4,
ED_SETMODIFIED = 8,
ED_CLRMODIFIED = 16
} EVENT_DISPOSITION;

typedef enum {
FDT_NULL = 0,
FDT_LONG = 1,
FDT_DOUBLE = 2,
FDT_TEXT = 3,
FDT_DATE = 4,
FDT_IMAGE = 5,
FDT_SIGNATURE = 6,
FDT_PRINTCOUNT = 7,
FDT_AUTOSEQ = 8,
FDT_BINARY = 9,
FDT_MAX = 10
} SCREEN_FIELD_DATA_TYPE;

typedef enum {
FT_NULL = 0,
FT_TEXT = 1,
FT_DATE = 2,
FT_IMAGE = 3,
FT_STATIC_TEXT = 4,
FT_STATIC_GRAPHIC = 5,
FT_COMPOSITE = 6,
FT_LIST = 7,
FT_SIGNATURE = 8,
FT_PRINTCOUNT = 9,
FT_AUTOSEQ = 10,
FT_BINARY = 11,
FT_BUTTON = 12,
FT_MAX = 13
} SCREEN_FIELD_TYPE;

typedef enum {
FRC_OK = 1,
FRC_OK_DATA_BY_FILE = 2,
FRC_NO_PROJECT_OPEN = 3,
FRC_FIELD_NOT_FOUND = 4,
FRC_UNSUPPORTED = 5,
FRC_NO_DATA = 6,
FRC_ERROR = 7,
FRC_INVALID_DATA = 8,
FRC_DATA_TRUNCATED = 9,
FRC_SOURCE_NOT_FOUND = 10,
FRC_CONFIG_NOT_FOUND = 11,
FRC_USER_CANCEL = 12
} FUNCTION_RTN_CODE;

typedef enum {
acSTART = 0,
acLEFT = 0,
acTOP = 1,
acRIGHT = 2,
acBOTTOM = 3,
acFIELDTYPE = 4,
acDATAMODIFIED = 5,
acMANDATORY = 6,
acVISIBLE = 7,
acREADONLY = 8,
acEMPTY = 9,
acBUFFERLENGTH = 10,
acEND = 11
} ATTRIBUTE_CODE;

[
uuid(E7EBB060-BA87-11D2-906E-00A0C926DC9D),
helpstring("IDWorks DataEntry SDK IDataEntry Interface")
]
dispinterface IDataEntry {
properties:
methods:
[id(0x00000001)]
long PrintCard(short bShowDialog);
[id(0x00000002)]
long DeleteRecord();
[id(0x00000003)]
void FirstRecord();
[id(0x00000004)]
void LastRecord();
[id(0x00000005)]
void NextRecord();
[id(0x00000006)]
void PreviousRecord();
[id(0x00000007)]
void Search();
[id(0x00000008)]
short UpdateRecord();
[id(0x00000009)]
void NewRecord();
[id(0x0000000a)]
void ShowForm(short bShow);
[id(0x0000000b)]
long SetFieldData(
BSTR FieldName,
VARIANT* pFieldData,
short bSetModified);
[id(0x0000000c)]
void ClearForm(short bAll);
[id(0x0000000d)]
long GetFieldData(
BSTR FieldName,
VARIANT* pFieldData,
short bWithMask);
[id(0x0000000e)]
BSTR GetProjectName();
[id(0x0000000f)]
long GetFieldAttribute(
BSTR FieldName,
short AttributeType,
VARIANT* pAttribute);
[id(0x00000010)]
void EnableForm(short bEnable);
[id(0x00000011)]
long SetFieldAttribute(
BSTR FieldName,
short AttributeType,
VARIANT* pAttributeValue);
[id(0x00000012)]
long GetFieldNames(VARIANT* vFieldNames);
[id(0x00000013)]
void ShowCardPreviewFront(short bVisible);
[id(0x00000014)]
void ShowCardPreviewBack(short bVisible);
};

[
uuid(1CA57410-8D68-11D3-80ED-0050040B83CD),
helpstring("IDWorks DataEntry SDK IDataEntry2 Interface")
]
dispinterface IDataEntry2 {
properties:
methods:
[id(0x00000001)]
long PrintCard(short bShowDialog);
[id(0x00000002)]
long DeleteRecord();
[id(0x00000003)]
void FirstRecord();
[id(0x00000004)]
void LastRecord();
[id(0x00000005)]
void NextRecord();
[id(0x00000006)]
void PreviousRecord();
[id(0x00000007)]
void Search();
[id(0x00000008)]
short UpdateRecord();
[id(0x00000009)]
void NewRecord();
[id(0x0000000a)]
void ShowForm(short bShow);
[id(0x0000000b)]
long SetFieldData(
BSTR FieldName,
VARIANT* pFieldData,
short bSetModified);
[id(0x0000000c)]
void ClearForm(short bAll);
[id(0x0000000d)]
long GetFieldData(
BSTR FieldName,
VARIANT* pFieldData,
short bWithMask);
[id(0x0000000e)]
BSTR GetProjectName();
[id(0x0000000f)]
long GetFieldAttribute(
BSTR FieldName,
short AttributeType,
VARIANT* pAttribute);
[id(0x00000010)]
void EnableForm(short bEnable);
[id(0x00000011)]
long SetFieldAttribute(
BSTR FieldName,
short AttributeType,
VARIANT* pAttributeValue);
[id(0x00000012)]
long GetFieldNames(VARIANT* vFieldNames);
[id(0x00000013)]
void ShowCardPreviewFront(short bVisible);
[id(0x00000014)]
void ShowCardPreviewBack(short bVisible);
[id(0x00000015)]
long LoadProject(BSTR ProjectName);
[id(0x00000016)]
long ExecuteStoredSearch(BSTR StoredSearchName);
[id(0x00000017)]
long PrintCard2(
short nCopies,
short bPrint,
short bEncode,
BSTR sPrinterName);
[id(0x00000018)]
long ExecuteSQLSearch(
BSTR Filter,
BSTR Sort);
[id(0x00000019)]
short EnableCardCompletion(short bEnable);
[id(0x0000001a)]
short GetLastPrintJobID(long* PrintJobID);
[id(0x0000001b)]
short Capture(
BSTR FieldName,
BSTR SourceName);
[id(0x0000001c)]
short CaptureBiometric(
BSTR FieldName,
BSTR DeviceName,
BSTR ConfigName);
};

[
odl,
uuid(781FD661-A607-11D2-906E-00A0C926DC9D),
helpstring("IDWorks DataEntry SDK IIDWorksEventHandler Interface")
]
interface IIDWorksEventHandler : IDispatch {
[helpstring("method EventNotify")]
HRESULT _stdcall EventNotify(
[in] long evtID,
[in] long fdt,
[in] long hwnd,
[in] BSTR FieldName,
[in] VARIANT FieldData,
[in] VARIANT p1,
[in] VARIANT p2,
[in, out] long* evtDisposition,
[in, out] VARIANT* R1,
[in, out] VARIANT* R2);
};

[
uuid(781FD663-A607-11D2-906E-00A0C926DC9D),
helpstring("IDWorks DataEntry SDK Class")
]
coclass SDK {
[default] interface IUnknown;
dispinterface IDataEntry;
dispinterface IDataEntry2;
};

[
uuid(781FD670-A607-11D2-906E-00A0C926DC9D),
helpstring("IDWorks EventHander Class")
]
coclass EVH {
[default] interface IUnknown;
interface IIDWorksEventHandler;
};
};

"IIDWorksEventHandler is the interface I want to implement"

"I will try using the outprocess COM server then (exe)"

"Had tried to build my event handler with Single-threaded COM Server (dll) and Multi-threaded COM Sever (dll) which both failed"

"Had not tried the Win32 executable/COM server (exe) build because the Visual Basic and C++ versions are DLLs that had worked seemlessly with the ID Works application"

"Do share me other information you know if you will regarding COM programming"

"Thanks for your replies"
 
I have no experience with Interfaces, so these are stabs in the dark:

While my suggestions below may have merit, I think this statement from MSDN is your problem:
When you implement an interface, you must include in the class definition all methods of that interface

See the last "Tip" for a quick way to do the above....

It seems, like you say, the interface is "IIDWorksEventHandler", so why refer to it as "IAppEventHandler" in the code?

Also, it's likely that the current directory isn't what you think it is, and the file dataentry.exe cannot be found during execution: Try giving the full path to the file.

Also, try using the ProgID instead of the type library (ie, use 'IDWorks.DataEntry' or whatever it's supposed to be, instead of the .exe file itself... let the windows Registry determine where the .exe containing the type library is.
* From MSDN: The Typelib option is the least recommended way to specify the typelib since this requires a file name whose path may differ from machine to machine. If your DLL is being distributed, consider using TypeLibGUID or ProgID.

Also, this recommendation from MSDN may auto-fix your problem: Tip Use the Visual FoxPro Object Browser to drag and drop an interface definition to your code to save time. The IMPLEMENTS statement, along with all the implemented methods with their proper parameter signatures, will be automatically written out for you.

 
You may be using this already, but check out the EventHandler function in VFP, too, for binding the interface implementor object to a COM object event source.

( BTW, "What's with all the quotes?" )
 
Build my event handler as an EXE.

"No such interface supported." was the error this time.

According to MSDN,the COM server class (dataenty.exe or "DataCard.SDK"), to which I want to create an event handler by implementing the IIDWorksEventHandler interface may have no support for late-binding (as suggested by the OLE eror).

Now my problem is how do I make use of GetInterface()function that return an early-bound object reference from an existing one.

I need to customize the only interface method available (EventNotify) to react to certain events such as shotcut keys, data alterations, etc.

ID Works expects a COM server class implementing the interface.

Can anyone tell me how I can define a class that implements the said interface (early-binding)?

BTW, sorry for misleading you regarding the interface name. As for the quotes, I intend it to let you know the statements I wrote myself with the rest from excepts.

Didn't put quotes though coz my intention does not reveal itself afterall with it.

I still don't get it why it worked in Visual Basic and C++ but not in Visual Foxpro 7!

But anyway, your feedbacks are leading me to the answer so thank you very much for them.
 
Glad to help... we all learn by poking around: now I know a little something of interfaces!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top