#ifndef __ControlItemCollection_h__ #define __ControlItemCollection_h__ //@doc /********************************************************************* * * @module ControlItemCollection.h | * * Declares the ControlItemCollection class and related classes * * History * ---------------------------------------------------------- * Mitchell S. Dernis Original * * (c) 1986-1998 Microsoft Corporation. All right reserved. * * @topic CControlItemCollection | * The ControlItemCollection class is a templatized class used for * representing the controls on a device. The depends on the client * using the class are non-trivial and therefore the following sections * should be read carefully. * * @topic Items in ControlItemCollection | * is the base class for all of the items in the collection. * X and Y axes on a joystick like device use , DPAD uses * , a proportional DPAD (as on Zorro, and also use for Tilt) * uses , Buttons use the class , Throttle * uses , a Rudder uses , etc. All of there * class are derived virtually from . * * @topic Custom Base class for | * The class was designed so that a client may create a custom base class. * To declare a collection of , derive it *virtually* * from CControlItem. Then derive each of the classes created by your factory * from the appropriate control specific derivative and from . * For example, would be derived from and * . When creating the collection specify in * template specifier for CControlItemCollection. * * *********************************************************************/ // // Warning 4250 notifies you that some virtual functions are inherited via // dominance (See a good C++ text on virtual base classes). This warning // would be generated by client code if they use scheme described above // for a custom base class for controls. // #pragma warning( disable : 4250 ) #include "ListAsArray.h" #include "ControlItems.h" // // @struct DEVICE_CONTROLS_DESC | Describes a paritcular device in terms // of its VidPid, it CONTROL_ITEM_DESC and it MODIFIER_DESC_TABLE. // struct DEVICE_CONTROLS_DESC { ULONG ulVidPid; //@field VID in high word and PID in low ULONG ulControlItemCount; //@field Number of control descriptors RAW_CONTROL_ITEM_DESC *pControlItems; //@field Array of control descriptors MODIFIER_DESC_TABLE *pModifierDescTable; //@field Pointer to modifier descriptor table }; typedef DEVICE_CONTROLS_DESC *PDEVICE_CONTROLS_DESC; // // This table is assumed to be linked in. // extern DEVICE_CONTROLS_DESC DeviceControlsDescList[]; typedef HRESULT (*PFNGENERICFACTORY) ( USHORT usType, const CONTROL_ITEM_DESC* cpControlItemDesc, PVOID *ppControlItem ); typedef CControlItem *(*PFNGETCONTROLITEM)(PVOID); typedef void (*PFNGENERICDELETEFUNC)(PVOID pItem); // // @class | Implementation of CControlItemCollection // class CControlItemCollectionImpl { public: // // @method | CControlItemCollection | CControlItemCollection | // C'tor, takes preparsed data and a factory to generate classes // CControlItemCollectionImpl():m_ulMaxXfers(0), m_ulModifiers(0){} HRESULT Init( ULONG ulVidPid, //@parm [in] Vid in the high word, Pid in the low word PFNGENERICFACTORY pfnFactory, //@parm [in] pointer to function which acts // on pFactoryHandle PFNGENERICDELETEFUNC pfnDeleteFunc //@parm [in] delete function to used for control items ); // // @method | CControlItemCollection | GetFirst | // Returns next control item in collection. If *pulCookie=0 on entry , returns first object. // @rdesc TRUE on success, FALSE if no more items in collection // HRESULT GetNext( PVOID *ppControlItem, //@parm [out] Next control item in collection ULONG& rulCookie //@parm [in\out] Cookie to continue enumeration ) const; // // @method | CControlItemCollection | GetFromControlItemXfer | // Given a ControlItemXfer gets the corresponding control item from the collection. // @rdesc Pointer to item, or NULL if not found PVOID GetFromControlItemXfer( const CONTROL_ITEM_XFER& crControlItemXfer //@parm [in] report selector to get object for ); // // Read\Write to Report // NTSTATUS ReadFromReport( PHIDP_PREPARSED_DATA pHidPreparsedData, PCHAR pcReport, LONG lReportLength, PFNGETCONTROLITEM GetControlFromPt ); NTSTATUS WriteToReport( PHIDP_PREPARSED_DATA pHidPreparsedData, PCHAR pcReport, LONG lReportLength, PFNGETCONTROLITEM GetControlFromPtr ) const; // // Functions dealing with internal state // inline ULONG GetMaxXferRequired() const { return m_ulMaxXfers; } void SetDefaultState( PFNGETCONTROLITEM GetControlFromPtr ); HRESULT GetState( ULONG& ulXferCount, PCONTROL_ITEM_XFER pControlItemXfers, PFNGETCONTROLITEM GetControlFromPtr ); HRESULT SetState( ULONG ulXferCount, PCONTROL_ITEM_XFER pControlItemXfers, PFNGETCONTROLITEM GetControlFromPtr ); void SetStateOverlayMode( PFNGETCONTROLITEM GetControlFromPtr, BOOLEAN fEnable ); inline ULONG GetModifiers() const { return m_ulModifiers; } inline void SetModifiers(ULONG ulModifiers) { m_ulModifiers = ulModifiers; } private: CListAsArray m_ObjectList; ULONG m_ulDeviceIndex; ULONG m_ulModifiers; ULONG m_ulMaxXfers; }; // @class CControlItemCollection | // An instance of this class contains a list of control item objects which represent // the controls on the device. The numbers and types of objects depend // not only the configuration of the device (obtained through the VidPid and a lookup table // - passed in the c'tor), but also on the CControlItemFactory which pairs // each control item with an object. // @tcarg class | T | Custom base class for control items to store in collection. template class CControlItemCollection { public: typedef HRESULT (*PFNFACTORY) ( USHORT usType, const CONTROL_ITEM_DESC* cpControlItemDesc, T **ppDeviceUsage ); typedef void (*PFNDELETEFUNC)(T *pItem); // // @method | CControlItemCollection | CControlItemCollection | // C'tor, takes a VidPid and a factory to generate classes // CControlItemCollection( ULONG ulVidPid, //@parm [in] Vid in the high word, Pid in the low word PFNFACTORY pfnFactory, //@parm [in] pointer to factory method for control item objects PFNDELETEFUNC pfnDeleteFunc=NULL //@parm [in] pointer to function for deleting the objects ) { if(!pfnDeleteFunc) { pfnDeleteFunc = DefaultDeleteFunc; } // // Init implementation // collectionImpl.Init( ulVidPid, reinterpret_cast(pfnFactory), reinterpret_cast(pfnDeleteFunc) ); } // // @method | CControlItemCollection | CControlItemCollection | // C'tor, which takes no parameters, much call init before using! // CControlItemCollection() : collectionImpl() {}; // // @method | CControlItemCollection | Init | // Must call after the default constructor, does the collection initialization // HRESULT Init( ULONG ulVidPid, //@parm [in] Vid in the high word, Pid in the low word PFNFACTORY pfnFactory, //@parm [in] pointer to factory method for control item objects PFNDELETEFUNC pfnDeleteFunc=NULL //@parm [in] pointer to function for deleting the objects ) { if(!pfnDeleteFunc) { pfnDeleteFunc = DefaultDeleteFunc; } // // Init implementation // return collectionImpl.Init( ulVidPid, reinterpret_cast(pfnFactory), reinterpret_cast(pfnDeleteFunc) ); } // // @method | CControlItemCollection | GetFirst | // Returns next control item in the collection. If *pulCookie=0 on entry , returns first object. // @rdesc TRUE on success, FALSE if no more objects in collection // inline HRESULT GetNext( T **ppControlItem, //@parm [out] Next control item object in collection ULONG& rulCookie //@parm [in\out] Cookie to continue enumeration ) const { // // Defer to implementation // return collectionImpl.GetNext( reinterpret_cast(ppControlItem), rulCookie ); } // // @method | CControlItemCollection | GetFromControlItemXfer | // Given a ControlItemXfer gets the corresponding control item object from the collection. // @rdesc Pointer to Control Item, or NULL if not found. inline T *GetFromControlItemXfer( const CONTROL_ITEM_XFER& crControlItemXfer //@parm [in] ControlItemXfer to get control item object for ) { // // Defer to implementation // return reinterpret_cast(collectionImpl.GetFromControlItemXfer(crControlItemXfer)); }; static CControlItem *GetControlFromPtr(PVOID pvItem) { return static_cast(reinterpret_cast(pvItem)); } static void DefaultDeleteFunc(T *pItem) { delete pItem; } // // Read\Write to Report // inline NTSTATUS ReadFromReport( PHIDP_PREPARSED_DATA pHidPPreparsedData, PCHAR pcReport, LONG lReportLength ) { return collectionImpl.ReadFromReport( pHidPPreparsedData, pcReport, lReportLength, &GetControlFromPtr ); } inline NTSTATUS WriteToReport( PHIDP_PREPARSED_DATA pHidPPreparsedData, PCHAR pcReport, LONG lReportLength ) const { return collectionImpl.WriteToReport( pHidPPreparsedData, pcReport, lReportLength, &GetControlFromPtr ); } inline void SetDefaultState() { collectionImpl.SetDefaultState(&GetControlFromPtr); } inline ULONG GetMaxXferRequired() const { return collectionImpl.GetMaxXferRequired(); } inline HRESULT GetState( ULONG& ulXferCount, PCONTROL_ITEM_XFER pControlItemXfers) { return collectionImpl.GetState( ulXferCount, pControlItemXfers, &GetControlFromPtr ); } inline HRESULT SetState( ULONG& ulXferCount, PCONTROL_ITEM_XFER pControlItemXfers) { return collectionImpl.SetState( ulXferCount, pControlItemXfers, &GetControlFromPtr ); } inline ULONG GetModifiers() const { return collectionImpl.GetModifiers(); } inline void SetModifiers(ULONG ulModifiers) { collectionImpl.SetModifiers(ulModifiers); } inline void SetStateOverlayMode(BOOLEAN fEnable) { collectionImpl.SetStateOverlayMode(&GetControlFromPtr, fEnable); } private: CControlItemCollectionImpl collectionImpl; }; HRESULT ControlItemDefaultFactory ( USHORT usType, const CONTROL_ITEM_DESC* cpControlItemDesc, CControlItem **ppControlItem ); // // @class Default collection where objects in collection have only the // the CControlItem class as their base classes. // class CControlItemDefaultCollection : public CControlItemCollection { public: CControlItemDefaultCollection(ULONG ulVidPid) : CControlItemCollection(ulVidPid, &ControlItemDefaultFactory) {} }; #endif //__ControlItemCollection_h__