|
|
#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.<nl> * * @topic Items in ControlItemCollection | * <c CControlItem> is the base class for all of the items in the collection. * X and Y axes on a joystick like device use <c XAxesItem>, DPAD uses * <c CDPADItem>, a proportional DPAD (as on Zorro, and also use for Tilt) * uses <c CPropDPADItem>, Buttons use the class <c CButtonsItem>, Throttle * uses <c CThrottleItem>, a Rudder uses <c CRudderItem>, etc. All of there * class are derived virtually from <c CControlITem>.<nl> * * @topic Custom Base class for <c CControlItem> | * The class was designed so that a client may create a custom base class. * To declare a collection of <c CMyBaseClass>, derive it *virtually* * from CControlItem. Then derive each of the classes created by your factory * from the appropriate control specific derivative and from <c CMyBaseClass>. * For example, <c CMyButtonsItems> would be derived from <c CButtonsItems> and * <c CMyBaseClass>. When creating the collection specify <c CMyBaseClass> in * template specifier for CControlItemCollection.<nl> * * *********************************************************************/
//
// 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 T> 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<PFNGENERICFACTORY>(pfnFactory), reinterpret_cast<PFNGENERICDELETEFUNC>(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<PFNGENERICFACTORY>(pfnFactory), reinterpret_cast<PFNGENERICDELETEFUNC>(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<PVOID *>(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<T *>(collectionImpl.GetFromControlItemXfer(crControlItemXfer)); };
static CControlItem *GetControlFromPtr(PVOID pvItem) { return static_cast<CControlItem *>(reinterpret_cast<T *>(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<CControlItem> { public: CControlItemDefaultCollection(ULONG ulVidPid) : CControlItemCollection<CControlItem>(ulVidPid, &ControlItemDefaultFactory) {} };
#endif //__ControlItemCollection_h__
|