home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / prefs / nsprefui / src / prefui.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  10.0 KB  |  389 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "pch.h"
  20. #include <assert.h>
  21. #include "prefui.h"
  22. #include "prefpriv.h"
  23. #include "framedlg.h"
  24.  
  25. HINSTANCE    g_hInstance;
  26.  
  27. /////////////////////////////////////////////////////////////////////////////
  28. // Global new/delete operators
  29.  
  30. void *
  31. operator new (size_t size)
  32. {
  33. #ifdef _WIN32
  34.     return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
  35. #else
  36.     return (void *)(void NEAR *)LocalAlloc(LPTR, size);
  37. #endif
  38. }
  39.  
  40. void
  41. operator delete (void *lpMem)
  42. {
  43. #ifdef _WIN32
  44.     HeapFree(GetProcessHeap(), 0, lpMem);
  45. #else
  46.     LocalFree((HLOCAL)OFFSETOF(lpMem));
  47. #endif
  48. }
  49.  
  50. /////////////////////////////////////////////////////////////////////////////
  51. // Helper routines
  52.  
  53. #ifndef _WIN32
  54. static LPVOID
  55. CoTaskMemAlloc(ULONG cb)
  56. {
  57.     LPMALLOC    pMalloc;
  58.     
  59.     if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pMalloc))) {
  60.         LPVOID    pv;
  61.          
  62.         pv = pMalloc->Alloc(cb);
  63.         pMalloc->Release();
  64.         return pv;
  65.     }
  66.  
  67.     return NULL;
  68. }
  69.  
  70. static void
  71. CoTaskMemFree(LPVOID pv)
  72. {
  73.     if (pv) {
  74.         LPMALLOC    pMalloc;
  75.     
  76.         if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pMalloc))) {
  77.             pMalloc->Free(pv);
  78.             pMalloc->Release();
  79.         }
  80.     }
  81. }
  82. #endif
  83.  
  84. // Converts an OLE string (UNICODE) to an ANSI string. The caller
  85. // must use CoTaskMemFree to free the memory
  86. static LPSTR
  87. AllocTaskAnsiString(LPOLESTR lpszString)
  88. {
  89.     LPSTR    lpszResult;
  90.     UINT    nBytes;
  91.  
  92.     if (lpszString == NULL)
  93.         return NULL;
  94.  
  95. #ifdef _WIN32
  96.     nBytes = (wcslen(lpszString) + 1) * 2;
  97. #else
  98.     nBytes = lstrlen(lpszString) + 1;  // Win 16 doesn't use any UNICODE
  99. #endif
  100.     lpszResult = (LPSTR)CoTaskMemAlloc(nBytes);
  101.  
  102.     if (lpszResult) {
  103. #ifdef _WIN32
  104.         WideCharToMultiByte(CP_ACP, 0, lpszString, -1, lpszResult, nBytes, NULL, NULL);
  105. #else
  106.         lstrcpy(lpszResult, lpszString);
  107. #endif
  108.     }
  109.  
  110.     return lpszResult;
  111. }
  112.  
  113. /////////////////////////////////////////////////////////////////////////////
  114. // CPropertyCategories implementation
  115.  
  116. // Destructor. Release all the interface pointers and free the
  117. // counted arrays
  118. CPropertyCategories::~CPropertyCategories()
  119. {
  120.     delete []m_pCategories;
  121. }
  122.  
  123. // Create the individual property pages for each of the
  124. // property categories
  125. HRESULT
  126. CPropertyCategories::Initialize(ULONG                           nCategories,
  127.                                 LPSPECIFYPROPERTYPAGEOBJECTS *lplpProviders,
  128.                                 LPPROPERTYPAGESITE              pSite)
  129. {
  130.     m_nCategories = nCategories;
  131.     m_pCategories = new CPropertyCategory[nCategories];
  132.     if (!m_pCategories)
  133.         return ResultFromScode(E_OUTOFMEMORY);
  134.  
  135.     for (ULONG i = 0; i < nCategories; i++) {
  136.         HRESULT    hres = m_pCategories[i].CreatePages(lplpProviders[i], pSite);
  137.  
  138.         if (FAILED(hres))
  139.             return hres;
  140.     }
  141.  
  142.     return NOERROR;
  143. }
  144.  
  145. /////////////////////////////////////////////////////////////////////////////
  146. // CPropertyCategory implementation
  147.  
  148. // Releases the reference to the interface for the property page provider,
  149. // and destroys each of the property pages objects
  150. CPropertyCategory::~CPropertyCategory()
  151. {
  152.     delete []m_pPages;
  153.     if (m_pProvider)
  154.         m_pProvider->Release();
  155. }
  156.  
  157. // Gets the list of property page obejcts and initializes each of the pages
  158. HRESULT
  159. CPropertyCategory::CreatePages(LPSPECIFYPROPERTYPAGEOBJECTS pProvider,
  160.                                LPPROPERTYPAGESITE              pSite)
  161. {
  162.     CAPPAGE        pages;
  163.     HRESULT        hres;
  164.     
  165.     // Keep the pointer to the property page provider. This is passed
  166.     // as the data object for each property page
  167.     m_pProvider = pProvider;
  168.     m_pProvider->AddRef();
  169.     
  170.     // Get the list of property pages objects
  171.     hres = pProvider->GetPageObjects(&pages);
  172. #ifdef _DEBUG
  173.     if (FAILED(hres)) {
  174.         OutputDebugString("Call to GetPageObjects() failed for property page provider\n");
  175.     }
  176. #endif
  177.  
  178.     if (SUCCEEDED(hres)) {
  179.         m_pPages = new CPropertyPage[pages.cElems];
  180.         if (!m_pPages) {
  181.             for (ULONG i = 0; i < pages.cElems; i++)
  182.                 pages.pElems[i]->Release();
  183.             CoTaskMemFree(pages.pElems);
  184.             return ResultFromScode(E_OUTOFMEMORY);
  185.         }
  186.  
  187.         // Initialize the array of property pages
  188.         m_nPages = 0;
  189.         for (ULONG i = 0; i < pages.cElems; i++) {
  190.             LPPROPERTYPAGE    pPage = pages.pElems[m_nPages];
  191.              
  192.             // Set the back pointer
  193.             m_pPages[m_nPages].m_pCategory = this;
  194.             
  195.             // Initialize the property page
  196.             hres = m_pPages[m_nPages].Initialize(pPage, pSite);
  197.  
  198.             // We're all done with the page
  199.             pPage->Release();
  200.             m_nPages++;
  201.         }
  202.  
  203.         CoTaskMemFree(pages.pElems);
  204.     }
  205.  
  206.     return hres;
  207. }
  208.  
  209. /////////////////////////////////////////////////////////////////////////////
  210. // CPropertyPage implementation
  211.  
  212. // Releases the reference to the interface for the property page,
  213. // set its page site to NULL, and frees any memory
  214. CPropertyPage::~CPropertyPage()
  215. {
  216.     if (m_pPage) {
  217.         m_pPage->SetPageSite(NULL);
  218.         m_pPage->Release();
  219.     }
  220.  
  221.     CoTaskMemFree((void *)m_lpszTitle);
  222.     CoTaskMemFree((void *)m_lpszDescription);
  223.     CoTaskMemFree((void *)m_lpszHelpTopic);
  224. }
  225.  
  226. // Initializes the property page by setting the page site
  227. // and getting the page info
  228. HRESULT
  229. CPropertyPage::Initialize(LPPROPERTYPAGE pPage, LPPROPERTYPAGESITE pSite)
  230. {
  231.     HRESULT    hres;
  232.  
  233.     // Hold a reference to the property page
  234.     m_pPage = pPage;
  235.     m_pPage->AddRef();
  236.  
  237.     // First thing we do is set the page site. This initializes
  238.     // the property page
  239.     hres = m_pPage->SetPageSite(pSite);
  240. #ifdef _DEBUG
  241.     if (FAILED(hres))
  242.         OutputDebugString("Call to SetPageSite() failed\n");
  243. #endif
  244.  
  245.     // Get information about the property page
  246.     PROPPAGEINFO    pageInfo;
  247.  
  248.     pageInfo.cb = sizeof(pageInfo);
  249.     hres = m_pPage->GetPageInfo(&pageInfo);
  250.     if (FAILED(hres)) {
  251. #ifdef _DEBUG
  252.         OutputDebugString("Call to GetPageInfo() failed\n");
  253. #endif
  254.         return hres;
  255.     }
  256.  
  257.     // The page must have a title
  258.     if (!pageInfo.pszTitle) {
  259. #ifdef _DEBUG
  260.         OutputDebugString("Property page has NULL 'pszTitle'\n");
  261. #endif
  262.         hres = ResultFromScode(E_UNEXPECTED);
  263.     }
  264.  
  265.     // Save the size for later
  266.     m_size = pageInfo.size;
  267.  
  268.     // OLE strings are UNICODE and we need ANSI strings
  269.     // XXX - use CString...
  270.     m_lpszTitle = AllocTaskAnsiString(pageInfo.pszTitle);
  271.     if (!m_lpszTitle) {
  272.         hres = ResultFromScode(E_OUTOFMEMORY);
  273.         goto done;
  274.     }
  275.  
  276.     if (pageInfo.pszDocString) {
  277.         m_lpszDescription = AllocTaskAnsiString(pageInfo.pszDocString);
  278.         if (!m_lpszDescription) {
  279.             hres = ResultFromScode(E_OUTOFMEMORY);
  280.             goto done;
  281.         }
  282.     }
  283.  
  284.     if (pageInfo.pszHelpFile) {
  285.         // NetHelp help topic is a string so it's stored in pszHelpFile
  286.         // instead of using dwHelpContext
  287.         m_lpszHelpTopic = AllocTaskAnsiString(pageInfo.pszHelpFile);
  288.         if (!m_lpszHelpTopic) {
  289.             hres = ResultFromScode(E_OUTOFMEMORY);
  290.             goto done;
  291.         }
  292.     }
  293.  
  294.   done:
  295.     // Free the memory
  296.     CoTaskMemFree(pageInfo.pszTitle);
  297.     CoTaskMemFree(pageInfo.pszDocString);
  298.     CoTaskMemFree(pageInfo.pszHelpFile);
  299.     return hres;
  300. }
  301.  
  302. //
  303. //  FUNCTION: NS_CreatePropertyFrame()
  304. //
  305. //  PURPOSE:  Called to create a property frame dialog. This function
  306. //              doesn't return until the dialog is closed.
  307. //
  308. //  PARAMETERS:
  309. //    hwndOwner - parent window of property sheet dialog
  310. //    x - horizontal position for dialog box, relative to hwndOwner
  311. //    y - vertical position for dialog box, relative to hwndOwner
  312. //    lpszCaption - dialog box caption
  313. //    nCategories - number of property page providers in lplpProviders
  314. //    lplpProviders - array of property page providers
  315. //    nInitial - index of category to be initially displayed
  316. //
  317. STDAPI
  318. NS_CreatePropertyFrame(HWND                             hwndOwner,
  319.                        int                                x,
  320.                        int                                y,
  321.                        LPCSTR                           lpszCaption,
  322.                        ULONG                            nCategories,
  323.                        LPSPECIFYPROPERTYPAGEOBJECTS *lplpProviders,
  324.                        ULONG                            nInitial,
  325.                        NETHELPFUNC                   lpfnNetHelp)
  326. {
  327.     HRESULT    hres;
  328.  
  329.     assert(nCategories > 0);
  330.     if (nCategories == 0)
  331.         return ResultFromScode(S_FALSE);
  332.  
  333.     // Create the property frame dialog
  334.     CPropertyFrameDialog    dialog(hwndOwner, x, y, lpszCaption, lpfnNetHelp);
  335.  
  336.     // Initialize the property frame dialog
  337.     hres = dialog.CreatePages(nCategories, lplpProviders, nInitial);
  338.     if (FAILED(hres)) {
  339. #ifdef _DEBUG
  340.         OutputDebugString("CPropertyFrameDialog::CreatePages failed\n");
  341. #endif
  342.         return hres;
  343.     }
  344.  
  345.     // Display the property frame as a modal dialog
  346.     dialog.DoModal();
  347.     return NOERROR;
  348. }
  349.  
  350. #ifdef _WIN32
  351. // Main entry point for the DLL. By defining the entry point ourselves
  352. // and not using the Visual C++ runtime library entry point we can avoid
  353. // linking in the runtime initialization code
  354. BOOL WINAPI
  355. DllEntryPoint(HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved)
  356. {
  357.     switch (dwReason) {
  358.         case DLL_PROCESS_ATTACH:
  359.             // The DLL is being loaded for the first time by a given process
  360.             g_hInstance = hInstance;
  361.             break;
  362.  
  363.         case DLL_PROCESS_DETACH:
  364.             // The DLL is being unloaded by a given process
  365.             break;
  366.  
  367.         case DLL_THREAD_ATTACH:
  368.             // A thread is being created in a process that has already loaded
  369.             // this DLL
  370.             break;
  371.  
  372.         case DLL_THREAD_DETACH:
  373.             // A thread is exiting cleanly in a process that has already
  374.             // loaded this DLL
  375.             break;
  376.     }
  377.  
  378.     return TRUE;
  379. }
  380. #else
  381. extern "C" int CALLBACK
  382. LibMain(HINSTANCE hInstance, WORD wDataSeg, WORD cbHeapSize, LPSTR)
  383. {
  384.     g_hInstance = hInstance;
  385.     InitTreeViewControl();
  386.     return TRUE;
  387. }
  388. #endif
  389.