propsext.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 12k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. //--------------------------------------------------------------------------------
  2. //
  3. //  File:   propsext.cpp
  4. //
  5. //  General handling of OLE Entry points, CClassFactory and CPropSheetExt
  6. //
  7. //  Common Code for all display property sheet extension
  8. //
  9. //  Copyright (c) Microsoft Corp.  1992-1998 All Rights Reserved
  10. //
  11. //--------------------------------------------------------------------------------
  12. //---------------------------------------------------------------------------
  13. // Globals
  14. //---------------------------------------------------------------------------
  15. //
  16. // Count number of objects and number of locks.
  17. //
  18. HINSTANCE    g_hInst = NULL;
  19. BOOL         g_RunningOnNT = FALSE;
  20. LPDATAOBJECT g_lpdoTarget = NULL;
  21. ULONG        g_cObj = 0;
  22. ULONG        g_cLock = 0;
  23. //---------------------------------------------------------------------------
  24. // DllMain()
  25. //---------------------------------------------------------------------------
  26. int APIENTRY DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID )
  27. {
  28.     if( dwReason == DLL_PROCESS_ATTACH )        // Initializing
  29.     {
  30.         if ((int)GetVersion() >= 0)
  31.         {
  32.             g_RunningOnNT = TRUE;
  33.         }
  34.         g_hInst = hInstance;
  35.         DisableThreadLibraryCalls(hInstance);
  36.     }
  37.     return 1;
  38. }
  39. //---------------------------------------------------------------------------
  40. //      DllGetClassObject()
  41. //
  42. //      If someone calls with our CLSID, create an IClassFactory and pass it to
  43. //      them, so they can create and use one of our CPropSheetExt objects.
  44. //
  45. //---------------------------------------------------------------------------
  46. STDAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, LPVOID* ppvOut )
  47. {
  48.     *ppvOut = NULL; // Assume Failure
  49.     if( IsEqualCLSID( rclsid, g_CLSID_CplExt ) )
  50.     {
  51.         //
  52.         //Check that we can provide the interface
  53.         //
  54.         if( IsEqualIID( riid, IID_IUnknown) ||
  55.             IsEqualIID( riid, IID_IClassFactory )
  56.            )
  57.         {
  58.             //Return our IClassFactory for CPropSheetExt objects
  59.             *ppvOut = (LPVOID* )new CClassFactory();
  60.             if( NULL != *ppvOut )
  61.             {
  62.                 //AddRef the object through any interface we return
  63.                 ((CClassFactory*)*ppvOut)->AddRef();
  64.                 return NOERROR;
  65.             }
  66.             return E_OUTOFMEMORY;
  67.         }
  68.         return E_NOINTERFACE;
  69.     }
  70.     else
  71.     {
  72.         return CLASS_E_CLASSNOTAVAILABLE;
  73.     }
  74. }
  75. //---------------------------------------------------------------------------
  76. //      DllCanUnloadNow()
  77. //
  78. //      If we are not locked, and no objects are active, then we can exit.
  79. //
  80. //---------------------------------------------------------------------------
  81. STDAPI DllCanUnloadNow()
  82. {
  83.     SCODE   sc;
  84.     //
  85.     //Our answer is whether there are any object or locks
  86.     //
  87.     sc = (0L == g_cObj && 0 == g_cLock) ? S_OK : S_FALSE;
  88.     return ResultFromScode(sc);
  89. }
  90. //---------------------------------------------------------------------------
  91. //      ObjectDestroyed()
  92. //
  93. //      Function for the CPropSheetExt object to call when it is destroyed.
  94. //      Because we're in a DLL, we only track the number of objects here,
  95. //      letting DllCanUnloadNow take care of the rest.
  96. //---------------------------------------------------------------------------
  97. void FAR PASCAL ObjectDestroyed( void )
  98. {
  99.     g_cObj--;
  100.     return;
  101. }
  102. UINT CALLBACK
  103. PropertySheeCallback(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
  104. {
  105.     switch (uMsg) {
  106.     case PSPCB_CREATE:
  107.         return TRUE;    // return TRUE to continue with creation of page
  108.     case PSPCB_RELEASE:
  109.         if (g_lpdoTarget) {
  110.             g_lpdoTarget->Release();
  111.             g_lpdoTarget = NULL;
  112.         }
  113.         return 0;       // return value ignored
  114.     default:
  115.         break;
  116.     }
  117.     return TRUE;
  118. }
  119. //***************************************************************************
  120. //
  121. //  CClassFactory Class
  122. //
  123. //***************************************************************************
  124. //---------------------------------------------------------------------------
  125. //      Constructor
  126. //---------------------------------------------------------------------------
  127. CClassFactory::CClassFactory()
  128. {
  129.     m_cRef = 0L;
  130.     return;
  131. }
  132. //---------------------------------------------------------------------------
  133. //      Destructor
  134. //---------------------------------------------------------------------------
  135. CClassFactory::~CClassFactory( void )
  136. {
  137.     return;
  138. }
  139. //---------------------------------------------------------------------------
  140. //      QueryInterface()
  141. //---------------------------------------------------------------------------
  142. STDMETHODIMP CClassFactory::QueryInterface( REFIID riid, LPVOID* ppv )
  143. {
  144.     *ppv = NULL;
  145.     //Any interface on this object is the object pointer.
  146.     if( IsEqualIID( riid, IID_IUnknown ) ||
  147.         IsEqualIID( riid, IID_IClassFactory )
  148.        )
  149.     {
  150.         *ppv = (LPVOID)this;
  151.         ++m_cRef;
  152.         return NOERROR;
  153.     }
  154.     return E_NOINTERFACE;
  155. }
  156. //---------------------------------------------------------------------------
  157. //      AddRef()
  158. //---------------------------------------------------------------------------
  159. STDMETHODIMP_(ULONG) CClassFactory::AddRef()
  160. {
  161.     return ++m_cRef;
  162. }
  163. //---------------------------------------------------------------------------
  164. //      Release()
  165. //---------------------------------------------------------------------------
  166. STDMETHODIMP_(ULONG) CClassFactory::Release()
  167. {
  168.     ULONG cRefT;
  169.     cRefT = --m_cRef;
  170.     if( 0L == m_cRef ) 
  171.         delete this;
  172.     return cRefT;
  173. }
  174. //---------------------------------------------------------------------------
  175. //      CreateInstance()
  176. //---------------------------------------------------------------------------
  177. STDMETHODIMP
  178. CClassFactory::CreateInstance( LPUNKNOWN pUnkOuter,
  179.                                REFIID riid,
  180.                                LPVOID FAR *ppvObj
  181.                               )
  182. {
  183.     CPropSheetExt*  pObj;
  184.     HRESULT         hr = E_OUTOFMEMORY;
  185.     *ppvObj = NULL;
  186.     // We don't support aggregation at all.
  187.     if( pUnkOuter )
  188.     {
  189.         return CLASS_E_NOAGGREGATION;
  190.     }
  191.     //Verify that a controlling unknown asks for IShellPropSheetExt
  192.     if( IsEqualIID( riid, IID_IShellPropSheetExt ) )
  193.     {
  194.         //Create the object, passing function to notify on destruction
  195.         pObj = new CPropSheetExt( pUnkOuter, ObjectDestroyed );
  196.         if( NULL == pObj )
  197.         {
  198.             return hr;
  199.         }
  200.         hr = pObj->QueryInterface( riid, ppvObj );
  201.         //Kill the object if initial creation or FInit failed.
  202.         if( FAILED(hr) )
  203.         {
  204.             delete pObj;
  205.         }
  206.         else
  207.         {
  208.             g_cObj++;
  209.         }
  210.         return hr;
  211.     }
  212.     return E_NOINTERFACE;
  213. }
  214. //---------------------------------------------------------------------------
  215. //      LockServer()
  216. //---------------------------------------------------------------------------
  217. STDMETHODIMP CClassFactory::LockServer( BOOL fLock )
  218. {
  219.     if( fLock )
  220.     {
  221.         g_cLock++;
  222.     }
  223.     else
  224.     {
  225.         g_cLock--;
  226.     }
  227.     return NOERROR;
  228. }
  229. //***************************************************************************
  230. //
  231. //  CPropSheetExt Class
  232. //
  233. //***************************************************************************
  234. //---------------------------------------------------------------------------
  235. //  Constructor
  236. //---------------------------------------------------------------------------
  237. CPropSheetExt::CPropSheetExt( LPUNKNOWN pUnkOuter, LPFNDESTROYED pfnDestroy )
  238. {
  239.     m_cRef = 0;
  240.     m_pUnkOuter = pUnkOuter;
  241.     m_pfnDestroy = pfnDestroy;
  242.     return;
  243. }
  244. //---------------------------------------------------------------------------
  245. //  Destructor
  246. //---------------------------------------------------------------------------
  247. CPropSheetExt::~CPropSheetExt( void )
  248. {
  249.     return;
  250. }
  251. //---------------------------------------------------------------------------
  252. //  QueryInterface()
  253. //---------------------------------------------------------------------------
  254. STDMETHODIMP CPropSheetExt::QueryInterface( REFIID riid, LPVOID* ppv )
  255. {
  256.     *ppv = NULL;
  257.     if (IsEqualIID(riid, IID_IShellExtInit))
  258.     {
  259.         *ppv = (IShellExtInit *) this;
  260.     }
  261.     if (IsEqualIID(riid, IID_IShellPropSheetExt))
  262.     {
  263.         *ppv = (LPVOID)this;
  264.     }
  265.     if (*ppv)
  266.     {
  267.         ++m_cRef;
  268.         return NOERROR;
  269.     }
  270.     return ResultFromScode(E_NOINTERFACE);
  271. }
  272. //---------------------------------------------------------------------------
  273. //  AddRef()
  274. //---------------------------------------------------------------------------
  275. STDMETHODIMP_(ULONG) CPropSheetExt::AddRef( void )
  276. {
  277.     return ++m_cRef;
  278. }
  279. //---------------------------------------------------------------------------
  280. //  Release()
  281. //---------------------------------------------------------------------------
  282. STDMETHODIMP_(ULONG) CPropSheetExt::Release( void )
  283. {
  284. ULONG cRefT;
  285.     cRefT = --m_cRef;
  286.     if( m_cRef == 0 )
  287.     {
  288.         // Tell the housing that an object is going away so that it
  289.         // can shut down if appropriate.
  290.         if( NULL != m_pfnDestroy )
  291.         {
  292.             (*m_pfnDestroy)();
  293.         }
  294.         delete this;
  295.     }
  296.     return cRefT;
  297. }
  298. //---------------------------------------------------------------------------
  299. //  AddPages()
  300. //---------------------------------------------------------------------------
  301. STDMETHODIMP CPropSheetExt::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam )
  302. {
  303.     PROPSHEETPAGE psp;
  304.     HPROPSHEETPAGE hpage;
  305.     TCHAR szTitle[ 30 ];
  306.     LoadString( g_hInst, IDS_PAGE_TITLE, szTitle, ARRAYSIZE(szTitle) );
  307.     psp.dwSize = sizeof(PROPSHEETPAGE);
  308.     psp.dwFlags = PSP_USETITLE | PSP_USECALLBACK;
  309.     psp.hIcon = NULL;
  310.     psp.hInstance = g_hInst;
  311.     psp.pszTemplate =MAKEINTRESOURCE( PROP_SHEET_DLG );
  312.     psp.pfnDlgProc = (DLGPROC)PropertySheeDlgProc;
  313.     psp.pfnCallback = PropertySheeCallback;
  314.     psp.pszTitle = szTitle;
  315.     psp.lParam = 0;
  316. #ifdef USESLINKCONTROL
  317.     LinkWindow_RegisterClass();
  318. #endif
  319.     
  320.     if( ( hpage = CreatePropertySheetPage( &psp ) ) == NULL )
  321.     {
  322.         return ( E_OUTOFMEMORY );
  323.     }
  324.     if( !lpfnAddPage(hpage, lParam ) )
  325.     {
  326.         DestroyPropertySheetPage(hpage );
  327.         return ( E_FAIL );
  328.     }
  329.     return NOERROR;
  330. }
  331. //---------------------------------------------------------------------------
  332. //  ReplacePage()
  333. //---------------------------------------------------------------------------
  334. STDMETHODIMP CPropSheetExt::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam )
  335. {
  336.     return NOERROR;
  337. }
  338. //---------------------------------------------------------------------------
  339. //  IShellExtInit member function- this interface needs only one
  340. //---------------------------------------------------------------------------
  341. STDMETHODIMP CPropSheetExt::Initialize(LPCITEMIDLIST pcidlFolder,
  342.                                        LPDATAOBJECT pdoTarget,
  343.                                        HKEY hKeyID)
  344. {
  345.     //
  346.     //  The target data object is an HDROP, or list of files from the shell.
  347.     //
  348.     if (g_lpdoTarget)
  349.     {
  350.         g_lpdoTarget->Release();
  351.         g_lpdoTarget = NULL;
  352.     }
  353.     if (pdoTarget)
  354.     {
  355.         g_lpdoTarget = pdoTarget;
  356.         g_lpdoTarget->AddRef();
  357.     }
  358.     return  NOERROR;
  359. }