step1: expose a custom COM interface
//denetifc.idl, use the MIDL compiler to create the header file which is to be used in the next step.
interface IMulticastConfig ;
[
object,
uuid (1CB42CC8-D32C-4f73-9267-C114DA470378)
]
interface IMulticastConfig : IUnknown
{
HRESULT
SetNetworkInterface (
[in] ULONG ulNIC // network order
) ;
HRESULT
GetNetworkInterface (
[out] ULONG * pNIC // network order
) ;
HRESULT
SetMulticastGroup (
[in] ULONG ulIP, // network order
[in] USHORT usPort // network order
) ;
HRESULT
GetMulticastGroup (
[out] ULONG * pIP, // network order
[out] USHORT * pPort // network order
) ;
} ;
step 2: implement the IMulticastConfig interface in a filter.
step 3: Implement the ISpecifyPropertyPages interface in the filter.
//dssend.h
class CNetworkSend : public ISpecifyPropertyPagesPages
{
// --------------------------------------------------------------------
// ISpecifyPropertyPages
STDMETHODIMP GetPages (IN OUT CAUUID * pPages) ;
}
//dssend.cpp
STDMETHODIMP
CNetworkSend::GetPages (
IN OUT CAUUID * pPages
)
{
if (pPages == NULL) return E_POINTER;
pPages -> cElems = 1 ;
pPages -> pElems = (GUID *) CoTaskMemAlloc (pPages -> cElems * sizeof GUID) ;
if (pPages -> pElems == NULL) {
return E_OUTOFMEMORY;
}
(pPages -> pElems) [0] = CLSID_IPMulticastSendProppage ;
return S_OK ;
}
/*
CAUUID : a Counted Array of UUID or GUID types.
Structure:
typedef struct tagCAUUID
{
ULONG cElems;
GUID FAR* pElems;
} CAUUID;
Members:
cElems
Size of the array
pElems
Pointer to an array of UUID values, each of which specifies a CLSID of a particular property page. This array is allocated by the callee using CoTaskMemAlloc and is freed by the caller using CoTaskMemFree.
*/
/*
CoTaskMemAlloc
Allocates a block of task memory.
Syntax
LPVOID CoTaskMemAlloc( ULONG cb);
Parameter
cb : size, in bytes, of the memory block to be allocted.
Return Values
Allocated memory block, if failed, return NULL.
*/
step 4:expose the filter's new interface to clients, so it need to support QueryInterface.
step 5: create the Property Page. The filter supports everything that it needs for the Property page.
step 6: Store a Pointer to the Filter overriding the CBasePropertyPage::OnConnect method.
step 7: override the CBaseProportyPage::OnActivate method and use the current value of the filter's property to initialize the Dialog.
step 8: override the CBasePropertyPage::OnReceiveMessage method to update the dialog controls in response to user input. If it is unneeded to handle a particular message, call the OnReceiveMessage method on the parent class.
step 9: override the CBasePropertyPage::OnApplyChanges method to commit any property changes.
step 10: override the CBasePropertyPage:OnDisconnect method to release any interface that obtained in the OnConnect method.
step11 : support COM registration