home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winui / shell / shellext / propshet.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-05  |  9.4 KB  |  301 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993-1997  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE:   propshet.cpp
  9. //
  10. //  PURPOSE:   Implements the IShellPropSheetExt member functions necessary to 
  11. //             support the property sheet page of this shell extension.  This
  12. //             page is displayed when the user selects "Properties..." after
  13. //             right clicking on a .GAK file
  14. //
  15.  
  16. #include "priv.h"
  17. #include "shellext.h"
  18. #include "resource.h"
  19.  
  20. extern UINT g_cRefThisDll;         // Reference count of this DLL.
  21. extern HINSTANCE g_hmodThisDll; // Handle to this DLL itself.
  22.  
  23. //
  24. //  FUNCTION: GAKPageCallback(HWND, UINT, LPPROPSHEETPAGE)
  25. //
  26. //  PURPOSE: Callback  procedure for the property page
  27. //
  28. //  PARAMETERS:
  29. //    hWnd      - Reserved (will always be NULL)
  30. //    uMessage  - Action flag: Are we being created or released
  31. //    ppsp      - The page that is being created or destroyed
  32. //
  33. //  RETURN VALUE:
  34. //
  35. //    Depends on message. 
  36. //
  37. //    For PSPCB_CREATE it's TRUE to let the page be created
  38. //    or false to prevent it from being created.  
  39. //    For PSPCB_RELEASE the return value is ignored.
  40. //
  41. //  COMMENTS:
  42. //
  43. UINT CALLBACK
  44. GAKPageCallback(HWND hWnd,
  45.                 UINT uMessage,
  46.                 LPPROPSHEETPAGE  ppsp)
  47. {
  48.     switch(uMessage)
  49.     {
  50.         case PSPCB_CREATE:
  51.             return TRUE;
  52.  
  53.         case PSPCB_RELEASE:
  54.             if (ppsp->lParam) 
  55.             {
  56.                ((LPCSHELLEXT)(ppsp->lParam))->Release();
  57.             }
  58.             return TRUE; 
  59.     }
  60.     return TRUE;
  61. }
  62.  
  63. //
  64. //  FUNCTION: GAKPageDlgProc(HWND, UINT, WPARAM, LPARAM)
  65. //
  66. //  PURPOSE: Callback dialog procedure for the property page
  67. //
  68. //  PARAMETERS:
  69. //    hDlg      - Dialog box window handle
  70. //    uMessage  - current message
  71. //    wParam    - depends on message
  72. //    lParam    - depends on message
  73. //
  74. //  RETURN VALUE:
  75. //
  76. //    Depends on message.  In general, return TRUE if we process it.
  77. //
  78. //  COMMENTS:
  79. //
  80.  
  81. BOOL CALLBACK GAKPageDlgProc(HWND hDlg, 
  82.                              UINT uMessage, 
  83.                              WPARAM wParam, 
  84.                              LPARAM lParam)
  85. {
  86.     LPPROPSHEETPAGE psp=(LPPROPSHEETPAGE)GetWindowLong(hDlg, DWL_USER);
  87.     UINT iIndex=0;
  88.     int  iID;
  89.     LPCSHELLEXT lpcs;
  90.      char szTemp[4];
  91.  
  92.     switch (uMessage)
  93.     {
  94.         //
  95.         // When the shell creates a dialog box for a property sheet page,
  96.         // it passes the pointer to the PROPSHEETPAGE data structure as
  97.         // lParam. The dialog procedures of extensions typically store it
  98.         // in the DWL_USER of the dialog box window.
  99.         //
  100.         case WM_INITDIALOG:
  101.             SetWindowLong(hDlg, DWL_USER, lParam);
  102.  
  103.             psp = (LPPROPSHEETPAGE)lParam;
  104.  
  105.             lpcs = (LPCSHELLEXT)psp->lParam;
  106.  
  107.             if (*(lpcs->m_szPropSheetFileUserClickedOn))
  108.                 iIndex = (UINT)GetPrivateProfileInt("IconImage", 
  109.                                                     "Index", 
  110.                                                     0, 
  111.                                                     lpcs->m_szPropSheetFileUserClickedOn);
  112.  
  113.             //Note that the following line assumes that IDC_RED, IDC_GREEN,
  114.             //and IDC_BLUE are in sequential order, with IDC_RED having the
  115.             //smallest value.
  116.             SendDlgItemMessage(hDlg, iIndex + IDC_RED, BM_SETCHECK, TRUE, 0L);
  117.  
  118.             break;
  119.  
  120.         case WM_DESTROY:
  121.             RemoveProp(hDlg, "ID");
  122.             break;
  123.  
  124.         case WM_COMMAND:
  125.             switch (LOWORD(wParam))
  126.             {
  127.                 case IDC_RED:
  128.                 case IDC_GREEN:
  129.                 case IDC_BLUE:
  130.                     SetProp(hDlg, "ID", (HANDLE)lParam);
  131.                     break;
  132.  
  133.                 default:
  134.                     break;
  135.             }
  136.             break;
  137.  
  138.         case WM_NOTIFY:
  139.             switch (((NMHDR FAR *)lParam)->code)
  140.             {
  141.                 case PSN_SETACTIVE:
  142.                     break;
  143.  
  144.                 case PSN_APPLY:
  145.                     //User has clicked the OK or Apply button so we'll
  146.                     //update the icon information in the .GAK file
  147.                     lpcs = (LPCSHELLEXT)psp->lParam;
  148.                     iID  = GetDlgCtrlID((HWND)GetProp(hDlg, "ID"));
  149.                     iID -= IDC_RED;
  150.                     wsprintf(szTemp, "%i", iID);
  151.                     WritePrivateProfileString("IconImage",
  152.                                               "Index",
  153.                                                szTemp,
  154.                                                lpcs->m_szPropSheetFileUserClickedOn);
  155.                     //Ask the shell to refresh the icon list...
  156.                     SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSHNOWAIT, 0, 0);
  157.                     break;
  158.             
  159.                 default:
  160.                     break;
  161.             }
  162.             break;
  163.  
  164.         default:
  165.             return FALSE;
  166.     }
  167.  
  168.     return TRUE;
  169. }
  170.  
  171.  
  172. //
  173. //  FUNCTION: CShellExt::AddPages(LPFNADDPROPSHEETPAGE, LPARAM)
  174. //
  175. //  PURPOSE: Called by the shell just before the property sheet is displayed.
  176. //
  177. //  PARAMETERS:
  178. //    lpfnAddPage -  Pointer to the Shell's AddPage function
  179. //    lParam      -  Passed as second parameter to lpfnAddPage
  180. //
  181. //  RETURN VALUE:
  182. //
  183. //    NOERROR in all cases.  If for some reason our pages don't get added,
  184. //    the Shell still needs to bring up the Properties... sheet.
  185. //
  186. //  COMMENTS:
  187. //
  188.  
  189. STDMETHODIMP CShellExt::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
  190. {
  191.     PROPSHEETPAGE psp;
  192.     HPROPSHEETPAGE hpage;
  193.  
  194.     ODS("CShellExt::AddPages()\r\n");
  195.  
  196.     FORMATETC fmte = {CF_HDROP,
  197.                       (DVTARGETDEVICE FAR *)NULL,
  198.                       DVASPECT_CONTENT,
  199.                       -1,
  200.                       TYMED_HGLOBAL 
  201.                      };
  202.     STGMEDIUM medium;
  203.     HRESULT hres = 0;
  204.  
  205.     if (m_pDataObj)  //Paranoid check, m_pDataObj should have something by now...
  206.        hres = m_pDataObj->GetData(&fmte, &medium);
  207.  
  208.     if (SUCCEEDED(hres))
  209.     {
  210.         //Find out how many files the user has selected...
  211.         UINT cbFiles = 0;
  212.         LPCSHELLEXT lpcsext = this;
  213.  
  214.         if (medium.hGlobal)
  215.             cbFiles = DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, 0, 0);
  216.  
  217.         if (cbFiles < 2)
  218.         {
  219.             //OK, the user has only selected a single file, so lets go ahead
  220.             //and add the property sheet.  Note that it doesn't HAVE to be this
  221.             //way, but for simplicity and educational reasons, I'll only add
  222.             //the property sheet if a single .GAK file is selected.
  223.  
  224.             //Get the name of the file the user has clicked on
  225.             if (cbFiles)
  226.                DragQueryFile((HDROP)medium.hGlobal, 
  227.                              0, 
  228.                              m_szPropSheetFileUserClickedOn,
  229.                              sizeof(m_szPropSheetFileUserClickedOn));
  230.  
  231.             //
  232.             // Create a property sheet page object from a dialog box.
  233.             //
  234.             // We store a pointer to our class in the psp.lParam, so we
  235.             // can access our class members from within the GAKPageDlgProc
  236.             //
  237.             // If the page needs more instance data, you can append
  238.             // arbitrary size of data at the end of this structure,
  239.             // and pass it to the CreatePropSheetPage. In such a case,
  240.             // the size of entire data structure (including page specific
  241.             // data) must be stored in the dwSize field.   Note that in
  242.             // general you should NOT need to do this, as you can simply
  243.             // store a pointer to date in the lParam member.
  244.             //
  245.         
  246.             psp.dwSize      = sizeof(psp);    // no extra data.
  247.             psp.dwFlags     = PSP_USEREFPARENT | PSP_USETITLE | PSP_USECALLBACK;
  248.             psp.hInstance   = g_hmodThisDll;
  249.             psp.pszTemplate = MAKEINTRESOURCE(IDD_GAKPAGE);
  250.             psp.hIcon       = 0;
  251.             psp.pszTitle    = "GAK Color";
  252.             psp.pfnDlgProc  = GAKPageDlgProc;
  253.             psp.pcRefParent = &g_cRefThisDll;
  254.             psp.pfnCallback = GAKPageCallback;
  255.             psp.lParam      = (LPARAM)lpcsext;
  256.             
  257.             AddRef();
  258.             hpage = CreatePropertySheetPage(&psp);
  259.             
  260.             if (hpage) 
  261.             {
  262.                 if (!lpfnAddPage(hpage, lParam)) 
  263.                 {
  264.                     DestroyPropertySheetPage(hpage);
  265.                     Release();
  266.                 }
  267.             }
  268.         }
  269.     }
  270.  
  271.     return NOERROR;
  272. }
  273.  
  274. //
  275. //  FUNCTION: CShellExt::ReplacePage(UINT, LPFNADDPROPSHEETPAGE, LPARAM)
  276. //
  277. //  PURPOSE: Called by the shell only for Control Panel property sheet 
  278. //           extensions
  279. //
  280. //  PARAMETERS:
  281. //    uPageID         -  ID of page to be replaced
  282. //    lpfnReplaceWith -  Pointer to the Shell's Replace function
  283. //    lParam          -  Passed as second parameter to lpfnReplaceWith
  284. //
  285. //  RETURN VALUE:
  286. //
  287. //    E_FAIL, since we don't support this function.  It should never be
  288. //    called.
  289.  
  290. //  COMMENTS:
  291. //
  292.  
  293. STDMETHODIMP CShellExt::ReplacePage(UINT uPageID, 
  294.                                     LPFNADDPROPSHEETPAGE lpfnReplaceWith, 
  295.                                     LPARAM lParam)
  296. {
  297.     ODS("CShellExt::ReplacePage()\r\n");
  298.  
  299.     return E_FAIL;
  300. }
  301.