wxutil.h
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:15k
源码类别:

P2P编程

开发平台:

Visual C++

  1. //------------------------------------------------------------------------------
  2. // File: WXUtil.h
  3. //
  4. // Desc: DirectShow base classes - defines helper classes and functions for
  5. //       building multimedia filters.
  6. //
  7. // Copyright (c) Microsoft Corporation.  All rights reserved.
  8. //------------------------------------------------------------------------------
  9. #ifndef __WXUTIL__
  10. #define __WXUTIL__
  11. // eliminate spurious "statement has no effect" warnings.
  12. #pragma warning(disable: 4705)
  13. // wrapper for whatever critical section we have
  14. class CCritSec {
  15.     // make copy constructor and assignment operator inaccessible
  16.     CCritSec(const CCritSec &refCritSec);
  17.     CCritSec &operator=(const CCritSec &refCritSec);
  18.     CRITICAL_SECTION m_CritSec;
  19. #ifdef DEBUG
  20. public:
  21.     DWORD   m_currentOwner;
  22.     DWORD   m_lockCount;
  23.     BOOL    m_fTrace;        // Trace this one
  24. public:
  25.     CCritSec();
  26.     ~CCritSec();
  27.     void Lock();
  28.     void Unlock();
  29. #else
  30. public:
  31.     CCritSec() {
  32.         InitializeCriticalSection(&m_CritSec);
  33.     };
  34.     ~CCritSec() {
  35.         DeleteCriticalSection(&m_CritSec);
  36.     };
  37.     void Lock() {
  38.         EnterCriticalSection(&m_CritSec);
  39.     };
  40.     void Unlock() {
  41.         LeaveCriticalSection(&m_CritSec);
  42.     };
  43. #endif
  44. };
  45. //
  46. // To make deadlocks easier to track it is useful to insert in the
  47. // code an assertion that says whether we own a critical section or
  48. // not.  We make the routines that do the checking globals to avoid
  49. // having different numbers of member functions in the debug and
  50. // retail class implementations of CCritSec.  In addition we provide
  51. // a routine that allows usage of specific critical sections to be
  52. // traced.  This is NOT on by default - there are far too many.
  53. //
  54. #ifdef DEBUG
  55.     BOOL WINAPI CritCheckIn(CCritSec * pcCrit);
  56.     BOOL WINAPI CritCheckIn(const CCritSec * pcCrit);
  57.     BOOL WINAPI CritCheckOut(CCritSec * pcCrit);
  58.     BOOL WINAPI CritCheckOut(const CCritSec * pcCrit);
  59.     void WINAPI DbgLockTrace(CCritSec * pcCrit, BOOL fTrace);
  60. #else
  61.     #define CritCheckIn(x) TRUE
  62.     #define CritCheckOut(x) TRUE
  63.     #define DbgLockTrace(pc, fT)
  64. #endif
  65. // locks a critical section, and unlocks it automatically
  66. // when the lock goes out of scope
  67. class CAutoLock {
  68.     // make copy constructor and assignment operator inaccessible
  69.     CAutoLock(const CAutoLock &refAutoLock);
  70.     CAutoLock &operator=(const CAutoLock &refAutoLock);
  71. protected:
  72.     CCritSec * m_pLock;
  73. public:
  74.     CAutoLock(CCritSec * plock)
  75.     {
  76.         m_pLock = plock;
  77.         m_pLock->Lock();
  78.     };
  79.     ~CAutoLock() {
  80.         m_pLock->Unlock();
  81.     };
  82. };
  83. // wrapper for event objects
  84. class CAMEvent
  85. {
  86.     // make copy constructor and assignment operator inaccessible
  87.     CAMEvent(const CAMEvent &refEvent);
  88.     CAMEvent &operator=(const CAMEvent &refEvent);
  89. protected:
  90.     HANDLE m_hEvent;
  91. public:
  92.     CAMEvent(BOOL fManualReset = FALSE);
  93.     ~CAMEvent();
  94.     // Cast to HANDLE - we don't support this as an lvalue
  95.     operator HANDLE () const { return m_hEvent; };
  96.     void Set() {EXECUTE_ASSERT(SetEvent(m_hEvent));};
  97.     BOOL Wait(DWORD dwTimeout = INFINITE) {
  98. return (WaitForSingleObject(m_hEvent, dwTimeout) == WAIT_OBJECT_0);
  99.     };
  100.     void Reset() { ResetEvent(m_hEvent); };
  101.     BOOL Check() { return Wait(0); };
  102. };
  103. // wrapper for event objects that do message processing
  104. // This adds ONE method to the CAMEvent object to allow sent
  105. // messages to be processed while waiting
  106. class CAMMsgEvent : public CAMEvent
  107. {
  108. public:
  109.     // Allow SEND messages to be processed while waiting
  110.     BOOL WaitMsg(DWORD dwTimeout = INFINITE);
  111. };
  112. // old name supported for the time being
  113. #define CTimeoutEvent CAMEvent
  114. // support for a worker thread
  115. // simple thread class supports creation of worker thread, synchronization
  116. // and communication. Can be derived to simplify parameter passing
  117. class AM_NOVTABLE CAMThread {
  118.     // make copy constructor and assignment operator inaccessible
  119.     CAMThread(const CAMThread &refThread);
  120.     CAMThread &operator=(const CAMThread &refThread);
  121.     CAMEvent m_EventSend;
  122.     CAMEvent m_EventComplete;
  123.     DWORD m_dwParam;
  124.     DWORD m_dwReturnVal;
  125. protected:
  126.     HANDLE m_hThread;
  127.     // thread will run this function on startup
  128.     // must be supplied by derived class
  129.     virtual DWORD ThreadProc() = 0;
  130. public:
  131.     CAMThread();
  132.     virtual ~CAMThread();
  133.     CCritSec m_AccessLock; // locks access by client threads
  134.     CCritSec m_WorkerLock; // locks access to shared objects
  135.     // thread initially runs this. param is actually 'this'. function
  136.     // just gets this and calls ThreadProc
  137.     static DWORD WINAPI InitialThreadProc(LPVOID pv);
  138.     // start thread running  - error if already running
  139.     BOOL Create();
  140.     // signal the thread, and block for a response
  141.     //
  142.     DWORD CallWorker(DWORD);
  143.     // accessor thread calls this when done with thread (having told thread
  144.     // to exit)
  145.     void Close() {
  146.         #pragma warning( push )
  147.         // C4312: 'type cast' : conversion from 'LONG' to 'PVOID' of greater size
  148.         //
  149.         // This code works correctly on 32-bit and 64-bit systems.
  150.         #pragma warning( disable : 4312 )
  151.         HANDLE hThread = (HANDLE)InterlockedExchangePointer(&m_hThread, 0);
  152.         #pragma warning( pop )
  153.         if (hThread) {
  154.             WaitForSingleObject(hThread, INFINITE);
  155.             CloseHandle(hThread);
  156.         }
  157.     };
  158.     // ThreadExists
  159.     // Return TRUE if the thread exists. FALSE otherwise
  160.     BOOL ThreadExists(void) const
  161.     {
  162.         if (m_hThread == 0) {
  163.             return FALSE;
  164.         } else {
  165.             return TRUE;
  166.         }
  167.     }
  168.     // wait for the next request
  169.     DWORD GetRequest();
  170.     // is there a request?
  171.     BOOL CheckRequest(DWORD * pParam);
  172.     // reply to the request
  173.     void Reply(DWORD);
  174.     // If you want to do WaitForMultipleObjects you'll need to include
  175.     // this handle in your wait list or you won't be responsive
  176.     HANDLE GetRequestHandle() const { return m_EventSend; };
  177.     // Find out what the request was
  178.     DWORD GetRequestParam() const { return m_dwParam; };
  179.     // call CoInitializeEx (COINIT_DISABLE_OLE1DDE) if
  180.     // available. S_FALSE means it's not available.
  181.     static HRESULT CoInitializeHelper();
  182. };
  183. // CQueue
  184. //
  185. // Implements a simple Queue ADT.  The queue contains a finite number of
  186. // objects, access to which is controlled by a semaphore.  The semaphore
  187. // is created with an initial count (N).  Each time an object is added
  188. // a call to WaitForSingleObject is made on the semaphore's handle.  When
  189. // this function returns a slot has been reserved in the queue for the new
  190. // object.  If no slots are available the function blocks until one becomes
  191. // available.  Each time an object is removed from the queue ReleaseSemaphore
  192. // is called on the semaphore's handle, thus freeing a slot in the queue.
  193. // If no objects are present in the queue the function blocks until an
  194. // object has been added.
  195. #define DEFAULT_QUEUESIZE   2
  196. template <class T> class CQueue {
  197. private:
  198.     HANDLE          hSemPut;        // Semaphore controlling queue "putting"
  199.     HANDLE          hSemGet;        // Semaphore controlling queue "getting"
  200.     CRITICAL_SECTION CritSect;      // Thread seriallization
  201.     int             nMax;           // Max objects allowed in queue
  202.     int             iNextPut;       // Array index of next "PutMsg"
  203.     int             iNextGet;       // Array index of next "GetMsg"
  204.     T              *QueueObjects;   // Array of objects (ptr's to void)
  205.     void Initialize(int n) {
  206.         iNextPut = iNextGet = 0;
  207.         nMax = n;
  208.         InitializeCriticalSection(&CritSect);
  209.         hSemPut = CreateSemaphore(NULL, n, n, NULL);
  210.         hSemGet = CreateSemaphore(NULL, 0, n, NULL);
  211.         QueueObjects = new T[n];
  212.     }
  213. public:
  214.     CQueue(int n) {
  215.         Initialize(n);
  216.     }
  217.     CQueue() {
  218.         Initialize(DEFAULT_QUEUESIZE);
  219.     }
  220.     ~CQueue() {
  221.         delete [] QueueObjects;
  222.         DeleteCriticalSection(&CritSect);
  223.         CloseHandle(hSemPut);
  224.         CloseHandle(hSemGet);
  225.     }
  226.     T GetQueueObject() {
  227.         int iSlot;
  228.         T Object;
  229.         LONG lPrevious;
  230.         // Wait for someone to put something on our queue, returns straight
  231.         // away is there is already an object on the queue.
  232.         //
  233.         WaitForSingleObject(hSemGet, INFINITE);
  234.         EnterCriticalSection(&CritSect);
  235.         iSlot = iNextGet++ % nMax;
  236.         Object = QueueObjects[iSlot];
  237.         LeaveCriticalSection(&CritSect);
  238.         // Release anyone waiting to put an object onto our queue as there
  239.         // is now space available in the queue.
  240.         //
  241.         ReleaseSemaphore(hSemPut, 1L, &lPrevious);
  242.         return Object;
  243.     }
  244.     void PutQueueObject(T Object) {
  245.         int iSlot;
  246.         LONG lPrevious;
  247.         // Wait for someone to get something from our queue, returns straight
  248.         // away is there is already an empty slot on the queue.
  249.         //
  250.         WaitForSingleObject(hSemPut, INFINITE);
  251.         EnterCriticalSection(&CritSect);
  252.         iSlot = iNextPut++ % nMax;
  253.         QueueObjects[iSlot] = Object;
  254.         LeaveCriticalSection(&CritSect);
  255.         // Release anyone waiting to remove an object from our queue as there
  256.         // is now an object available to be removed.
  257.         //
  258.         ReleaseSemaphore(hSemGet, 1L, &lPrevious);
  259.     }
  260. };
  261. // miscellaneous string conversion functions
  262. // NOTE: as we need to use the same binaries on Win95 as on NT this code should
  263. // be compiled WITHOUT unicode being defined.  Otherwise we will not pick up
  264. // these internal routines and the binary will not run on Win95.
  265. // int WINAPIV wsprintfWInternal(LPWSTR, LPCWSTR, ...);
  266. //LPWSTR
  267. //WINAPI
  268. //lstrcpyWInternal(
  269. //    LPWSTR lpString1,
  270. //    LPCWSTR lpString2
  271. //    );
  272. LPWSTR
  273. WINAPI
  274. lstrcpynWInternal(
  275.     LPWSTR lpString1,
  276.     LPCWSTR lpString2,
  277.     int     iMaxLength
  278.     );
  279. int
  280. WINAPI
  281. lstrcmpWInternal(
  282.     LPCWSTR lpString1,
  283.     LPCWSTR lpString2
  284.     );
  285. int
  286. WINAPI
  287. lstrcmpiWInternal(
  288.     LPCWSTR lpString1,
  289.     LPCWSTR lpString2
  290.     );
  291. int
  292. WINAPI
  293. lstrlenWInternal(
  294.     LPCWSTR lpString
  295.     );
  296. #ifndef UNICODE
  297. #define wsprintfW wsprintfWInternal
  298. #define lstrcpyW lstrcpyWInternal
  299. #define lstrcpynW lstrcpynWInternal
  300. #define lstrcmpW lstrcmpWInternal
  301. #define lstrcmpiW lstrcmpiWInternal
  302. #define lstrlenW lstrlenWInternal
  303. #endif
  304. extern "C"
  305. void * __stdcall memmoveInternal(void *, const void *, size_t);
  306. inline void * __cdecl memchrInternal(const void *buf, int chr, size_t cnt)
  307. {
  308. #ifdef _X86_
  309.     void *pRet = NULL;
  310.     _asm {
  311.         cld                 // make sure we get the direction right
  312.         mov     ecx, cnt    // num of bytes to scan
  313.         mov     edi, buf    // pointer byte stream
  314.         mov     eax, chr    // byte to scan for
  315.         repne   scasb       // look for the byte in the byte stream
  316.         jnz     exit_memchr // Z flag set if byte found
  317.         dec     edi         // scasb always increments edi even when it
  318.                             // finds the required byte
  319.         mov     pRet, edi
  320. exit_memchr:
  321.     }
  322.     return pRet;
  323. #else
  324.     while ( cnt && (*(unsigned char *)buf != (unsigned char)chr) ) {
  325.         buf = (unsigned char *)buf + 1;
  326.         cnt--;
  327.     }
  328.     return(cnt ? (void *)buf : NULL);
  329. #endif
  330. }
  331. void WINAPI IntToWstr(int i, LPWSTR wstr, size_t len);
  332. #define WstrToInt(sz) _wtoi(sz)
  333. #define atoiW(sz) _wtoi(sz)
  334. #define atoiA(sz) atoi(sz)
  335. // These are available to help managing bitmap VIDEOINFOHEADER media structures
  336. extern const DWORD bits555[3];
  337. extern const DWORD bits565[3];
  338. extern const DWORD bits888[3];
  339. // These help convert between VIDEOINFOHEADER and BITMAPINFO structures
  340. STDAPI_(const GUID) GetTrueColorType(const BITMAPINFOHEADER *pbmiHeader);
  341. STDAPI_(const GUID) GetBitmapSubtype(const BITMAPINFOHEADER *pbmiHeader);
  342. STDAPI_(WORD) GetBitCount(const GUID *pSubtype);
  343. // strmbase.lib implements this for compatibility with people who
  344. // managed to link to this directly.  we don't want to advertise it.
  345. //
  346. // STDAPI_(/* T */ CHAR *) GetSubtypeName(const GUID *pSubtype);
  347. STDAPI_(CHAR *) GetSubtypeNameA(const GUID *pSubtype);
  348. STDAPI_(WCHAR *) GetSubtypeNameW(const GUID *pSubtype);
  349. #ifdef UNICODE
  350. #define GetSubtypeName GetSubtypeNameW
  351. #else
  352. #define GetSubtypeName GetSubtypeNameA
  353. #endif
  354. STDAPI_(LONG) GetBitmapFormatSize(const BITMAPINFOHEADER *pHeader);
  355. STDAPI_(DWORD) GetBitmapSize(const BITMAPINFOHEADER *pHeader);
  356. STDAPI_(BOOL) ContainsPalette(const VIDEOINFOHEADER *pVideoInfo);
  357. STDAPI_(const RGBQUAD *) GetBitmapPalette(const VIDEOINFOHEADER *pVideoInfo);
  358. // Compares two interfaces and returns TRUE if they are on the same object
  359. BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond);
  360. // This is for comparing pins
  361. #define EqualPins(pPin1, pPin2) IsEqualObject(pPin1, pPin2)
  362. // Arithmetic helper functions
  363. // Compute (a * b + rnd) / c
  364. LONGLONG WINAPI llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG rnd);
  365. LONGLONG WINAPI Int64x32Div32(LONGLONG a, LONG b, LONG c, LONG rnd);
  366. // Avoids us dyna-linking to SysAllocString to copy BSTR strings
  367. STDAPI WriteBSTR(BSTR * pstrDest, LPCWSTR szSrc);
  368. STDAPI FreeBSTR(BSTR* pstr);
  369. // Return a wide string - allocating memory for it
  370. // Returns:
  371. //    S_OK          - no error
  372. //    E_POINTER     - ppszReturn == NULL
  373. //    E_OUTOFMEMORY - can't allocate memory for returned string
  374. STDAPI AMGetWideString(LPCWSTR pszString, LPWSTR *ppszReturn);
  375. // Special wait for objects owning windows
  376. DWORD WINAPI WaitDispatchingMessages(
  377.     HANDLE hObject,
  378.     DWORD dwWait,
  379.     HWND hwnd = NULL,
  380.     UINT uMsg = 0,
  381.     HANDLE hEvent = NULL);
  382. // HRESULT_FROM_WIN32 converts ERROR_SUCCESS to a success code, but in
  383. // our use of HRESULT_FROM_WIN32, it typically means a function failed
  384. // to call SetLastError(), and we still want a failure code.
  385. //
  386. #define AmHresultFromWin32(x) (MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, x))
  387. // call GetLastError and return an HRESULT value that will fail the
  388. // SUCCEEDED() macro.
  389. HRESULT AmGetLastErrorToHResult(void);
  390. // duplicate of ATL's CComPtr to avoid linker conflicts.
  391. IUnknown* QzAtlComPtrAssign(IUnknown** pp, IUnknown* lp);
  392. template <class T>
  393. class QzCComPtr
  394. {
  395. public:
  396. typedef T _PtrClass;
  397. QzCComPtr() {p=NULL;}
  398. QzCComPtr(T* lp)
  399. {
  400. if ((p = lp) != NULL)
  401. p->AddRef();
  402. }
  403. QzCComPtr(const QzCComPtr<T>& lp)
  404. {
  405. if ((p = lp.p) != NULL)
  406. p->AddRef();
  407. }
  408. ~QzCComPtr() {if (p) p->Release();}
  409. void Release() {if (p) p->Release(); p=NULL;}
  410. operator T*() {return (T*)p;}
  411. T& operator*() {ASSERT(p!=NULL); return *p; }
  412. //The assert on operator& usually indicates a bug.  If this is really
  413. //what is needed, however, take the address of the p member explicitly.
  414. T** operator&() { ASSERT(p==NULL); return &p; }
  415. T* operator->() { ASSERT(p!=NULL); return p; }
  416. T* operator=(T* lp){return (T*)QzAtlComPtrAssign((IUnknown**)&p, lp);}
  417. T* operator=(const QzCComPtr<T>& lp)
  418. {
  419. return (T*)QzAtlComPtrAssign((IUnknown**)&p, lp.p);
  420. }
  421. #if _MSC_VER>1020
  422. bool operator!(){return (p == NULL);}
  423. #else
  424. BOOL operator!(){return (p == NULL) ? TRUE : FALSE;}
  425. #endif
  426. T* p;
  427. };
  428. MMRESULT CompatibleTimeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent );
  429. bool TimeKillSynchronousFlagAvailable( void );
  430. #endif /* __WXUTIL__ */