Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

IPropSheetExt...

Posted on 1999-07-15
4
Medium Priority
?
277 Views
Last Modified: 2013-12-03
I'm going to try to add a tab to the 'Display Properties' dialog deally.  I'm assuming I have to use IPropSheetExt.  However, I have no clue how to use it, I can't find anything on MSDN about it, and I can't find any examples/tutorials on the web.  Can someone tell me how to do this and provide some sample code (not MFC) if possible?...Thanx guys
0
Comment
Question by:redec
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
4 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 450 total points
ID: 1403064
See the MS 'shellext' sample on the VC++ cdrom (or at msdn.microsoft.com) - it uses IShellPropSheetExt to implement this:

   //IShellPropSheetExt methods
    STDMETHODIMP AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam);
   
    STDMETHODIMP ReplacePage(UINT uPageID,
                             LPFNADDPROPSHEETPAGE lpfnReplaceWith,
                             LPARAM lParam);



// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) 1993-1995  Microsoft Corporation.  All Rights Reserved.
//
//  MODULE:   propshet.cpp
//
//  PURPOSE:   Implements the IShellPropSheetExt member functions necessary to
//             support the property sheet page of this shell extension.  This
//             page is displayed when the user selects "Properties..." after
//             right clicking on a .GAK file
//

#include "priv.h"
#include "shellext.h"
#include "resource.h"

extern UINT g_cRefThisDll;         // Reference count of this DLL.
extern HINSTANCE g_hmodThisDll; // Handle to this DLL itself.

//
//  FUNCTION: GAKPageDlgProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE: Callback dialog procedure for the property page
//
//  PARAMETERS:
//    hDlg      - Dialog box window handle
//    uMessage  - current message
//    wParam    - depends on message
//    lParam    - depends on message
//
//  RETURN VALUE:
//
//    Depends on message.  In general, return TRUE if we process it.
//
//  COMMENTS:
//

BOOL CALLBACK GAKPageDlgProc(HWND hDlg,
                             UINT uMessage,
                             WPARAM wParam,
                             LPARAM lParam)
{
    LPPROPSHEETPAGE psp=(LPPROPSHEETPAGE)GetWindowLong(hDlg, DWL_USER);
    UINT iIndex=0;
    int  iID;
    LPCSHELLEXT lpcs;
      char szTemp[4];

    switch (uMessage)
    {
        //
        // When the shell creates a dialog box for a property sheet page,
        // it passes the pointer to the PROPSHEETPAGE data structure as
        // lParam. The dialog procedures of extensions typically store it
        // in the DWL_USER of the dialog box window.
        //
        case WM_INITDIALOG:
            SetWindowLong(hDlg, DWL_USER, lParam);

            psp = (LPPROPSHEETPAGE)lParam;

            lpcs = (LPCSHELLEXT)psp->lParam;

                  if (*(lpcs->m_szPropSheetFileUserClickedOn))
                  iIndex = (UINT)GetPrivateProfileInt("IconImage",
                                                        "Index",
                                                        0,
                                                        lpcs->m_szPropSheetFileUserClickedOn);

            //Note that the following line assumes that IDC_RED, IDC_GREEN,
            //and IDC_BLUE are in sequential order, with IDC_RED having the
            //smallest value.
            SendDlgItemMessage(hDlg, iIndex + IDC_RED, BM_SETCHECK, TRUE, 0L);

            break;

        case WM_DESTROY:
            RemoveProp(hDlg, "ID");
            break;

        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
                case IDC_RED:
                case IDC_GREEN:
                case IDC_BLUE:
                    SetProp(hDlg, "ID", (HANDLE)lParam);
                    break;

                default:
                    break;
            }
            break;

        case WM_NOTIFY:
            switch (((NMHDR FAR *)lParam)->code)
            {
                case PSN_SETACTIVE:
                    break;

                case PSN_APPLY:
                    //User has clicked the OK or Apply button so we'll
                    //update the icon information in the .GAK file
                    lpcs = (LPCSHELLEXT)psp->lParam;
                    iID  = GetDlgCtrlID((HWND)GetProp(hDlg, "ID"));
                    iID -= IDC_RED;
                    wsprintf(szTemp, "%i", iID);
                            WritePrivateProfileString("IconImage",
                                              "Index",
                                               szTemp,
                                               lpcs->m_szPropSheetFileUserClickedOn);
                    //Ask the shell to refresh the icon list...
                    SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSHNOWAIT, 0, 0);
                    break;
           
                default:
                    break;
            }
            break;

        default:
            return FALSE;
    }

    return TRUE;
}


//
//  FUNCTION: CShellExt::AddPages(LPFNADDPROPSHEETPAGE, LPARAM)
//
//  PURPOSE: Called by the shell just before the property sheet is displayed.
//
//  PARAMETERS:
//    lpfnAddPage -  Pointer to the Shell's AddPage function
//    lParam      -  Passed as second parameter to lpfnAddPage
//
//  RETURN VALUE:
//
//    NOERROR in all cases.  If for some reason our pages don't get added,
//    the Shell still needs to bring up the Properties... sheet.
//
//  COMMENTS:
//

STDMETHODIMP CShellExt::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
{
    PROPSHEETPAGE psp;
    HPROPSHEETPAGE hpage;

    ODS("CShellExt::AddPages()\r\n");

    FORMATETC fmte = {CF_HDROP,
                        (DVTARGETDEVICE FAR *)NULL,
                        DVASPECT_CONTENT,
                        -1,
                        TYMED_HGLOBAL
                       };
    STGMEDIUM medium;
      HRESULT hres = 0;

    if (m_pDataObj)  //Paranoid check, m_pDataObj should have something by now...
       hres = m_pDataObj->GetData(&fmte, &medium);

    if (SUCCEEDED(hres))
    {
        //Find out how many files the user has selected...
        UINT cbFiles = 0;
        LPCSHELLEXT lpcsext = this;

        if (medium.hGlobal)
            cbFiles = DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, 0, 0);

        if (cbFiles < 2)
        {
            //OK, the user has only selected a single file, so lets go ahead
            //and add the property sheet.  Note that it doesn't HAVE to be this
            //way, but for simplicity and educational reasons, I'll only add
            //the property sheet if a single .GAK file is selected.

            //Get the name of the file the user has clicked on
                  if (cbFiles)
               DragQueryFile((HDROP)medium.hGlobal,
                             0,
                             m_szPropSheetFileUserClickedOn,
                             sizeof(m_szPropSheetFileUserClickedOn));

                  //
                  // Create a property sheet page object from a dialog box.
                  //
                  // We store a pointer to our class in the psp.lParam, so we
            // can access our class members from within the GAKPageDlgProc
                  //
                  // If the page needs more instance data, you can append
                  // arbitrary size of data at the end of this structure,
                  // and pass it to the CreatePropSheetPage. In such a case,
                  // the size of entire data structure (including page specific
                  // data) must be stored in the dwSize field.   Note that in
            // general you should NOT need to do this, as you can simply
            // store a pointer to date in the lParam member.
                  //
       
            psp.dwSize      = sizeof(psp);      // no extra data.
            psp.dwFlags     = PSP_USEREFPARENT | PSP_USETITLE;
            psp.hInstance   = g_hmodThisDll;
            psp.pszTemplate = MAKEINTRESOURCE(IDD_GAKPAGE);
            psp.hIcon       = 0;
            psp.pszTitle    = "GAK Color";
            psp.pfnDlgProc  = GAKPageDlgProc;
            psp.pcRefParent = &g_cRefThisDll;
            psp.lParam      = (LPARAM)lpcsext;
           
            hpage = CreatePropertySheetPage(&psp);
           
            if (hpage)
            {
                if (!lpfnAddPage(hpage, lParam))
                    DestroyPropertySheetPage(hpage);
            }
        }
    }

    return NOERROR;
}

//
//  FUNCTION: CShellExt::ReplacePage(UINT, LPFNADDPROPSHEETPAGE, LPARAM)
//
//  PURPOSE: Called by the shell only for Control Panel property sheet
//           extensions
//
//  PARAMETERS:
//    uPageID         -  ID of page to be replaced
//    lpfnReplaceWith -  Pointer to the Shell's Replace function
//    lParam          -  Passed as second parameter to lpfnReplaceWith
//
//  RETURN VALUE:
//
//    E_FAIL, since we don't support this function.  It should never be
//    called.

//  COMMENTS:
//

STDMETHODIMP CShellExt::ReplacePage(UINT uPageID,
                                    LPFNADDPROPSHEETPAGE lpfnReplaceWith,
                                    LPARAM lParam)
{
    ODS("CShellExt::ReplacePage()\r\n");

    return E_FAIL;
}


Feel free to ask if you need more information!
0
 

Author Comment

by:redec
ID: 1403065
Thanks, that will give me a starting point anyways.  Do you know perhaps where  I could find a tutorial on doing this?.....also.....do you know exactly what the ReplacePage function does?.....thx
0
 
LVL 86

Expert Comment

by:jkr
ID: 1403066
>>do you know exactly what the ReplacePage function
>>does?

Well, in this particular example, it does nothing ;-)

AFAIK there's no tutorial available, the shellext ample by MS is the only one I know about, and it's quite comprehensive - it really should be easy to adapt it...
0

Featured Post

Get free NFR key for Veeam Availability Suite 9.5

Veeam is happy to provide a free NFR license (1 year, 2 sockets) to all certified IT Pros. The license allows for the non-production use of Veeam Availability Suite v9.5 in your home lab, without any feature limitations. It works for both VMware and Hyper-V environments

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article, I will show how to use the Ribbon IDs Tool Window to assign the built-in Office icons to a ribbon button.  This tool will help us to find the OfficeImageId that corresponds to our desired built-in Office icon. The tool is part of…
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…

704 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question