791 lines
21 KiB
C++
791 lines
21 KiB
C++
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
|
//
|
|
// Chanmenu.cpp
|
|
//
|
|
// IConextMenu for folder items.
|
|
//
|
|
// History:
|
|
//
|
|
// 6/12/97 edwardp Created.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Includes
|
|
//
|
|
|
|
#include "stdinc.h"
|
|
#include "cdfidl.h"
|
|
#include "xmlutil.h"
|
|
#include "chanmenu.h"
|
|
#include "dll.h"
|
|
#include "persist.h"
|
|
#include "resource.h"
|
|
#include "chanapi.h"
|
|
#include "chanmgrp.h"
|
|
#include "chanmgri.h"
|
|
#define _SHDOCVW_
|
|
#include <shdocvw.h>
|
|
|
|
#include <mluisupp.h>
|
|
|
|
#ifdef UNIX
|
|
EXTERN_C char *MwGetXDisplayString( void );
|
|
|
|
#ifdef UNICODE
|
|
#define unixInvokeEditor unixInvokeEditorW
|
|
#else
|
|
#define unixInvokeEditor unixInvokeEditorA
|
|
#endif /* UNICODE */
|
|
|
|
static void unixInvokeEditorA(LPCSTR lpszPath)
|
|
{
|
|
HKEY hkeyUnix;
|
|
CHAR szCommand [2*MAX_PATH];
|
|
CHAR szCmdTempl[MAX_PATH+1];
|
|
CHAR szName [MAX_PATH+1];
|
|
CHAR hKeyName [MAX_PATH+1];
|
|
|
|
STARTUPINFOA st;
|
|
PROCESS_INFORMATION pi;
|
|
|
|
BOOL bIsKnownEdit = FALSE;
|
|
char displayString [2*MAX_PATH];
|
|
DWORD editors = 0;
|
|
DWORD type = REG_SZ;
|
|
DWORD dwLength = sizeof(szCmdTempl);
|
|
|
|
if( MwGetXDisplayString() )
|
|
sprintf( displayString, "-display %s", MwGetXDisplayString() );
|
|
else
|
|
sprintf( displayString, " ");
|
|
|
|
|
|
// Get user preferred editor.
|
|
if( getenv("EDITOR" ) )
|
|
strcpy(szName, getenv("EDITOR") );
|
|
else
|
|
strcpy(szName, "vi");
|
|
|
|
// Check editor against the list of known editors in
|
|
// registry.
|
|
|
|
sprintf( hKeyName,
|
|
"Software\\Microsoft\\Internet Explorer\\Unix\\Editors\\%s",
|
|
szName );
|
|
|
|
LONG lResult = RegOpenKeyExA(
|
|
HKEY_CURRENT_USER,
|
|
hKeyName,
|
|
0,
|
|
KEY_QUERY_VALUE,
|
|
&hkeyUnix);
|
|
|
|
// Create proper command and append dissplay string to make the
|
|
// editor appear on the same XServer as the Iexplorer.
|
|
if( !bIsKnownEdit )
|
|
{
|
|
// Default use vi
|
|
sprintf( szCommand, "xterm %s -e vi %s ", displayString, lpszPath );
|
|
}
|
|
else
|
|
{
|
|
// Use template command from registry to create actual command.
|
|
sprintf( szCommand, szCmdTempl, displayString, lpszPath );
|
|
}
|
|
|
|
// Initialize startup info struct.
|
|
st.cb = sizeof(STARTUPINFO);
|
|
st.lpReserved = NULL;
|
|
st.lpDesktop = NULL;
|
|
st.lpTitle = NULL;
|
|
st.dwFlags = 0;
|
|
st.wShowWindow= SW_SHOWNORMAL;
|
|
st.cbReserved2= 0;
|
|
st.lpReserved2= NULL;
|
|
|
|
// Launch the command
|
|
if ( CreateProcessA( NULL, szCommand, NULL, NULL, TRUE,
|
|
CREATE_NEW_CONSOLE, NULL, NULL, &st, &pi ))
|
|
{
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
|
|
static void unixInvokeEditorW(LPCWSTR lpwszPath)
|
|
{
|
|
char szFileName[MAX_PATH+2]; /* same as in ViewSource */
|
|
|
|
SHUnicodeToAnsi(lpwszPath,szFileName, ARRAYSIZE(szFileName));
|
|
unixInvokeEditorA(szFileName);
|
|
|
|
return;
|
|
}
|
|
#endif /* UNIX */
|
|
|
|
|
|
|
|
//
|
|
// Constructor and destructor.
|
|
//
|
|
|
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
|
//
|
|
// *** CContextMenu::CContextMenu ***
|
|
//
|
|
// Constructor for IContextMenu.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
CChannelMenu::CChannelMenu (
|
|
void
|
|
)
|
|
: m_cRef(1)
|
|
{
|
|
TraceMsg(TF_OBJECTS, "+ IContextMenu (root)");
|
|
|
|
DllAddRef();
|
|
|
|
ASSERT(NULL == m_pSubscriptionMgr);
|
|
ASSERT(NULL == m_bstrURL);
|
|
ASSERT(NULL == m_bstrName);
|
|
|
|
return;
|
|
}
|
|
|
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
|
//
|
|
// *** CContextMenu::~CContextMenu ***
|
|
//
|
|
// Destructor.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
CChannelMenu::~CChannelMenu (
|
|
void
|
|
)
|
|
{
|
|
ASSERT(0 == m_cRef);
|
|
|
|
if (NULL != m_bstrURL)
|
|
SysFreeString(m_bstrURL);
|
|
|
|
if (NULL != m_bstrName)
|
|
SysFreeString(m_bstrName);
|
|
|
|
if (NULL != m_pSubscriptionMgr)
|
|
m_pSubscriptionMgr->Release();
|
|
//
|
|
// Matching Release for the constructor Addref.
|
|
//
|
|
|
|
TraceMsg(TF_OBJECTS, "- IContextMenu (root)");
|
|
|
|
DllRelease();
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//
|
|
// IUnknown methods.
|
|
//
|
|
|
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
|
//
|
|
// *** CContextMenu::CContextMenu ***
|
|
//
|
|
// CExtractIcon QI.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CChannelMenu::QueryInterface (
|
|
REFIID riid,
|
|
void **ppv
|
|
)
|
|
{
|
|
ASSERT(ppv);
|
|
|
|
HRESULT hr;
|
|
|
|
*ppv = NULL;
|
|
|
|
if (IID_IUnknown == riid || IID_IContextMenu == riid)
|
|
{
|
|
*ppv = (IContextMenu*)this;
|
|
}
|
|
else if (IID_IShellExtInit == riid)
|
|
{
|
|
*ppv = (IShellExtInit*)this;
|
|
}
|
|
|
|
if (*ppv)
|
|
{
|
|
((IUnknown*)*ppv)->AddRef();
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
hr = E_NOINTERFACE;
|
|
}
|
|
|
|
ASSERT((SUCCEEDED(hr) && *ppv) || (FAILED(hr) && NULL == *ppv));
|
|
|
|
return hr;
|
|
}
|
|
|
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
|
//
|
|
// *** CContextMenu::AddRef ***
|
|
//
|
|
// CContextMenu AddRef.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_(ULONG)
|
|
CChannelMenu::AddRef (
|
|
void
|
|
)
|
|
{
|
|
ASSERT(m_cRef != 0);
|
|
ASSERT(m_cRef < (ULONG)-1);
|
|
|
|
return ++m_cRef;
|
|
}
|
|
|
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
|
//
|
|
// *** CContextMenu::Release ***
|
|
//
|
|
// CContextMenu Release.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_(ULONG)
|
|
CChannelMenu::Release (
|
|
void
|
|
)
|
|
{
|
|
ASSERT (m_cRef != 0);
|
|
|
|
ULONG cRef = --m_cRef;
|
|
|
|
if (0 == cRef)
|
|
delete this;
|
|
|
|
return cRef;
|
|
}
|
|
|
|
|
|
//
|
|
// IContextMenu methods.
|
|
//
|
|
|
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
|
//
|
|
// *** CContextMenu::QueryContextMenu ***
|
|
//
|
|
//
|
|
// Description:
|
|
// Adds menu items to the given item's context menu.
|
|
//
|
|
// Parameters:
|
|
// [In Out] hmenu - A handle to the menu. New items are inserted into
|
|
// this menu
|
|
// [In] indexMenu - Zero-based position at which to insert the first
|
|
// menu item.
|
|
// [In] idCmdFirst - Minimum value that can be used for a new menu item
|
|
// identifier.
|
|
// [In] idCmdLast - Maximum value the can be used for a menu item id.
|
|
// [In] uFlags - CMF_DEFAULTONLY, CMF_EXPLORE, CMF_NORMAL or
|
|
// CMF_VERBSONLY.
|
|
//
|
|
// Return:
|
|
// On success the scode contains the the menu identifier offset of the last
|
|
// menu item added plus one.
|
|
//
|
|
// Comments:
|
|
// CMF_DEFAULTONLY flag indicates the user double-clicked on the item. In
|
|
// this case no menu is displayed. The shell is simply querying for the ID
|
|
// of the default action.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CChannelMenu::QueryContextMenu(
|
|
HMENU hmenu,
|
|
UINT indexMenu,
|
|
UINT idCmdFirst,
|
|
UINT idCmdLast,
|
|
UINT uFlags
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL fSubscribed;
|
|
HMENU hChannelMenu, hChannelSubMenu;
|
|
|
|
ASSERT(hmenu);
|
|
ASSERT(idCmdFirst < idCmdLast);
|
|
|
|
if (!(CMF_DEFAULTONLY & uFlags))
|
|
{
|
|
if (NULL != m_pSubscriptionMgr)
|
|
{
|
|
ASSERT(idCmdFirst + IDM_SUBSCRIBE < idCmdLast);
|
|
|
|
#ifndef UNIX
|
|
if (CanSubscribe(m_bstrURL))
|
|
{
|
|
m_pSubscriptionMgr->IsSubscribed(m_bstrURL, &fSubscribed);
|
|
if (fSubscribed)
|
|
{
|
|
hChannelMenu = LoadMenu(MLGetHinst(),
|
|
MAKEINTRESOURCE(IDM_SUBSCRIBEDMENU));
|
|
|
|
if (SHRestricted2W(REST_NoRemovingSubscriptions, m_bstrURL, 0))
|
|
{
|
|
EnableMenuItem(hChannelMenu, IDM_SUBSCRIBE,
|
|
MF_BYCOMMAND | MF_GRAYED);
|
|
}
|
|
|
|
if (SHRestricted2W(REST_NoManualUpdates, m_bstrURL, 0))
|
|
{
|
|
EnableMenuItem(hChannelMenu, IDM_UPDATESUBSCRIPTION,
|
|
MF_BYCOMMAND | MF_GRAYED);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int idMenu = !SHRestricted2W(REST_NoAddingSubscriptions,
|
|
m_bstrURL, 0)
|
|
? IDM_UNSUBSCRIBEDMENU : IDM_NOSUBSCRIBEMENU;
|
|
|
|
hChannelMenu = LoadMenu(MLGetHinst(), MAKEINTRESOURCE(idMenu));
|
|
}
|
|
}
|
|
else
|
|
#endif /* !UNIX */
|
|
{
|
|
hChannelMenu = LoadMenu(MLGetHinst(),
|
|
MAKEINTRESOURCE(IDM_NOSUBSCRIBEMENU));
|
|
}
|
|
|
|
if (NULL != hChannelMenu)
|
|
{
|
|
hChannelSubMenu = GetSubMenu(hChannelMenu, 0);
|
|
|
|
if (NULL != hChannelSubMenu)
|
|
{
|
|
hr = Shell_MergeMenus(hmenu, hChannelSubMenu, indexMenu,
|
|
idCmdFirst, idCmdLast, MM_ADDSEPARATOR)
|
|
- idCmdFirst;
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
DestroyMenu(hChannelMenu);
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
|
|
RemoveMenuItems(hmenu);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
|
//
|
|
// *** CContextMenu::InvokeCommand ***
|
|
//
|
|
//
|
|
// Description:
|
|
// Carries out the command for the given menu item id.
|
|
//
|
|
// Parameters:
|
|
// [In] lpici - Structure containing the verb, hwnd, menu id, etc.
|
|
//
|
|
// Return:
|
|
// S_OK if the command was successful.
|
|
// E_FAIL otherwise.
|
|
//
|
|
// Comments:
|
|
//
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CChannelMenu::InvokeCommand(
|
|
LPCMINVOKECOMMANDINFO lpici
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
ASSERT(lpici);
|
|
|
|
if (HIWORD(lpici->lpVerb) == 0)
|
|
{
|
|
switch (LOWORD(lpici->lpVerb))
|
|
{
|
|
case IDM_UPDATESUBSCRIPTION:
|
|
ASSERT(NULL != m_pSubscriptionMgr);
|
|
m_pSubscriptionMgr->UpdateSubscription(m_bstrURL);
|
|
break;
|
|
|
|
case IDM_SUBSCRIBE:
|
|
ASSERT(NULL != m_pSubscriptionMgr);
|
|
ASSERT( sizeof(SUBSCRIPTIONINFO) == m_si.cbSize);
|
|
|
|
hr = Subscribe(lpici->hwnd);
|
|
break;
|
|
|
|
case IDM_UNSUBSCRIBE:
|
|
ASSERT(NULL != m_pSubscriptionMgr);
|
|
m_pSubscriptionMgr->DeleteSubscription(m_bstrURL, lpici->hwnd);
|
|
break;
|
|
|
|
case IDM_EDITSUBSCRIPTION:
|
|
ASSERT(NULL != m_pSubscriptionMgr);
|
|
m_pSubscriptionMgr->ShowSubscriptionProperties(m_bstrURL,
|
|
lpici->hwnd);
|
|
break;
|
|
|
|
case IDM_REFRESHCHANNEL:
|
|
Refresh(lpici->hwnd);
|
|
break;
|
|
|
|
case IDM_VIEWSOURCE:
|
|
ViewSource(lpici->hwnd);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
return hr;
|
|
}
|
|
|
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
|
//
|
|
// *** CContextMenu::GetCommandString ***
|
|
//
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Parameters:
|
|
//
|
|
//
|
|
// Return:
|
|
//
|
|
//
|
|
// Comments:
|
|
//
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CChannelMenu::GetCommandString(
|
|
UINT_PTR idCommand,
|
|
UINT uFLags,
|
|
UINT *pwReserved,
|
|
LPSTR pszName,
|
|
UINT cchMax
|
|
)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
STDMETHODIMP
|
|
CChannelMenu::Initialize(
|
|
LPCITEMIDLIST pidl,
|
|
LPDATAOBJECT pdobj,
|
|
HKEY hkey
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
STGMEDIUM stgmed;
|
|
FORMATETC fmtetc = {CF_HDROP, NULL, DVASPECT_CONTENT, -1,
|
|
TYMED_HGLOBAL};
|
|
|
|
ASSERT(pdobj);
|
|
|
|
hr = pdobj->GetData(&fmtetc, &stgmed);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (DragQueryFile((HDROP)stgmed.hGlobal, 0, m_szPath,
|
|
ARRAYSIZE(m_szPath)))
|
|
{
|
|
m_tt.cbTriggerSize = sizeof(TASK_TRIGGER);
|
|
m_si.cbSize = sizeof(SUBSCRIPTIONINFO);
|
|
m_si.fUpdateFlags |= SUBSINFO_SCHEDULE;
|
|
m_si.schedule = SUBSSCHED_AUTO;
|
|
m_si.pTrigger = &m_tt;
|
|
|
|
hr = GetNameAndURLAndSubscriptionInfo(m_szPath, &m_bstrName, &m_bstrURL,
|
|
&m_si);
|
|
|
|
ASSERT((SUCCEEDED(hr) && m_bstrName && m_bstrURL) || FAILED(hr));
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
ReleaseStgMedium(&stgmed);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = CoCreateInstance(CLSID_SubscriptionMgr, NULL,
|
|
CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr,
|
|
(void**)&m_pSubscriptionMgr);
|
|
}
|
|
}
|
|
// Return S_OK even if things didn't go as planned so that
|
|
// RemoveMenus will get called.
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//
|
|
// Helper functions
|
|
//
|
|
|
|
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
|
|
//
|
|
// *** Name ***
|
|
//
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Parameters:
|
|
//
|
|
//
|
|
// Return:
|
|
//
|
|
//
|
|
// Comments:
|
|
//
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
CChannelMenu::RemoveMenuItems(
|
|
HMENU hmenu
|
|
)
|
|
{
|
|
TCHAR aszRemove[4][62] = {{0}, {0}, {0}, {0}};
|
|
|
|
MLLoadString(IDS_SHARING, aszRemove[0], ARRAYSIZE(aszRemove[0]));
|
|
MLLoadString(IDS_RENAME, aszRemove[1], ARRAYSIZE(aszRemove[1]));
|
|
MLLoadString(IDS_SENDTO, aszRemove[2], ARRAYSIZE(aszRemove[2]));
|
|
|
|
if (SHRestricted2W(REST_NoEditingChannels, NULL, 0))
|
|
MLLoadString(IDS_PROPERTIES, aszRemove[3], ARRAYSIZE(aszRemove[3]));
|
|
|
|
TCHAR szBuffer[62];
|
|
MENUITEMINFO mii;
|
|
|
|
mii.cbSize = sizeof(MENUITEMINFO);
|
|
mii.fMask = MIIM_TYPE;
|
|
|
|
for (int i = GetMenuItemCount(hmenu) - 1; i >= 0; i--)
|
|
{
|
|
mii.dwTypeData = szBuffer;
|
|
mii.cch = ARRAYSIZE(szBuffer);
|
|
|
|
if (GetMenuItemInfo(hmenu, i, TRUE, &mii) && mii.cch)
|
|
{
|
|
for (int j = 0; j < ARRAYSIZE(aszRemove); j++)
|
|
{
|
|
if (StrEql(aszRemove[j], mii.dwTypeData))
|
|
{
|
|
DeleteMenu(hmenu, i, MF_BYPOSITION);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void CChannelMenu::Refresh(HWND hwnd)
|
|
{
|
|
IXMLDocument* pIXMLDocument;
|
|
|
|
DLL_ForcePreloadDlls(PRELOAD_MSXML);
|
|
|
|
HRESULT hr = CoCreateInstance(CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_IXMLDocument, (void**)&pIXMLDocument);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ASSERT(pIXMLDocument);
|
|
|
|
if (DownloadCdfUI(hwnd, m_bstrURL, pIXMLDocument))
|
|
{
|
|
UpdateImage(m_szPath);
|
|
SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH | SHCNF_FLUSH,
|
|
(void*)m_szPath, NULL);
|
|
}
|
|
|
|
pIXMLDocument->Release();
|
|
}
|
|
}
|
|
|
|
static TCHAR c_szFileProtocol[] = TEXT("file:");
|
|
static TCHAR c_szCDFExtension[] = TEXT(".cdf");
|
|
static TCHAR c_szShellEdit[] = TEXT("\\shell\\edit\\command");
|
|
static TCHAR c_szEditVerb[] = TEXT("edit");
|
|
static TCHAR c_szChannelFile[] = TEXT("ChannelFile");
|
|
static TCHAR c_szChannelFileEdit[] = TEXT("ChannelFile\\shell\\edit\\command");
|
|
static TCHAR c_szNotepad[] = TEXT("notepad.exe");
|
|
|
|
void CChannelMenu::ViewSource(HWND hwnd)
|
|
{
|
|
TCHAR szProgId[64] = TEXT("");
|
|
TCHAR szBuf[INTERNET_MAX_URL_LENGTH];
|
|
TCHAR szFile[MAX_PATH + 2]; // Leave room for quotes
|
|
DWORD cch, dwType;
|
|
SHELLEXECUTEINFO sei;
|
|
BOOL fFoundProg = FALSE;
|
|
HRESULT hr = S_OK;
|
|
|
|
TraceMsg(TF_OBJECTS, "+ IContextMenu ViewSource %ls", m_bstrURL);
|
|
|
|
if (SHUnicodeToTChar(m_bstrURL, szBuf, ARRAYSIZE(szBuf)))
|
|
{
|
|
if (SUCCEEDED(URLGetLocalFileName(szBuf, szFile, ARRAYSIZE(szFile),
|
|
NULL)))
|
|
{
|
|
if (StrCmpNI(szFile, c_szFileProtocol, 5) == 0)
|
|
{
|
|
ASSERT(ARRAYSIZE(szFile) < ARRAYSIZE(szBuf));
|
|
StrCpy(szBuf, szFile);
|
|
cch = ARRAYSIZE(szFile) - 2;
|
|
hr = PathCreateFromUrl(szBuf, szFile, &cch, 0);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
PathQuoteSpaces(szFile);
|
|
|
|
//
|
|
// We don't just call ShellExec with edit verb since
|
|
// who knows what the file extension will be.
|
|
//
|
|
cch = ARRAYSIZE(szProgId);
|
|
if (ERROR_SUCCESS == SHGetValue(HKEY_CLASSES_ROOT,
|
|
c_szCDFExtension,
|
|
NULL, &dwType,
|
|
szProgId, &cch)
|
|
)
|
|
{
|
|
ASSERT(ARRAYSIZE(szProgId) < ARRAYSIZE(szBuf));
|
|
StrCpy(szBuf, szProgId);
|
|
ASSERT(ARRAYSIZE(szProgId) + ARRAYSIZE(c_szShellEdit) <
|
|
ARRAYSIZE(szBuf));
|
|
StrCat(szBuf, c_szShellEdit);
|
|
cch = ARRAYSIZE(szBuf);
|
|
|
|
if (ERROR_SUCCESS == SHGetValue(HKEY_CLASSES_ROOT, szBuf,
|
|
NULL, &dwType, szBuf, &cch)
|
|
)
|
|
{
|
|
//
|
|
// Getting here means they have an edit verb for CDF files
|
|
//
|
|
fFoundProg = TRUE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// If we haven't found a class key yet and the CDF ProgID
|
|
// isn't ours, then fall back to our edit verb.
|
|
//
|
|
if (!fFoundProg && StrCmpI(szProgId, c_szChannelFile))
|
|
{
|
|
cch = ARRAYSIZE(szBuf);
|
|
if (ERROR_SUCCESS == SHGetValue(HKEY_CLASSES_ROOT,
|
|
c_szChannelFileEdit,
|
|
NULL, &dwType,
|
|
szBuf, &cch)
|
|
)
|
|
{
|
|
fFoundProg = TRUE;
|
|
ASSERT(ARRAYSIZE(c_szChannelFile) < ARRAYSIZE(szProgId));
|
|
StrCpy(szProgId, c_szChannelFile);
|
|
}
|
|
}
|
|
|
|
memset(&sei, 0, sizeof(sei));
|
|
sei.cbSize = sizeof(sei);
|
|
sei.hwnd = hwnd;
|
|
sei.nShow = SW_SHOW;
|
|
|
|
if (fFoundProg)
|
|
{
|
|
sei.fMask = SEE_MASK_CLASSNAME;
|
|
sei.lpVerb = c_szEditVerb;
|
|
sei.lpFile = szFile;
|
|
sei.lpClass = szProgId;
|
|
TraceMsg(TF_OBJECTS, "IContextMenu ViewSource progid=%s file=%s", szProgId, szFile);
|
|
}
|
|
else
|
|
{
|
|
sei.lpFile = c_szNotepad;
|
|
sei.lpParameters = szFile;
|
|
TraceMsg(TF_OBJECTS, "IContextMenu ViewSource Notepad file=%s", szFile);
|
|
}
|
|
|
|
#ifndef UNIX
|
|
ShellExecuteEx(&sei);
|
|
#else
|
|
unixInvokeEditor(szFile);
|
|
#endif /* UNIX */
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CDFMessageBox(hwnd, IDS_ERROR_NO_CACHE_ENTRY, IDS_ERROR_DLG_TITLE,
|
|
MB_OK | MB_ICONEXCLAMATION, szBuf);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TraceMsg(TF_OBJECTS, "IContextMenu ViewSource couldn't convert to TSTR");
|
|
}
|
|
TraceMsg(TF_OBJECTS, "- IContextMenu ViewSource");
|
|
}
|
|
|
|
|
|
HRESULT CChannelMenu::Subscribe(HWND hwnd)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CChannelMgr *pChannelMgr = new CChannelMgr;
|
|
|
|
if (pChannelMgr)
|
|
{
|
|
hr = pChannelMgr->AddAndSubscribeEx2(hwnd, m_bstrURL, m_pSubscriptionMgr, TRUE);
|
|
pChannelMgr->Release();
|
|
|
|
if (SUCCEEDED(hr) && (NULL != m_pSubscriptionMgr))
|
|
{
|
|
hr = m_pSubscriptionMgr->UpdateSubscription(m_bstrURL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|