Figures
Figure 1
Figure 1
Figure 1 fooble
////////////////////////////////////////////////////////////////
// MSDN — May 2000
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably Windows NT 
// too.
//
// StaticClassArray — shows how to initialize a static C array of C++ 
// objects.
// To compile, type:
//
//    cl fooble.cpp
//
#include <stdio.h>

//////////////////
// A typical class with three data members...
//
class CFooble {
protected:
   int x,y,z;

public:
   // two constructors...
   CFooble(int i) { x=y=z=i; }
   CFooble(int xx, int yy, int zz) : x(xx),y(yy),z(zz) { }

   // a print function..
   void print() {
      printf("CFooble at %p: (%d,%d,%d)\n", this, x, y, z);
   }

   // and a function to check for emptiness...
   int IsEmpty() {
      return x==0 && y==0 && z==0;
   }
};

#ifdef NEVER
// This won't work—you can't do "raw" initialization of C++ class objects! 
CFooble table[] = {
   { 1,2,3 },
   { 4,5,6 },
   { 0,0,0 }
};
#endif

// Here's how to initialize a class array:
CFooble table[] = {
   CFooble(1,2,3),
   CFooble(4,5,6),
   CFooble(0), // can even use a different constructor!
};

void main()
{
   for (CFooble* pc=table; !pc->IsEmpty(); pc++) {
      pc->print();
   }
}
Figure 2 IActiveDesktop Methods
Method
Purpose
AddDesktopItem
Adds a desktop item
AddDesktopItemWithUI
Adds a desktop item to the Active Desktop using a user interface
AddUrl
Adds the desktop item associated with the specified URL
ApplyChanges
Applies changes to the Active Desktop. You must call this to make other changes effective. Used to enable or disable Active Desktop
GenerateDesktopItemHtml
Generates a generic HTML page containing the given desktop item
GetDesktopItem
Retrieves the specified desktop item
GetDesktopItemByID
Retrieves the desktop item that matches the given identification
GetDesktopItemBySource
Retrieves a desktop item using its source URL
GetDesktopItemCount
Retrieves a count of the desktop items
GetDesktopItemOptions
Finds out if Active Desktop is on or off. SHGetSettings is better. Used to enable or disable Active Desktop
GetPattern
Retrieves the pattern currently being used
GetWallpaper
Retrieves the wallpaper currently being used. Active Desktop only—for normal mode (Active Desktop off), use SystemParametersInfo
GetWallpaperOptions
Retrieves the wallpaper options. Active Desktop only—for normal mode (Active Desktop off), use SystemParametersInfo
ModifyDesktopItem
Modifies the desktop item
RemoveDesktopItem
Removes the specified desktop item from the desktop
SetDesktopItemOptions
Turns Active Desktop on or off
SetPattern
Sets the Active Desktop pattern
SetWallpaper
Sets the wallpaper for the Active Desktop. Active Desktop only—for normal mode (Active Desktop off), use SystemParametersInfo
SetWallpaperOptions
Sets the wallpaper options. Active Desktop only—for normal mode (Active Desktop off), use SystemParametersInfo
Figure 3 SHGetSettings.h
////////////////////////////////////////////////////////////////
// Information obtained with SHGetSettings

// SHGetSettings retrieves current shell settings. 
//
VOID SHGetSettings(
    LPSHELLFLAGSTATE lpsfs, // address of struct below
    DWORD dwMask            // which info to get (see below)
);

// SHGetSettings fills this structure of bit fields. The flags correspond
// more or less to the choices in Explorer under View | Folder Options, 
// View tab.
//
typedef struct {
    BOOL fShowAllObjects : 1;   // show all files (hidden, sys)
    BOOL fShowExtensions : 1;   // show file name extension (eg, .txt)
    BOOL fNoConfirmRecycle : 1; // don't confirm delete
    BOOL fShowSysFiles : 1;     // show files with system attribute
    BOOL fShowCompColor : 1;
    BOOL fDoubleClickInWebView : 1; // what it says
    BOOL fDesktopHTML : 1;          // Active Desktop is on
    BOOL fWin95Classic : 1;         // Windows 95 "Classic" view is on.
    BOOL fDontPrettyPath : 1;
    BOOL fShowAttribCol : 1;
    BOOL fMapNetDrvBtn : 1;  // show Map Network Drive button
    BOOL fShowInfoTip : 1;   // show popup descriptions
    BOOL fHideIcons : 1;     // hide icons in Active Desktop mode
    UINT fRestFlags : 3;
} SHELLFLAGSTATE;

// These flags are used to get the fields above; ie, call with dwMask = 
// (SSF_DESKTOPHTML | SSF_WIN95CLASSIC) to retrieve fDesktopHTML and
// fWin95Classic. 
//
#define SSF_SHOWALLOBJECTS          0x00000001
#define SSF_SHOWEXTENSIONS          0x00000002
#define SSF_SHOWCOMPCOLOR           0x00000008
#define SSF_SHOWSYSFILES            0x00000020
#define SSF_DOUBLECLICKINWEBVIEW    0x00000080
#define SSF_SHOWATTRIBCOL           0x00000100
#define SSF_DESKTOPHTML             0x00000200
#define SSF_WIN95CLASSIC            0x00000400
#define SSF_DONTPRETTYPATH          0x00000800
#define SSF_SHOWINFOTIP             0x00002000
#define SSF_MAPNETDRVBUTTON         0x00001000
#define SSF_NOCONFIRMRECYCLE        0x00008000
#define SSF_HIDEICONS               0x00004000
Figure 7 TestAD Source

(In the printed version of the May issue of MSDN Magazine, several lines of code were inadvertently omitted from figure 7. The version here is complete.)

ActiveDesk.h
////////////////////////////////////////////////////////////////
// MSDN Magazine — May 2001
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0. Runs on Windows 98 and probably Windows 
// 2000 too.
// 
#pragma once

#include <atlbase.h> // ATL smart pointers
#include <shlguid.h> // shell GUIDs
#include <shlobj.h>  // IActiveDesktop

//////////////////
// Handy class to enable/disable Active Desktop. This class wraps only the
// IActiveDesktop functions needed to enable/disable and get the enabled
// status. You could improve it to encapsulate all of IActiveDesktop.
//
class CActiveDesktop {
protected:
   // ATL smart pointers are the only way to go!!
   CComQIPtr<IActiveDesktop> m_pIActiveDesktop;

public:
   HRESULT m_hr; // most recent return code

   // ctor: create IActiveDesktop interface instance
   // 
   CActiveDesktop() {
      m_hr = m_pIActiveDesktop.CoCreateInstance(CLSID_ActiveDesktop,
         NULL, CLSCTX_INPROC_SERVER);
      // If this bombs, you probably forgot to call call CoInitialize
      ASSERT(SUCCEEDED(m_hr));
   }

   // Determine if Active Desktop is enabled. SHGetSettings is apparently
   // more reliable than IActiveDesktop::GetDesktopItemOptions, which can
   // report incorrectly during the middle of ApplyChanges!
   // 
   BOOL IsEnabled() {
      SHELLFLAGSTATE shfs;
      SHGetSettings(&shfs, SSF_DESKTOPHTML);
      return shfs.fDesktopHTML;
   }
      
   // Enable/disable Active Desktop.
   // Calls ApplyChanges to make it really happen.
   //
   void Enable(BOOL bEnable) {
      ASSERT(m_pIActiveDesktop);
      COMPONENTSOPT opt;
      opt.dwSize = sizeof(opt);
      opt.fActiveDesktop = opt.fEnableComponents = bEnable;
      m_hr = m_pIActiveDesktop->SetDesktopItemOptions(&opt,0);
      ASSERT(SUCCEEDED(m_hr));
      ApplyChanges(AD_APPLY_REFRESH); // do it!
   }

   // Apply the changes
   //
   void ApplyChanges(DWORD dwFlags) {
      ASSERT(m_pIActiveDesktop);
      m_hr = m_pIActiveDesktop->ApplyChanges(dwFlags);
      ASSERT(SUCCEEDED(m_hr));
   };
};

MainFrm.h
////////////////////////////////////////////////////////////////
// MSDN Magazine — May 2001
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0. Runs on Windows 98 and probably Windows 
// 2000 too.
// 
#pragma once

#include "ActiveDesk.h"

//////////////////
// Typical mainframe class. Main window has a read-only edit control to
// display WM_SETTINCHANGE and whether Active Desktop is enabled/disabled.
//
class CMainFrame : public CFrameWnd {
public:
   CMainFrame();
   virtual ~CMainFrame();

protected: 
   CEdit       m_wndEdit;               // main view: edit window
   CStatusBar  m_wndStatusBar;          // standard status bar
   CToolBar    m_wndToolBar;            // standard toolbar buttons

   // helper: show status in edit window
   void ShowADStatus();

   virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

   // WM_ handlers
   afx_msg int  OnCreate(LPCREATESTRUCT lpCreateStruct);
   afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);

   // Command/UI handlers
   afx_msg void OnEditClear();
   afx_msg void OnActiveDesktop();
   afx_msg void OnUpdateActiveDesktop(CCmdUI* pCmdUI);

   DECLARE_MESSAGE_MAP()
   DECLARE_DYNAMIC(CMainFrame)
};

MainFrm.cpp
////////////////////////////////////////////////////////////////
// MSDN Magazine — May 2001
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0. Runs on Windows 98 and probably Windows 
// 2000 too.
// 
#include "stdafx.h"
#include "resource.h"
#include "MainFrm.h"
#include "ActiveDesk.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
   ON_WM_CREATE()
   ON_WM_SETTINGCHANGE()
   ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
   ON_COMMAND(ID_ACTIVEDESKTOP, OnActiveDesktop)
   ON_UPDATE_COMMAND_UI(ID_ACTIVEDESKTOP, OnUpdateActiveDesktop)
END_MESSAGE_MAP()

static UINT indicators[] = {
   ID_SEPARATOR,
   ID_INDICATOR_CAPS,
   ID_INDICATOR_NUM,
   ID_INDICATOR_SCRL,
};

CMainFrame::CMainFrame()
{
}

CMainFrame::~CMainFrame()
{
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
   VERIFY(CFrameWnd::OnCreate(lpCreateStruct)==0);

   // Create main edit window. Use AFX_IDW_PANE_FIRST so MFC will size it!
   //
   VERIFY(m_wndEdit.CreateEx(WS_EX_CLIENTEDGE,"Edit","",
      WS_VISIBLE|WS_VSCROLL|WS_CHILD|ES_READONLY|ES_MULTILINE,
      CRect(0, 0, 0, 0) ,this, AFX_IDW_PANE_FIRST));

   // Create toolbar
   VERIFY(m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE |
      CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC));
   VERIFY(m_wndToolBar.LoadToolBar(IDR_MAINFRAME));

   // Create status bar
   VERIFY(m_wndStatusBar.Create(this));
   VERIFY(m_wndStatusBar.SetIndicators(indicators,
        sizeof(indicators)/sizeof(UINT)));

   ShowADStatus(); // show initial Active Destkop on/off status

   return 0;
}

//////////////////
// Main about to be created: adjust flags.
//
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
   if( !CFrameWnd::PreCreateWindow(cs) )
      return FALSE;
   cs.style |= WS_CLIPCHILDREN;         // no display flicker
   cs.dwExStyle &= ~WS_EX_CLIENTEDGE;   // no thin client edge
   cs.cx = 500;                         // use smaller default size..
   cs.cy = 250;                         // ..
   return TRUE;
}

//////////////////
// Clear edit window.
//
void CMainFrame::OnEditClear()
{
   m_wndEdit.SetWindowText(_T(""));
}

//////////////////
// Somebody changed system settings: display a message.
//
void CMainFrame::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
   CFrameWnd::OnSettingChange(uFlags, lpszSection);
   CString msg;
   msg.Format(_T("WM_SETTINGCHANGE: flags=0x%08x, section=%s\r\n"),
      uFlags, lpszSection);
   m_wndEdit.SetSel(-1,-1);
   m_wndEdit.ReplaceSel(msg);

   if (lpszSection && _tcscmp(lpszSection,_T("ShellState"))==0) {
      // Active Desktop state possibly changed: display it too.
      ShowADStatus();
   }
}

//////////////////
// Display current Active Desktop on/off state.
//
void CMainFrame::ShowADStatus()
{
   CActiveDesktop ad;
   CString msg;
   msg.Format(_T("Active Desktop is %s\r\n"),
      ad.IsEnabled() ? _T("ON") : _T("OFF"));
   m_wndEdit.SetSel(-1,-1);
   m_wndEdit.ReplaceSel(msg);
}

////////////////////
// Command: Enable/Disable Active Desktop.
//
void CMainFrame::OnActiveDesktop()
{
   CActiveDesktop ad;
   ad.Enable(!ad.IsEnabled());
}

////////////////////
// Update menu item: change name appopriately
//
void CMainFrame::OnUpdateActiveDesktop(CCmdUI* pCmdUI)
{
   CActiveDesktop ad;
   pCmdUI->SetText(ad.IsEnabled() ? _T("Disable &Active Desktop")
      : _T("Enable &Active Desktop"));
}
Page view tracker