?? devicechooser.cpp
字號:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>
#include "DeviceChooser.h"
#define _STRINGS_DEFINE_STRINGS
#include "ObexStrings.h"
#define MSG_OBEX_EVENT (WM_USER + 1001)
static BOOL fIsEnuming;
class CObexSink : public IObexSink
{
public:
CObexSink(HWND hWnd)
{
_hWnd = hWnd;
_ulRefs = 0;
}
~CObexSink() {}
public:
HRESULT STDMETHODCALLTYPE Notify(OBEX_EVENT Event, IUnknown * pUnk1, IUnknown * pUnk2)
{
ASSERT(fIsEnuming);
if ((IsWindow(_hWnd)) && (pUnk1))
{
//since PostMessage returns quickly (w/o processing event)
// AddRef it first
pUnk1->AddRef();
PostMessage(_hWnd, MSG_OBEX_EVENT, (WPARAM )Event, (LPARAM )pUnk1);
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv)
{
if ((riid == IID_IObexSink) || (riid == IID_IUnknown))
{
*ppv = (IConnectionPoint *) this;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE AddRef()
{
return InterlockedIncrement((LONG*)&_ulRefs);
}
ULONG STDMETHODCALLTYPE Release()
{
ULONG ulRefs;
InterlockedExchange((LONG *)&ulRefs, _ulRefs);
if (InterlockedDecrement((LONG*)&_ulRefs) == 0)
{
delete this;
return 0;
}
return ulRefs - 1;
}
private:
ULONG _ulRefs;
HWND _hWnd;
};
struct DeviceList
{
DeviceList *pNext;
IPropertyBag *pBag;
};
typedef struct CHOOSEDEVICE_PARAM
{
IObex *pObex;
IObexDevice **ppObexDevice;
ULONG ulListenMask;
} CHOOSEDEVICE_PARAM;
CRITICAL_SECTION csLock;
UINT ChooseService(HINSTANCE hInst, HWND hwndParent, IObex *pObex, IObexDevice **ppObexDevice, ULONG ulListenMask)
{
int ret;
*ppObexDevice = NULL;
CHOOSEDEVICE_PARAM cp;
cp.pObex = pObex;
cp.ppObexDevice = ppObexDevice;
cp.ulListenMask = ulListenMask;
InitializeCriticalSection(&csLock);
ret =
DialogBoxParam(hInst,
MAKEINTRESOURCE(IDD_CHOOSESERVICE),
hwndParent,
(DLGPROC)ChooseServiceProc,
(LPARAM)&cp);
DeleteCriticalSection(&csLock);
if(ret && ppObexDevice)
return ret;
else
return 1;
}
LRESULT CALLBACK ChooseServiceProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hwndList;
static IObexDevice **ppObexDevice;
static IObex *pObex = NULL;
static IConnectionPointContainer *pCont = NULL;
static IConnectionPoint *pConPt = NULL;
static DWORD dwCookie;
static DeviceList *pDeviceList = NULL;
static ULONG ulListenMask = 0;
switch(message)
{
case WM_INITDIALOG :
EnterCriticalSection(&csLock);
pDeviceList = NULL;
pObex = ((CHOOSEDEVICE_PARAM *)lParam)->pObex;
ulListenMask = ((CHOOSEDEVICE_PARAM *)lParam)->ulListenMask;
pObex->AddRef();
ppObexDevice = ((CHOOSEDEVICE_PARAM *)lParam)->ppObexDevice;
//release the device (if it exists)
if(*ppObexDevice)
(*ppObexDevice)->Release();
*ppObexDevice = 0;
hwndList = GetDlgItem(hwnd, IDC_LIST);
CObexSink *pSink;
pSink = new CObexSink(hwnd);
if (!pSink)
{
LeaveCriticalSection(&csLock);
break;
}
fIsEnuming = TRUE;
if ( (pObex) && (pSink) && (SUCCEEDED(pObex->QueryInterface(IID_IConnectionPointContainer, (LPVOID *)&pCont))) &&
(SUCCEEDED(pCont->FindConnectionPoint(IID_IObexSink, &pConPt))) && (pConPt) &&
(SUCCEEDED(pConPt->Advise((IUnknown *)pSink, &dwCookie))) )
{
pObex->StartDeviceEnum();
}
else
{
fIsEnuming = FALSE;
}
LeaveCriticalSection(&csLock);
break;
case WM_DESTROY:
EnterCriticalSection(&csLock);
//
// Disconnect ourselves as a sink
if (pConPt)
{
pConPt->Unadvise(dwCookie);
pConPt->Release();
}
if(fIsEnuming)
{
pObex->StopDeviceEnum();
fIsEnuming = FALSE;
}
//
// Delete all devices that are lingering
while(pDeviceList)
{
DeviceList *pDelMe = pDeviceList;
pDeviceList = pDeviceList->pNext;
pDelMe->pBag->Release();
delete pDelMe;
}
if (pCont)
pCont->Release();
if (pObex)
pObex->Release();
LeaveCriticalSection(&csLock);
break;
case MSG_OBEX_EVENT:
{
EnterCriticalSection(&csLock);
IPropertyBag *pDevice = NULL;
if (NULL != (pDevice = (IPropertyBag *)lParam))
{
VARIANT varAddress;
VARIANT varDeviceName;
VARIANT varTransport;
VARIANT varPort;
VARIANT varUUID;
BOOL fHaveAddress = FALSE;
BOOL fHaveDeviceName = FALSE;
BOOL fHaveTransport = FALSE;
BOOL fHavePort = FALSE;
BOOL fHaveUUID = FALSE;
VariantInit(&varDeviceName);
VariantInit(&varTransport);
VariantInit(&varAddress);
VariantInit(&varPort);
VariantInit(&varUUID);
if(SUCCEEDED(pDevice->Read(c_szDevicePropName, &varDeviceName, NULL)))
fHaveDeviceName = TRUE;
if(SUCCEEDED(pDevice->Read(c_szDevicePropTransport, &varTransport, NULL)))
fHaveTransport = TRUE;
if(SUCCEEDED(pDevice->Read(c_szDevicePropAddress, &varAddress, NULL)))
fHaveAddress = TRUE;
if(SUCCEEDED(pDevice->Read(c_szPort, &varPort, NULL)))
fHavePort = TRUE;
if(SUCCEEDED(pDevice->Read(c_szDeviceServiceUUID, &varUUID, NULL)))
fHaveUUID = TRUE;
//see how much we can read
if (wParam == OE_DEVICE_ARRIVAL)
{
CLSID clsidTrans;
if( fHaveDeviceName && (varDeviceName.vt == VT_BSTR) &&
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -