When you declare an interface pointer variable, initially it is 0. That is, it does not refer to an object. Before using it to call COM object functions, you must create new object or get existing object. For this purpose, you can use functions described in this topic. Common syntax is:
ip.function(arguments)
Here ip is interface pointer variable. Each function returns ip itself.
ip._create([class])
Creates new COM object of class type and populates ip with object's address.
If class is omitted or 0, is used class of ip. Usually class is omitted, because QM knows it. Class is unknown when the variable is declared as IDispatch or other interface, not as a coclass. As class, you can use CLSID or ProgId of object's class. It can be either GUID* (see uuidof), or string in form "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", or ProgID string in form "Application.Class".
Objects of that class must be externally creatable, and class must be registered. If class is not registered, QM tries to register the component automatically, but this should be used only while experimenting with a new component. To register automatically, are required administrator privileges. For this reason, auto registration will not work on user accounts with limited privileges and on Windows Vista if QM is running not as administrator. Also, it does not work in exe. Read here about installing/registering and using COM components.
To create object that must exist while dialog is running, declare the variable in dialog procedure, under WM_INITDIALOG, as thread variable (with -), e.g., Typelib.Class- obj._create. Or, you can declare it before ShowDialog. If you declare it as local (without -) in dialog procedure, it will be quickly destroyed, because dialog procedure is called multiple times while the dialog is displayed. Actually, thread variables are destroyed when thread ends (macro ends), not when destroying dialog. If it is important to delete the object immediately when dialog is closed, under WM_DESTROY assign 0, e.g., obj=0.
This function is not used to create ActiveX controls for dialogs, but it can be used to create ActiveX controls that provide useful functions without being visible.
QM 2.2.1. Some ActiveX controls created using this function will not work anymore. Place them in a dialog. Some others will work better.
ip._getactive([class] [flags] [moniker])
Gets currently active object of class type and populates ip with object's address.
class - object's class (see _create). If omitted or 0, is used class of ip or moniker.
| 0 (default) | if there is no active object, generate error. |
| 1 | if there is no active object, create new. |
| 16 | display available moniker strings. Example: ip._getactive(0 16 ".") |
moniker (QM 2.2.0) - object's name in system Running Object Table (ROT). Can contain wildcard characters. If not found in ROT, and class is specified or known, the function tries to get or create object.
This function may fail on Vindows Vista. There are several workarounds.
ip._getfile(file [class])
Gets object from file, starts the associated application, and populates ip with object's address. If class is used, gets object of class type (uses different method). If class is omitted or 0, is used class of ip (see _create).
file also can be moniker. For example, it is easier to get WMI services using moniker string, such as "winmgmts:".
ip._getcontrol(hwndcontrol)
Retrieves ActiveX control object that is hosted by hwndcontrol in a dialog. In QM, an ActiveX control is created and hosted by a child window of class "ActiveX", so hwndcontrol must be handle of that child window. To get it, use function id. For example, if control id in dialog is 3, then you can use id(3 hDlg). Usually it is not the id you see in the status bar, because an ActiveX control also creates its own child window that covers the host child window. The id is shown in the dialog definition (it is the first number in the green line with "ActiveX"). This function is inserted when you click the Events button in the Dialog Editor.
ip._setevents([eventfolder] [flags])
Activates or deactivates object's events.
You also can use other ways to create/get COM objects. You can use universal or specialized API functions (example 4). Objects that are not externally creatable, usually are retrieved using properties (functions) of other objects of that component (example 3). Functions acc, htm and web also return interface pointer.
1. Create Excel Application object and make window visible: typelib Excel {00020813-0000-0000-C000-000000000046} 1.2 Excel.Application a._create a.Visible=TRUE; err 2. You can specify class, although usually this is not necessary. Several examples how can be specified class: Excel.Application b c d b._create("Excel.Application") c._create(uuidof(Excel.Application)) d._create("{00024500-0000-0000-C000-000000000046}") 3. Get Excel Workbook object from file; get pointers to other interfaces; make window and document visible: Excel.Workbook x._getfile("$desktop$\Book5.xls") Excel.Application a=x.Application a.Visible=TRUE; err Excel.Windows ws=a.Windows Excel.Window w=ws.Item(1) w.Visible=TRUE 4. Use dll function to get interface pointer: IAccessible a if(AccessibleObjectFromWindow(hwnd 0 uuidof(IAccessible) &a)) ret out a.accName(0)