VB ActiveX Does Not Support Externally Defined Events
* If you define an interface in a Type Library and implement it in Visual Basic, no problem.
* For example, if you define an interface ITestInterface in a Type Library and then have your VB ActiveX project reference this type lib, the following statement goes fine :
Implements ITestInterface
* However, if you define a source (i.e. event) interface in a Type Library and try to have a Visual Basic ActiveX raise its events via RaiseEvent statements, not possible.
* For example, if you define a dispinterface _ITestEvents with event Event01() in a Type Library and then have your VB ActiveX Project raise it as follows :
RaiseEvent Event01()
The VB Compiler will complain of an unidentified event.
If you try to raise it as follows :
RaiseEvent <typelibraryname>.Event01()
The compiler will not complain but it still won't work. The problem is that _ITestEvents will not be recognized as being a source interface of the ActiveX.
* If we try to define the events of _ITestEvents in the declaration of the ActiveX itself, e.g. :
Public Event Event01()
The ActiveX will then declare a source interface for itself and Event01() will be absorbed into this default source event set, i.e. you will find the following declarations when you observe the TLB generated for the ActiveX :
coclass clsVBActiveX
{
...
...
...
[default, source] dispinterface __clsVBActiveX;
};...
...
...
dispinterface __clsVBActiveX
{
void Event01();
};
_______________________
Tip Courtesy :- Lim Bio Liong
Different way of using break-point in visual cpp?
click on this link to more about this. This is by Microsoft MVP Nibu thomas. god bless him.
How to detect user's language for user interface
MSDN has weath of knowledge, only if we able to find it.
. Anyways following api's can help in achieving multilanguage support for your application:-
- GetUserDefaultUILanguage()
- GetSystemDefaultUILanguage()
- GetSystemDefaultLangID()
How to detect user’s language for user interface
MSDN has weath of knowledge, only if we able to find it.
. Anyways following api's can help in achieving multilanguage support for your application:-
- GetUserDefaultUILanguage()
- GetSystemDefaultUILanguage()
- GetSystemDefaultLangID()
Two Ways To Reference External Types Into An IDL?
1. There are two ways to reference types defined externally in an IDL file :
1.1 Via the [import] MIDL directive.
1.2 Via the [importlib] MIDL directive.
2. An example use of the [import] directive is listed below :
import "msado15.idl";
2.1 This avails all definitions inside the imported IDL file ("msado15.idl" in above example) inside the current IDL file.
3. An example use of the [importlib] directive is listed below :
library MyInterfacesLib
{
importlib("msado15.tlb");
...
};
3.1 This avails all types that have already been compiled in another type library ("msado15.tlb" in the above example) to the current IDL file.
3.2 Note that an [importlib] statement can only appear inside a [library] statement. Furthermore, the imported type library, together with the generated type library of the current IDL file, must be available at runtime for the application.
3.3 Now, unlike the [import] statement, where a #include <header file of the imported IDL> directive is generated inside the .h file the current IDL, an [importlib] statement does not cause the generation of such an #include statement.
3.4 Because of this, the cpp_quote IDL keyword should be used to #include any necessary header files in the generated .h file for the current IDL. For example :
cpp_quote("#include \"msado15.h\"")
Handling COM Events in an MFC Client.
1. The API to use for connecting to the event source of an object to a sink in a client application is AfxConnectionAdvise().
2. Assuming an event source interface that is purely IDispatch-based, we can implement an event sink (using MFC) via a CCmdTarget-derived class.
3. Listed below are the basic requirements of a sink :
3.1 It must implement IDispatch.
3.2 It must acknowledge the support of the DIID (dispatch ID) of the outgoing event interface.
3.3 It must implement the methods of the outgoing source interface.
4. Based on the requirements listed above, we can proceed to create an eventsink that is based on code provided by MFC. The following are the salient points of such a class :
4.1 It must derive from CCmdTarget. This is due to the CCmdTarget class' internal support of the IDispatch interface (as per requirement 3.1). The CCmdTarget's IDispatch implementation is achieved via a tiny embedded class named XDispatch. An instance of this emdedded class (m_xDispatch) is declared inside CCmdTarget. m_xDispatch must first be initialized via the CCmdTarget::EnableAutomation() function. This should be called inside the constructor of the sink class.
4.2 It must include the DECLARE_INTERFACE_MAP() macro in its class definition. This indicates to the MFC framework that this class will have a custom interface map. Through the interface map, we declare the various interfaces (including any source Dispatch interface) supported by the sink class (as per requirement 3.2). Via the macros BEGIN_INTERFACE_MAP(), INTERFACE_PART() and END_INTERFACE_MAP(), we declare that the sink class implements the source Dispatch interface.
4.3 It must include the DECLARE_DISPATCH_MAP() macro in its class definition. This macro indicates to the framework that this class will provide a dispatch map to expose IDispatch-based methods and properties. Through the diapatch map, we declare the various methods and properties exposed by the sink class. The methods must of course correspond with the methods of the source IDispatch interface (as per requirement 3.3).
The macros used are : BEGIN_DISPATCH_MAP(), DISP_FUNCTION(), DISP_PROPERTY(), END_DISPATCH_MAP().
5. In a call to AfxConnectionAdvise(), the 3rd parameter must be the IUnknown interface pointer to the event sink. To get this IUnknown interface pointer, the entry point function is the CCmdTarget::GetIDispatch() function. Call this function using the sink object. From the IDispatch interface pointer returned from CCmdTarget::GetIDispatch(), we can QueryInterface() it for an IUnknown interface pointer.
_______________________
Tip Courtesy :- Lim Bio Liong