Source code of Windows XP (NT5)
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.

600 lines
18 KiB

  1. #ifndef _UTIL_H_
  2. #define _UTIL_H_
  3. int IsVK_TABCycler(MSG *pMsg);
  4. BOOL IsVK_CtlTABCycler(MSG *pMsg);
  5. #ifdef __cplusplus
  6. //=--------------------------------------------------------------------------=
  7. // allocates a temporary buffer that will disappear when it goes out of scope
  8. // NOTE: be careful of that -- make sure you use the string in the same or
  9. // nested scope in which you created this buffer. people should not use this
  10. // class directly. use the macro(s) below.
  11. //
  12. class TempBuffer {
  13. #ifdef DEBUG
  14. const DWORD* _pdwSigniture;
  15. const static DWORD s_dummy;
  16. #endif
  17. public:
  18. TempBuffer(ULONG cBytes) {
  19. #ifdef DEBUG
  20. _pdwSigniture = &s_dummy;
  21. #endif
  22. m_pBuf = (cBytes <= 120) ? &m_szTmpBuf : LocalAlloc(LMEM_FIXED, cBytes);
  23. m_fHeapAlloc = (cBytes > 120);
  24. }
  25. ~TempBuffer() {
  26. if (m_pBuf && m_fHeapAlloc) LocalFree(m_pBuf);
  27. }
  28. void *GetBuffer() {
  29. return m_pBuf;
  30. }
  31. private:
  32. void *m_pBuf;
  33. // we'll use this temp buffer for small cases.
  34. //
  35. char m_szTmpBuf[120];
  36. unsigned m_fHeapAlloc:1;
  37. };
  38. #endif // __cplusplus
  39. #ifdef __cplusplus
  40. extern "C" {
  41. #endif
  42. //=--------------------------------------------------------------------------=
  43. // string helpers.
  44. //
  45. // given and ANSI String, copy it into a wide buffer.
  46. // be careful about scoping when using this macro!
  47. //
  48. // how to use the below two macros:
  49. //
  50. // ...
  51. // LPSTR pszA;
  52. // pszA = MyGetAnsiStringRoutine();
  53. // MAKE_WIDEPTR_FROMANSI(pwsz, pszA);
  54. // MyUseWideStringRoutine(pwsz);
  55. // ...
  56. //
  57. // similarily for MAKE_ANSIPTR_FROMWIDE. note that the first param does not
  58. // have to be declared, and no clean up must be done.
  59. //
  60. #define MAKE_WIDEPTR_FROMANSI(ptrname, ansistr) \
  61. long __l##ptrname = (lstrlen(ansistr) + 1) * sizeof(WCHAR); \
  62. TempBuffer __TempBuffer##ptrname(__l##ptrname); \
  63. MultiByteToWideChar(CP_ACP, 0, ansistr, -1, (LPWSTR)__TempBuffer##ptrname.GetBuffer(), __l##ptrname); \
  64. LPWSTR ptrname = (LPWSTR)__TempBuffer##ptrname.GetBuffer()
  65. #define MAKE_ANSIPTR_FROMWIDE(ptrname, widestr) \
  66. long __l##ptrname = (lstrlenW(widestr) + 1) * 2 * sizeof(char); \
  67. TempBuffer __TempBuffer##ptrname(__l##ptrname); \
  68. WideCharToMultiByte(CP_ACP, 0, widestr, -1, (LPSTR)__TempBuffer##ptrname.GetBuffer(), __l##ptrname, NULL, NULL); \
  69. LPSTR ptrname = (LPSTR)__TempBuffer##ptrname.GetBuffer()
  70. BOOL __cdecl _FormatMessage(LPCWSTR szTemplate, LPWSTR szBuf, UINT cchBuf, ...);
  71. HRESULT IUnknown_FileSysChange(IUnknown* punk, DWORD dwEvent, LPCITEMIDLIST* ppidl);
  72. HRESULT QueryService_SID_IBandProxy(IUnknown * punkParent, REFIID riid, IBandProxy ** ppbp, void **ppvObj);
  73. HRESULT CreateIBandProxyAndSetSite(IUnknown * punkParent, REFIID riid, IBandProxy ** ppbp, void **ppvObj);
  74. DWORD GetPreferedDropEffect(IDataObject *pdtobj);
  75. HRESULT _SetPreferedDropEffect(IDataObject *pdtobj, DWORD dwEffect);
  76. #ifdef DEBUG
  77. int SearchDWP(DWORD_PTR *pdwBuf, int cbBuf, DWORD_PTR dwVal);
  78. #endif
  79. #define REGVALUE_STREAMSA "Streams"
  80. #define REGVALUE_STREAMS TEXT(REGVALUE_STREAMSA)
  81. #define SZ_REGKEY_TYPEDCMDMRU TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU")
  82. #define SZ_REGKEY_TYPEDURLMRU TEXT("Software\\Microsoft\\Internet Explorer\\TypedURLs")
  83. #define SZ_REGVAL_MRUENTRY TEXT("url%lu")
  84. #define SZ_REGKEY_INETCPL_POLICIES TEXT("Software\\Policies\\Microsoft\\Internet Explorer\\Control Panel")
  85. #define SZ_REGVALUE_RESETWEBSETTINGS TEXT("ResetWebSettings")
  86. #define SZ_REGKEY_IE_POLICIES TEXT("Software\\Policies\\Microsoft\\Internet Explorer\\Main")
  87. #define SZ_REGVALUE_IEREPAIR TEXT("Repair IE Option")
  88. #define SZ_REGKEY_ACTIVE_SETUP TEXT("Software\\Microsoft\\Active Setup")
  89. #define SZ_REGVALUE_DISABLE_REPAIR TEXT("DisableRepair")
  90. #if 0
  91. BOOL IsIERepairOn();
  92. #endif
  93. BOOL IsResetWebSettingsEnabled(void);
  94. HRESULT GetMRUEntry(HKEY hKey, DWORD dwMRUIndex, LPTSTR pszMRUEntry, DWORD cchMRUEntry, LPITEMIDLIST * ppidl);
  95. extern UINT g_cfURL;
  96. extern UINT g_cfHIDA;
  97. extern UINT g_cfFileDescA;
  98. extern UINT g_cfFileDescW;
  99. extern UINT g_cfFileContents;
  100. extern const CLSID g_clsidNull; // for those that want a NULL clsid.
  101. void InitClipboardFormats();
  102. // raymondc's futile attempt to reduce confusion
  103. //
  104. // EICH_KBLAH = a registry key named blah
  105. // EICH_SBLAH = a win.ini section named blah
  106. #define EICH_UNKNOWN 0xFFFFFFFF
  107. #define EICH_KINET 0x00000002
  108. #define EICH_KINETMAIN 0x00000004
  109. #define EICH_KWIN 0x00000008
  110. #define EICH_KWINPOLICY 0x00000010
  111. #define EICH_KWINEXPLORER 0x00000020
  112. #define EICH_SSAVETASKBAR 0x00000040
  113. #define EICH_SWINDOWMETRICS 0x00000080
  114. #define EICH_SPOLICY 0x00000100
  115. #define EICH_SSHELLMENU 0x00000200
  116. #define EICH_KWINEXPLSMICO 0x00000400
  117. #define EICH_SWINDOWS 0x00000800
  118. DWORD SHIsExplorerIniChange(WPARAM wParam, LPARAM lParam);
  119. #define GEN_DEBUGSTRW(str) ((str) ? (str) : L"<Null Str>")
  120. #define GEN_DEBUGSTRA(str) ((str) ? (str) : "<Null Str>")
  121. #ifdef UNICODE
  122. #define GEN_DEBUGSTR GEN_DEBUGSTRW
  123. #else // UNICODE
  124. #define GEN_DEBUGSTR GEN_DEBUGSTRA
  125. #endif // UNICODE
  126. void _InitAppGlobals();
  127. BOOL _InitComCtl32();
  128. void* DataObj_GetDataOfType(IDataObject* pdtobj, UINT cfType, STGMEDIUM *pstg);
  129. HRESULT RootCreateFromPath(LPCTSTR pszPath, LPITEMIDLIST * ppidl);
  130. extern DEFFOLDERSETTINGS g_dfs;
  131. STDAPI_(void) SaveDefaultFolderSettings(UINT flags);
  132. STDAPI_(void) GetCabState(CABINETSTATE *pcs);
  133. //-------------------------------------------------------------------------
  134. //*** Reg_GetStrs -- read registry strings into struct fields
  135. struct regstrs
  136. {
  137. LPTSTR name; // registry name
  138. int off; // struct offset
  139. };
  140. BOOL ViewIDFromViewMode(UINT uViewMode, SHELLVIEWID *pvid);
  141. void Reg_GetStrs(HKEY hkey, const struct regstrs *tab, TCHAR *szBuf, int cchBuf, void *pv);
  142. HRESULT DropOnMailRecipient(IDataObject *pdtobj, DWORD grfKeyState);
  143. HRESULT SendDocToMailRecipient(LPCITEMIDLIST pidl, UINT uiCodePage, DWORD grfKeyState, IUnknown *pUnkSite);
  144. #ifdef DEBUG
  145. void Dbg_DumpMenu(LPCTSTR psz, HMENU hmenu);
  146. #else
  147. #define Dbg_DumpMenu(psz, hmenu)
  148. #endif
  149. extern const LARGE_INTEGER c_li0;
  150. extern BOOL g_fNewNotify;
  151. // FEATURE: Need to handle two different implementations of SHChangeRegister...
  152. typedef ULONG (* PFNSHCHANGENOTIFYREGISTER)(HWND hwnd, int fSources, LONG fEvents, UINT wMsg, int cEntries, SHChangeNotifyEntry *pshcne);
  153. typedef BOOL (* PFNSHCHANGENOTIFYDEREGISTER)(unsigned long ulID);
  154. ULONG RegisterNotify(HWND hwnd, UINT nMsg, LPCITEMIDLIST pidl, DWORD dwEvents, UINT uFlags, BOOL fRecursive);
  155. int PropBag_ReadInt4(IPropertyBag* pPropBag, LPWSTR pszKey, int iDefault);
  156. HINSTANCE HinstShdocvw();
  157. HINSTANCE HinstShell32();
  158. extern const VARIANT c_vaEmpty;
  159. #define PVAREMPTY ((VARIANT*)&c_vaEmpty)
  160. BOOL ILIsBrowsable(LPCITEMIDLIST pidl, BOOL *pfISFolder);
  161. STDAPI_(LPITEMIDLIST) IEILCreate(UINT cbSize);
  162. BOOL GetInfoTipEx(IShellFolder* psf, DWORD dwFlags, LPCITEMIDLIST pidl, LPTSTR pszText, int cchTextMax);
  163. BOOL IsBrowsableShellExt(LPCITEMIDLIST pidl);
  164. void OpenFolderPidl(LPCITEMIDLIST pidl);
  165. void OpenFolderPath(LPCTSTR pszPath);
  166. int WINAPI _SHHandleUpdateImage( LPCITEMIDLIST pidlExtra );
  167. extern BOOL g_fICWCheckComplete;
  168. BOOL CheckSoftwareUpdateUI( HWND hwndOwner, IShellBrowser *pisb );
  169. BOOL CheckRunICW(LPCTSTR);
  170. #ifdef DEBUG
  171. LPTSTR Dbg_PidlStr(LPCITEMIDLIST pidl, LPTSTR pszBuffer, DWORD cchBufferSize);
  172. #else // DEBUG
  173. #define Dbg_PidlStr(pidl, pszBuffer, cchBufferSize) ((LPTSTR)NULL)
  174. #endif // DEBUG
  175. HRESULT SavePidlAsLink(IUnknown* punkSite, IStream *pstm, LPCITEMIDLIST pidl);
  176. HRESULT LoadPidlAsLink(IUnknown* punkSite, IStream *pstm, LPITEMIDLIST *ppidl);
  177. #define ADJUST_TO_WCHAR_POS 0
  178. #define ADJUST_TO_TCHAR_POS 1
  179. int AdjustECPosition(char *psz, int iPos, int iType);
  180. BOOL ExecItemFromFolder(HWND hwnd, LPCSTR pszVerb, IShellFolder* psf, LPCITEMIDLIST pidlItem);
  181. // See if a give URL is actually present as an installed entry
  182. STDAPI_(BOOL) CallCoInternetQueryInfo(LPCTSTR pszURL, QUERYOPTION QueryOption);
  183. #define UrlIsInstalledEntry(pszURL) CallCoInternetQueryInfo(pszURL, QUERY_IS_INSTALLEDENTRY)
  184. BOOL IsSubscribableA(LPCSTR pszUrl);
  185. BOOL IsSubscribableW(LPCWSTR pwzUrl);
  186. HRESULT IURLQualifyW(IN LPCWSTR pcwzURL, DWORD dwFlags, OUT LPWSTR pwzTranslatedURL, LPBOOL pbWasSearchURL, LPBOOL pbWasCorrected);
  187. #ifdef UNICODE
  188. #define IsSubscribable IsSubscribableW
  189. #define IURLQualifyT IURLQualifyW
  190. #else // UNICODE
  191. #define IsSubscribable IsSubscribableA
  192. #define IURLQualifyT IURLQualifyA
  193. #endif // UNICODE
  194. #define IURLQualifyA IURLQualify
  195. HDPA GetSortedIDList(LPITEMIDLIST pidl);
  196. void FreeSortedIDList(HDPA hdpa);
  197. //#define StopWatch StopWatchT
  198. int GetColorComponent(LPSTR *ppsz);
  199. COLORREF RegGetColorRefString( HKEY hkey, LPTSTR RegValue, COLORREF Value);
  200. LRESULT SetHyperlinkCursor(IShellFolder* pShellFolder, LPCITEMIDLIST pidl);
  201. HRESULT StrCmpIWithRoot(LPCTSTR szDispNameIn, BOOL fTotalStrCmp, LPTSTR * ppszCachedRoot);
  202. STDAPI UpdateSubscriptions();
  203. enum TRI_STATE
  204. {
  205. TRI_UNKNOWN = 2,
  206. TRI_TRUE = TRUE,
  207. TRI_FALSE = FALSE
  208. };
  209. LONG OpenRegUSKey(LPCTSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult);
  210. HWND GetTrayWindow();
  211. #define STREAMSIZE_UNKNOWN 0xFFFFFFFF
  212. HRESULT SaveStreamHeader(IStream *pstm, DWORD dwSignature, DWORD dwVersion, DWORD dwSize);
  213. HRESULT LoadStreamHeader(IStream *pstm, DWORD dwSignature, DWORD dwStartVersion, DWORD dwEndVersion, DWORD * pdwSize, DWORD * pdwVersionOut);
  214. // _FrameTrack flags
  215. #define TRACKHOT 0x0001
  216. #define TRACKEXPAND 0x0002
  217. #define TRACKNOCHILD 0x0004
  218. void FrameTrack(HDC hdc, LPRECT prc, UINT uFlags);
  219. #ifdef __cplusplus
  220. //+-------------------------------------------------------------------------
  221. // This function scans the document for the given HTML tag and returns the
  222. // result in a collection.
  223. //--------------------------------------------------------------------------
  224. interface IHTMLDocument2;
  225. interface IHTMLElementCollection;
  226. HRESULT GetDocumentTags(IHTMLDocument2* pHTMLDocument, LPOLESTR pszTagName, IHTMLElementCollection** ppTagsCollection);
  227. // CMenuList: a small class that tracks whether a given hmenu belongs
  228. // to the frame or the object, so the messages can be
  229. // dispatched correctly.
  230. class CMenuList
  231. {
  232. public:
  233. CMenuList(void);
  234. ~CMenuList(void);
  235. void Set(HMENU hmenuShared, HMENU hmenuFrame);
  236. void AddMenu(HMENU hmenu);
  237. void RemoveMenu(HMENU hmenu);
  238. BOOL IsObjectMenu(HMENU hmenu);
  239. #ifdef DEBUG
  240. void Dump(LPCTSTR pszMsg);
  241. #endif
  242. private:
  243. HDSA _hdsa;
  244. };
  245. };
  246. #endif
  247. #ifdef __cplusplus
  248. class CAssociationList
  249. {
  250. public:
  251. //
  252. // WARNING: We don't want a destructor on this because then it can't
  253. // be a global object without bringing in the CRT main. So
  254. // we can't free the DSA in a destructor. The DSA memory will be
  255. // freed by the OS when the process detaches. If this
  256. // class is ever dynamically allocated (ie not a static) then
  257. // we will need to free the DSA.
  258. //
  259. // ~CAssociationList();
  260. BOOL Add(DWORD dwKey, LPVOID lpData);
  261. void Delete(DWORD dwKey);
  262. HRESULT Find(DWORD dwKey, LPVOID* ppData);
  263. protected:
  264. int FindEntry(DWORD dwKey);
  265. struct ASSOCDATA
  266. {
  267. DWORD dwKey;
  268. LPVOID lpData;
  269. };
  270. HDSA _hdsa;
  271. };
  272. #endif
  273. STDAPI_(void) DrawMenuItem(DRAWITEMSTRUCT* pdi, LPCTSTR lpszMenuText, UINT iIcon);
  274. STDAPI_(LRESULT) MeasureMenuItem(MEASUREITEMSTRUCT *lpmi, LPCTSTR lpszMenuText);
  275. void FireEventSz(LPCTSTR szEvent);
  276. #ifndef UNICODE
  277. void FireEventSzW(LPCWSTR szEvent);
  278. #else
  279. #define FireEventSzW FireEventSz
  280. #endif
  281. // comctl32.dll doesn't really implement Str_SetPtrW.
  282. STDAPI_(BOOL) Str_SetPtrPrivateW(WCHAR * UNALIGNED * ppwzCurrent, LPCWSTR pwzNew);
  283. // This function is similar to Str_SetPtrPrivateW but it is compatible with API's
  284. // that use LocalAlloc for string memory
  285. STDAPI_(BOOL) SetStr(WCHAR * UNALIGNED * ppwzCurrent, LPCWSTR pwzNew);
  286. // Review chrisny: this can be moved into an object easily to handle generic droptarget, dropcursor
  287. // , autoscrool, etc. . .
  288. STDAPI_(void) _DragEnter(HWND hwndTarget, const POINTL ptStart, IDataObject *pdtObject);
  289. STDAPI_(void) _DragMove(HWND hwndTarget, const POINTL ptStart);
  290. #define Str_SetPtrW Str_SetPtrPrivateW
  291. STDAPI_(BOOL) _MenuCharMatch(LPCTSTR lpsz, TCHAR ch, BOOL fIgnoreAmpersand);
  292. STDAPI GetNavigateTarget(IShellFolder *psf, LPCITEMIDLIST pidl, LPITEMIDLIST *ppidl, DWORD *pdwAttribs);
  293. STDAPI_(BOOL) DoDragDropWithInternetShortcut(IOleCommandTarget *pcmdt, LPITEMIDLIST pidl, HWND hwnd);
  294. STDAPI_(BSTR) SysAllocStringA(LPCSTR);
  295. #ifdef UNICODE
  296. #define SysAllocStringT(psz) SysAllocString(psz)
  297. #else
  298. #define SysAllocStringT(psz) SysAllocStringA(psz)
  299. #endif
  300. void EnableOKButton(HWND hDlg, int id, LPTSTR pszText);
  301. BOOL IsExplorerWindow(HWND hwnd);
  302. BOOL IsFolderWindow(HWND hwnd);
  303. STDAPI_(BOOL) WasOpenedAsBrowser(IUnknown *punkSite);
  304. STDAPI_(HWND) GetTopLevelAncestor(HWND hWnd);
  305. STDAPI SHNavigateToFavorite(IShellFolder* psf, LPCITEMIDLIST pidl, IUnknown* punkSite, DWORD dwFlags);
  306. STDAPI SHGetTopBrowserWindow(IUnknown* punk, HWND* phwnd);
  307. STDAPI_(void) UpdateButtonArray(TBBUTTON *ptbDst, const TBBUTTON *ptbSrc, int ctb, LONG_PTR lStrOffset);
  308. STDAPI_(BOOL) DoesAppWantUrl(LPCTSTR pszCmdLine);
  309. STDAPI SHCreateThreadRef(LONG *pcRef, IUnknown **ppunk);
  310. BOOL ILIsFolder(LPCITEMIDLIST pidl);
  311. HRESULT URLToCacheFile(LPCWSTR pszUrl, LPWSTR pszFile, int cchFile);
  312. #ifdef DEBUG
  313. void DebugDumpPidl(DWORD dwDumpFlag, LPTSTR pszOutputString, LPCITEMIDLIST pidl);
  314. #else
  315. #define DebugDumpPidl(p, q, w)
  316. #endif
  317. STDAPI_(LPITEMIDLIST) SafeILClone(LPCITEMIDLIST pidl);
  318. #define ILClone SafeILClone
  319. WPARAM AnsiWparamToUnicode(WPARAM wParam);
  320. HMONITOR GetPrimaryMonitor();
  321. BOOL GetMonitorRects(HMONITOR hMon, LPRECT prc, BOOL bWork);
  322. #define GetMonitorRect(hMon, prc) \
  323. GetMonitorRects((hMon), (prc), FALSE)
  324. #define GetMonitorWorkArea(hMon, prc) \
  325. GetMonitorRects((hMon), (prc), TRUE)
  326. #define IsMonitorValid(hMon) \
  327. GetMonitorRects((hMon), NULL, TRUE)
  328. #define GetNumberOfMonitors() \
  329. GetSystemMetrics(SM_CMONITORS)
  330. void SHOutlineRect(HDC hdc, const RECT* prc, COLORREF cr);
  331. //------------------------------------------------------------------------
  332. typedef struct tagBMPCACHE
  333. {
  334. HBITMAP hbmp;
  335. COLORREF cr3D;
  336. } BMPCACHE;
  337. //------------------------------------------------------------------------
  338. // determine background settings and source for toolbar,
  339. // load bitmap (file/resource) and update cache
  340. HBITMAP LoadToolbarBackBmp(LPTSTR * ppszBitmap, BMPCACHE * pbmpCache, BOOL fInternet);
  341. UINT MapClsidToID(REFCLSID rclsid);
  342. VOID StripDecorations(PTSTR psz, BOOL fStripAmp);
  343. LPCTSTR UnescapeDoubleAmpersand(LPTSTR pszTitle);
  344. // Create mask from given bitmap, use color at pixel (x/y) as transparent color
  345. HBITMAP CreateMaskBitmap(HDC hdc, int x, int y, HBITMAP hbmpImage);
  346. // draw bitmap transparently; on Win2K and up, one could use MaskBlt()
  347. BOOL DrawTransparentBitmap(HDC hdc, int x, int y, HBITMAP hbmpImage, HBITMAP hbmpMask);
  348. BOOL DrawTransparentBitmapPart(HDC hdc, int x, int y, int dx, int dy, HBITMAP hbmpImage, HBITMAP hbmpMask);
  349. BOOL DrawAlphaBitmap(HDC hdc, int x, int y, int dx, int dy, HBITMAP hbmpImage);
  350. STDAPI_(IDeskBand *) FindBandByClsidBS(IBandSite *pbs, REFCLSID clsid);
  351. HIMAGELIST CreateImageList(HINSTANCE hi, LPCTSTR lpbmp, int cx, int cGrow, COLORREF crMask,
  352. UINT uType, UINT uFlags, BOOL bUseNewMirroringSupport);
  353. #ifdef __cplusplus
  354. //------------------------------------------------------------------------
  355. // ref count base class for non-COM classes
  356. class CRefCount
  357. {
  358. public:
  359. CRefCount() : _cRef(0) {};
  360. ULONG AddRef(void)
  361. {
  362. return InterlockedIncrement(&_cRef);
  363. }
  364. ULONG Release(void)
  365. {
  366. ASSERT(_cRef > 0);
  367. long cRef = InterlockedDecrement(&_cRef);
  368. if (cRef > 0)
  369. return cRef;
  370. delete this;
  371. return 0;
  372. }
  373. protected:
  374. virtual ~CRefCount() {};
  375. long _cRef;
  376. };
  377. //------------------------------------------------------------------------
  378. // smart pointer for non-COM classes
  379. template <class T>
  380. class _NoAddRefReleaseOnCRefPtr : public T
  381. {
  382. private:
  383. STDMETHOD_(ULONG, AddRef)()=0;
  384. STDMETHOD_(ULONG, Release)()=0;
  385. };
  386. //------------------------------------------------------------------------
  387. template<class T>
  388. class CRefPtr
  389. {
  390. public:
  391. CRefPtr()
  392. {
  393. _p = NULL;
  394. }
  395. CRefPtr(T* p)
  396. {
  397. _p = p;
  398. if (_p != NULL)
  399. _p->AddRef();
  400. }
  401. CRefPtr(const CRefPtr<T>& p)
  402. {
  403. _p = p;
  404. if (_p != NULL)
  405. _p->AddRef();
  406. }
  407. ~CRefPtr()
  408. {
  409. if (_p)
  410. _p->Release();
  411. }
  412. void Release()
  413. {
  414. T* pTemp = _p;
  415. if (pTemp)
  416. {
  417. _p = NULL;
  418. pTemp->Release();
  419. }
  420. }
  421. operator T*() const
  422. {
  423. return (T*)_p;
  424. }
  425. T& operator*() const
  426. {
  427. ASSERT(_p != NULL);
  428. return *_p;
  429. }
  430. //The assert on operator& usually indicates a bug. If this is really
  431. //what is needed, however, take the address of the p member explicitly.
  432. T** operator&()
  433. {
  434. ASSERT(_p == NULL);
  435. return &_p;
  436. }
  437. _NoAddRefReleaseOnCRefPtr<T>* operator->() const
  438. {
  439. ASSERT(_p != NULL);
  440. return (_NoAddRefReleaseOnCRefPtr<T>*)_p;
  441. }
  442. T* operator=(T* p)
  443. {
  444. if (p != NULL)
  445. p->AddRef();
  446. if (_p)
  447. (_p)->Release();
  448. _p = p;
  449. return p;
  450. }
  451. T* operator=(const CRefPtr<T>& p)
  452. {
  453. if (p != NULL)
  454. p->AddRef();
  455. if (_p)
  456. (_p)->Release();
  457. _p = p;
  458. return p;
  459. }
  460. bool operator!() const
  461. {
  462. return (_p == NULL);
  463. }
  464. bool operator<(T* pT) const
  465. {
  466. return _p < pT;
  467. }
  468. bool operator==(T* pT) const
  469. {
  470. return _p == pT;
  471. }
  472. T* Detach()
  473. {
  474. T* pt = _p;
  475. _p = NULL; // no release here, hand out live ptr!
  476. return pt;
  477. }
  478. private:
  479. T *_p;
  480. };
  481. #endif // __cplusplus
  482. #endif // _UTIL_H_