You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
393 lines
12 KiB
393 lines
12 KiB
#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__
|