STK and VC++ joint programming practice (the second round: STK service preparation & initialization)

Still taking the sample project "Events" as an example, first start with the MFC standard header file stdafx.h.

stdafx.h

The main global include files are as follows:

First of all, it can be seen that STK is based on COM programming (#include <afxdisp.h>). Note that the lower part of the above picture is the interface information provided by STK. The files defining these interface information are in the first round (supplementary link...) In the mentioned external Include folder (CppIncludes), it is provided by the example code installed by STK by default. There are 33 files in this folder (including 13 .tlb files, 13 .tlh files, 4 .tli files, and 3 .dll files), as shown below:

For the meaning of each file, please refer to the contents of the IDL file in COM programming, where *.tlb is the library file compiled by the IDL file, which can be used in other programming languages; *.tlh is the header file; *.tli is the c/cpp source code. Among them, the agstkobjects.tlh file has 79520 lines! ! ! , these files should be automatically generated by MFC's IDL file compiler, and you will learn more about them later if they are involved.

Events.h/Events.cpp

The header file Events.h is quite satisfactory, and the MFC application class (CWinApp) generated by the standard MFC framework.

In Events.cpp, three STK .tli (C++ source code) files are included. This reference is very important, which is equivalent to directly embedding the method definitions related to IDL (interface) into the project code, because c/c++ needs to be pre-configured function declaration, without this reference, a link error will be reported when the project is built. As shown below:

         

In the application initialization (InitInstance()), the key code is as follows:

Among them, line 48: AfxOleInit(), according to Microsoft documents, is to initialize OLE support for applications, probably to initialize (load when necessary) the DLLs of the OLE system, and to check whether the version is correct. OLE is a higher-level COM technology of MFC. You don't need to understand these technical details for the time being, just know how to use them first.

Line 62: AfxEnableControlContainer(), used together with AfxOleInit(), these two functions are placed under the same entry (OLE Initialization) in the MFC online help, the function is to perform initialization so that the application supports the OLE control container (Original text: Call this funciton in your application object's InitInstance function to enable containment of OLE controls).

Lines 54 to 60 are to perform STK License detection, but according to the code, m_pApp is a local variable. This License detection should not be necessary for the application to run, and it needs to be verified later.

It has been verified that the program can still run normally after the license detection code is commented out, but in the operation of creating a new scene, the code performs license detection again.

Events.cpp, line 55: IAgSTKXApplicationPtr m_pApp;

IAgSTKXApplicationPtr is a smart pointer, defined in the file stkx.tlh (line 96), as follows:

_COM_SMARTPTR_TYPEDEF(IAgSTKXApplication, __uuidof(IAgSTKXApplication));

The method 'CreateInstance()' on line 56 of Events.cpp is a smart pointer (CComPtr) method, see Microsoft online documentation help, entry '_com_ptr_t::CreateInstance', interpreted as: create an object instance for a given CLSID or ProgID, The ProgID here is 'AgSTKXApplication', which is defined in the file stkx.tlh (lines 32~33). as follows:

struct __declspec(uuid("98ac4db1-6e59-4fad-b03d-54a67f1cf350"))

/* dual interface */ IAgSTKXApplication;

According to the declaration, it is a dual interface, which supports both IUnknown calls and IDispatch calls.

ObjectModelEventSink.h/ ObjectModelEventSink.cpp

The COM specification uses the event and callback mechanism to handle the event response and processing between the COM object (server) and the caller (client), that is, the connection point mechanism in the COM specification.

If a COM object can send an event (that is, a callback function) after performing an operation, then this object is called a connectable object (Connectable Object). Each event is called back through the interface, which is called the callback interface (Outgoing Interface), and the caller implements this interface. Then, if the connectable object can call a certain callback interface, then it must define a connection point object (Connection Point Object) for this interface, and the caller implements this callback interface, and its specific implementation type is called Sink (slot, similar to Signal/slot mechanism in QT).

The CObjectModelEventSink class in this instance given by STK is a Sink class, inherited from CCmdTarget, and the CCmdTarget class implements the IDispatch interface, so this custom Sink class also conforms to the COM object standard.

In ObjectModelEventSink.h, the callback functions all start with On*.

ObjectModelEventSink.cpp

In the constructor of the class CObjectModelEventSink executed the method: EnableAutomation() . This method enables the Sink class to receive events passed from the STK COM component object, which is mainly realized through several subsequent macro definitions in the file. The code is as follows:

BEGIN_DISPATCH_MAP(CObjectModelEventSink, CCmdTarget)

DISP_FUNCTION_ID(CObjectModelEventSink, …)

END_DISPATCH_MAP()

BEGIN_INTERFACE_MAP(CObjectModelEventSink, CCmdTarget)

         INTERFACE_PART(CObjectModelEventSink, __uuidof(STKObjects::IAgStkObjectRootEvents), Dispatch)

END_INTERFACE_MAP()

ObjectModelHelper.h/ ObjectModelHelper.cpp

The Helper class is an intermediate class that assists us in calling STK COM object methods (interfaces). The methods of the Helper class can also be called directly anywhere in the application (without passing through the Helper class). Using a Helper class can make the program structure clearer. For example, the code for creating a new scene in the Helper class is as follows:

void CObjectModelHelper ::NewScenario(STKObjects:: IAgStkObjectRootPtr pRoot )

{

    ASSERT(pRoot != NULL);

    pRoot -> NewScenario( "Demo" );

}

In fact, "pRoot->NewScenario("Demo");" can be executed anywhere as long as we have the pRoot object.

EventsDlg.h/EventsDlg.cpp

InitObjectModel()

Important initialization: InitObjectModel(), one of the weird usages, m_pRoot sees that the variable name should be a pointer, it is indeed a pointer, and it is a smart pointer, see the definition in the .h file (IAgStkObjectRootPtr m_pRoot;) but in the first initialization The dot operation (.) is performed in the operation, as follows:

HRESULT hr = m_pRoot.CreateInstance( __uuidof ( AgStkObjectRoot ));

It seems that COM is really extensive and profound. For the scoring situation, if it is the method of the IAgStkObjectRoot (interface) class itself, you need to use the pointer operator (->).

I don't know why, just follow along and learn how to use it! If you don't ask for a deep understanding, you can't understand it for a while.

Then get the IDispatch interface of the Sink class, as follows:

LPUNKNOWN pUnkSink = m_pSink->GetIDispatch(FALSE);

Finally, establish the connection point between the STK COM service and the Sink customized by the client (that is, this application), the code is as follows:

AfxConnectionAdvise(m_pRoot, __uuidof(STKObjects::IAgStkObjectRootEvents),

        pUnkSink, FALSE, &m_dwCookie);

The event callback interface IAgStkObjectRootEvents is defined in the file agstkobjects.tlh (starting from line 4496), and a total of 22 event callback interfaces are defined.

TerminateObjectModel()

Disconnects the connection between the source and the sink. AfxConnectionUnadvise() method, m_pRoot still uses point operation (.), amazing!

onInitDialog()

Initialize the random number generator: srand(), it seems that the STK algorithm relies on random numbers internally. After code analysis, it is found that when adding satellite objects, random numbers are used to generate satellite orbit parameters to ensure that the satellite orbits added each time are random.

Call InitObjectModel() to complete the connection point establishment with the STK COM object.

About the relationship between the 2D and 3D window display and the scene

The 3D window control in the sample dialog interface, after searching for a long time, did not find its relationship with the current scene of STK. It is guessed that the STK application will automatically search for the window controls in the process space, including 2D and 3D windows, and then establish a connection internally for display. Control and update, for this a simple test is performed as follows.

The default mode opens the application dialog box (IDD_EVENTS_DIALOG) in the project resource file, adjusts the interface, and creates three 3D window objects by copying and copying. Except for adjusting the unknown, do nothing else. The adjusted interface is as follows:

 Run the program, create a new scene, and add objects to the scene. As expected, all four windows can be displayed, and you can control the window display zoom, adjust the viewing angle, etc. through mouse operations independently. The running effect is as shown in the figure below:

Guess you like

Origin blog.csdn.net/wangyulj/article/details/123878639