mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 09:50:07 +00:00
[SHELLDESKTOP]
- Create a new sublibrary for shell32 that will contain the implementation of CDesktopBrowser and desktop dde support. Link it to both shell32 and rshell. Also add a win8+ hack. svn path=/trunk/; revision=68769
This commit is contained in:
parent
0cb0f1e091
commit
aa12df35cf
|
@ -18,11 +18,13 @@ set_module_type(rshell win32dll UNICODE)
|
||||||
|
|
||||||
target_link_libraries(rshell
|
target_link_libraries(rshell
|
||||||
shellmenu
|
shellmenu
|
||||||
|
shelldesktop
|
||||||
atlnew
|
atlnew
|
||||||
uuid
|
uuid
|
||||||
wine)
|
wine)
|
||||||
|
|
||||||
add_importlibs(rshell
|
add_importlibs(rshell
|
||||||
|
browseui
|
||||||
uxtheme
|
uxtheme
|
||||||
shlwapi
|
shlwapi
|
||||||
advapi32
|
advapi32
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "shellmenu.h"
|
#include "shellmenu.h"
|
||||||
|
|
||||||
|
extern "C"
|
||||||
HINSTANCE shell32_hInstance = NULL;
|
HINSTANCE shell32_hInstance = NULL;
|
||||||
|
|
||||||
DWORD WINAPI WinList_Init(void)
|
DWORD WINAPI WinList_Init(void)
|
||||||
|
|
|
@ -7,4 +7,6 @@
|
||||||
@ stdcall CMenuSite_Constructor(ptr ptr);
|
@ stdcall CMenuSite_Constructor(ptr ptr);
|
||||||
@ stdcall CMenuBand_Constructor(ptr ptr);
|
@ stdcall CMenuBand_Constructor(ptr ptr);
|
||||||
@ stdcall CMergedFolder_Constructor(ptr ptr);
|
@ stdcall CMergedFolder_Constructor(ptr ptr);
|
||||||
@ stdcall ShellDDEInit(long);
|
@ stdcall ShellDDEInit(long);
|
||||||
|
@ stdcall SHCreateDesktop(ptr);
|
||||||
|
@ stdcall SHDesktopMessageLoop(ptr);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
PROJECT(SHELL)
|
PROJECT(SHELL)
|
||||||
|
|
||||||
|
add_subdirectory(shelldesktop)
|
||||||
add_subdirectory(shellmenu)
|
add_subdirectory(shellmenu)
|
||||||
|
|
||||||
set_cpp(WITH_RUNTIME)
|
set_cpp(WITH_RUNTIME)
|
||||||
|
@ -20,9 +21,7 @@ include_directories(
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
CIDLDataObj.cpp
|
CIDLDataObj.cpp
|
||||||
CQueryAssociations.cpp
|
CQueryAssociations.cpp
|
||||||
dde.cpp
|
|
||||||
debughlp.cpp
|
debughlp.cpp
|
||||||
CDesktopBrowser.cpp
|
|
||||||
dialogs/dialogs.cpp
|
dialogs/dialogs.cpp
|
||||||
dialogs/drive.cpp
|
dialogs/drive.cpp
|
||||||
dialogs/drvdefext.cpp
|
dialogs/drvdefext.cpp
|
||||||
|
@ -82,7 +81,7 @@ add_library(shell32 SHARED
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/shell32.def)
|
${CMAKE_CURRENT_BINARY_DIR}/shell32.def)
|
||||||
|
|
||||||
set_module_type(shell32 win32dll UNICODE HOTPATCHABLE)
|
set_module_type(shell32 win32dll UNICODE HOTPATCHABLE)
|
||||||
target_link_libraries(shell32 shellmenu atlnew wine uuid recyclebin)
|
target_link_libraries(shell32 shellmenu shelldesktop atlnew wine uuid recyclebin)
|
||||||
add_delay_importlibs(shell32 uxtheme ole32 userenv version fmifs)
|
add_delay_importlibs(shell32 uxtheme ole32 userenv version fmifs)
|
||||||
add_importlibs(shell32 advapi32 browseui gdi32 user32 powrprof comctl32 comdlg32 shdocvw shlwapi devmgr winspool winmm msvcrt kernel32 ntdll)
|
add_importlibs(shell32 advapi32 browseui gdi32 user32 powrprof comctl32 comdlg32 shdocvw shlwapi devmgr winspool winmm msvcrt kernel32 ntdll)
|
||||||
add_pch(shell32 precomp.h SOURCE)
|
add_pch(shell32 precomp.h SOURCE)
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "shelldesktop.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(desktop);
|
WINE_DEFAULT_DEBUG_CHANNEL(desktop);
|
||||||
|
|
||||||
|
@ -210,6 +210,12 @@ BOOL CDesktopBrowser::CreateDeskWnd()
|
||||||
|
|
||||||
SetShellWindowEx(hWnd, FindDesktopListView());
|
SetShellWindowEx(hWnd, FindDesktopListView());
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
/* A Windows8+ specific hack */
|
||||||
|
::ShowWindow(hWndShellView, SW_SHOW);
|
||||||
|
::ShowWindow(FindDesktopListView(), SW_SHOW);
|
||||||
|
#endif
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "shelldesktop.h"
|
||||||
#include <ddeml.h>
|
#include <ddeml.h>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
|
|
|
@ -1,566 +0,0 @@
|
||||||
/*
|
|
||||||
* Shell Desktop
|
|
||||||
*
|
|
||||||
* Copyright 2008 Thomas Bluemel
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "shellmenu.h"
|
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(desktop);
|
|
||||||
|
|
||||||
#define SHDESK_TAG 'KSED'
|
|
||||||
|
|
||||||
static const WCHAR szProgmanClassName [] = L"Progman";
|
|
||||||
static const WCHAR szProgmanWindowName [] = L"Program Manager";
|
|
||||||
|
|
||||||
class CDesktopBrowser :
|
|
||||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
|
||||||
public IShellBrowser,
|
|
||||||
public ICommDlgBrowser,
|
|
||||||
public IServiceProvider
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DWORD Tag;
|
|
||||||
private:
|
|
||||||
HWND hWnd;
|
|
||||||
HWND hWndShellView;
|
|
||||||
HWND hWndDesktopListView;
|
|
||||||
CComPtr<IShellDesktopTray> ShellDesk;
|
|
||||||
CComPtr<IShellView> DesktopView;
|
|
||||||
IShellBrowser *DefaultShellBrowser;
|
|
||||||
LPITEMIDLIST pidlDesktopDirectory;
|
|
||||||
LPITEMIDLIST pidlDesktop;
|
|
||||||
public:
|
|
||||||
CDesktopBrowser();
|
|
||||||
~CDesktopBrowser();
|
|
||||||
HRESULT Initialize(HWND hWndx, IShellDesktopTray *ShellDeskx);
|
|
||||||
HWND FindDesktopListView();
|
|
||||||
BOOL CreateDeskWnd();
|
|
||||||
HWND DesktopGetWindowControl(IN UINT id);
|
|
||||||
static LRESULT CALLBACK ProgmanWindowProc(IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam);
|
|
||||||
static BOOL MessageLoop();
|
|
||||||
|
|
||||||
// *** IOleWindow methods ***
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
|
|
||||||
|
|
||||||
// *** IShellBrowser methods ***
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE RemoveMenusSB(HMENU hmenuShared);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetStatusTextSB(LPCOLESTR pszStatusText);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE EnableModelessSB(BOOL fEnable);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorSB(MSG *pmsg, WORD wID);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE BrowseObject(LPCITEMIDLIST pidl, UINT wFlags);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE GetViewStateStream(DWORD grfMode, IStream **ppStrm);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE GetControlWindow(UINT id, HWND *lphwnd);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE QueryActiveShellView(struct IShellView **ppshv);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE OnViewWindowActive(struct IShellView *ppshv);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags);
|
|
||||||
|
|
||||||
// *** ICommDlgBrowser methods ***
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE OnDefaultCommand(struct IShellView *ppshv);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE OnStateChange(struct IShellView *ppshv, ULONG uChange);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE IncludeObject(struct IShellView *ppshv, LPCITEMIDLIST pidl);
|
|
||||||
|
|
||||||
// *** IServiceProvider methods ***
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
|
|
||||||
|
|
||||||
BEGIN_COM_MAP(CDesktopBrowser)
|
|
||||||
COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
|
|
||||||
COM_INTERFACE_ENTRY_IID(IID_IShellBrowser, IShellBrowser)
|
|
||||||
COM_INTERFACE_ENTRY_IID(IID_ICommDlgBrowser, ICommDlgBrowser)
|
|
||||||
COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
|
|
||||||
END_COM_MAP()
|
|
||||||
};
|
|
||||||
|
|
||||||
CDesktopBrowser::CDesktopBrowser()
|
|
||||||
{
|
|
||||||
Tag = SHDESK_TAG;
|
|
||||||
hWnd = NULL;
|
|
||||||
hWndShellView = NULL;
|
|
||||||
hWndDesktopListView = NULL;
|
|
||||||
DefaultShellBrowser = NULL;
|
|
||||||
pidlDesktopDirectory = NULL;
|
|
||||||
pidlDesktop = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
CDesktopBrowser::~CDesktopBrowser()
|
|
||||||
{
|
|
||||||
if (DesktopView.p != NULL)
|
|
||||||
{
|
|
||||||
if (hWndShellView != NULL)
|
|
||||||
DesktopView->DestroyViewWindow();
|
|
||||||
|
|
||||||
hWndShellView = NULL;
|
|
||||||
hWndDesktopListView = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pidlDesktopDirectory != NULL)
|
|
||||||
{
|
|
||||||
ILFree(pidlDesktopDirectory);
|
|
||||||
pidlDesktopDirectory = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pidlDesktop != NULL)
|
|
||||||
{
|
|
||||||
ILFree(pidlDesktop);
|
|
||||||
pidlDesktop = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CDesktopBrowser::Initialize(HWND hWndx, IShellDesktopTray *ShellDeskx)
|
|
||||||
{
|
|
||||||
CComPtr<IShellFolder> psfDesktopFolder;
|
|
||||||
CSFV csfv;
|
|
||||||
HRESULT hRet;
|
|
||||||
|
|
||||||
hWnd = hWndx;
|
|
||||||
ShellDesk = ShellDeskx;
|
|
||||||
ShellDesk->AddRef();
|
|
||||||
|
|
||||||
pidlDesktopDirectory = SHCloneSpecialIDList(hWnd, CSIDL_DESKTOPDIRECTORY, FALSE);
|
|
||||||
hRet = SHGetSpecialFolderLocation(hWnd, CSIDL_DESKTOP, &pidlDesktop);
|
|
||||||
if (FAILED(hRet))
|
|
||||||
return hRet;
|
|
||||||
|
|
||||||
hRet = SHGetDesktopFolder(&psfDesktopFolder);
|
|
||||||
if (FAILED(hRet))
|
|
||||||
return hRet;
|
|
||||||
|
|
||||||
ZeroMemory(&csfv, sizeof(csfv));
|
|
||||||
csfv.cbSize = sizeof(csfv);
|
|
||||||
csfv.pshf = psfDesktopFolder;
|
|
||||||
csfv.psvOuter = NULL;
|
|
||||||
|
|
||||||
hRet = SHCreateShellFolderViewEx(&csfv, &DesktopView);
|
|
||||||
|
|
||||||
return hRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CDesktopBrowser *SHDESK_Create(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
|
|
||||||
{
|
|
||||||
IShellDesktopTray *ShellDesk;
|
|
||||||
CComObject<CDesktopBrowser> *pThis;
|
|
||||||
HRESULT hRet;
|
|
||||||
|
|
||||||
ShellDesk = static_cast<IShellDesktopTray *>(lpCreateStruct->lpCreateParams);
|
|
||||||
if (ShellDesk == NULL)
|
|
||||||
{
|
|
||||||
WARN("No IShellDesk interface provided!");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pThis = new CComObject<CDesktopBrowser>;
|
|
||||||
if (pThis == NULL)
|
|
||||||
return NULL;
|
|
||||||
pThis->AddRef();
|
|
||||||
|
|
||||||
hRet = pThis->Initialize(hWnd, ShellDesk);
|
|
||||||
if (FAILED(hRet))
|
|
||||||
{
|
|
||||||
pThis->Release();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pThis;
|
|
||||||
}
|
|
||||||
|
|
||||||
HWND CDesktopBrowser::FindDesktopListView()
|
|
||||||
{
|
|
||||||
return FindWindowExW(hWndShellView, NULL, WC_LISTVIEW, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CDesktopBrowser::CreateDeskWnd()
|
|
||||||
{
|
|
||||||
FOLDERSETTINGS fs;
|
|
||||||
RECT rcClient;
|
|
||||||
HRESULT hRet;
|
|
||||||
|
|
||||||
if (!GetClientRect(hWnd, &rcClient))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.ViewMode = FVM_ICON;
|
|
||||||
fs.fFlags = FWF_DESKTOP | FWF_NOCLIENTEDGE | FWF_NOSCROLL | FWF_TRANSPARENT;
|
|
||||||
hRet = DesktopView->CreateViewWindow(NULL, &fs, static_cast<IShellBrowser *>(this), &rcClient, &hWndShellView);
|
|
||||||
if (!SUCCEEDED(hRet))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
SetShellWindowEx(hWnd, FindDesktopListView());
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
/* A windows 8 specific hack */
|
|
||||||
::ShowWindow(hWndShellView, SW_SHOW);
|
|
||||||
::ShowWindow(FindDesktopListView(), SW_SHOW);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetWindow(HWND *phwnd)
|
|
||||||
{
|
|
||||||
if (hWnd != NULL)
|
|
||||||
{
|
|
||||||
*phwnd = hWnd;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
*phwnd = NULL;
|
|
||||||
return E_UNEXPECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::ContextSensitiveHelp(BOOL fEnterMode)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::RemoveMenusSB(HMENU hmenuShared)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetStatusTextSB(LPCOLESTR lpszStatusText)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::EnableModelessSB(BOOL fEnable)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::TranslateAcceleratorSB(LPMSG lpmsg, WORD wID)
|
|
||||||
{
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef HRESULT(WINAPI *SH_OPEN_NEW_FRAME)(LPITEMIDLIST pidl, IUnknown *paramC, long param10, long param14);
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::BrowseObject(LPCITEMIDLIST pidl, UINT wFlags)
|
|
||||||
{
|
|
||||||
/* FIXME: Implement executing filebrowser.exe and somehow pass the pidl to it */
|
|
||||||
|
|
||||||
/* Returning failure here will make windows 7 and 8 to use the default file browser */
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetViewStateStream(DWORD grfMode, IStream **ppStrm)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HWND CDesktopBrowser::DesktopGetWindowControl(IN UINT id)
|
|
||||||
{
|
|
||||||
switch (id)
|
|
||||||
{
|
|
||||||
case FCW_TOOLBAR:
|
|
||||||
case FCW_STATUS:
|
|
||||||
case FCW_TREE:
|
|
||||||
case FCW_PROGRESS:
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetControlWindow(UINT id, HWND *lphwnd)
|
|
||||||
{
|
|
||||||
HWND hWnd;
|
|
||||||
|
|
||||||
hWnd = DesktopGetWindowControl(id);
|
|
||||||
if (hWnd != NULL)
|
|
||||||
{
|
|
||||||
*lphwnd = hWnd;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
*lphwnd = NULL;
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret)
|
|
||||||
{
|
|
||||||
HWND hWnd;
|
|
||||||
|
|
||||||
if (pret == NULL)
|
|
||||||
return E_POINTER;
|
|
||||||
|
|
||||||
hWnd = DesktopGetWindowControl(id);
|
|
||||||
if (hWnd != NULL)
|
|
||||||
{
|
|
||||||
*pret = SendMessageW(hWnd, uMsg, wParam, lParam);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryActiveShellView(IShellView **ppshv)
|
|
||||||
{
|
|
||||||
*ppshv = DesktopView;
|
|
||||||
if (DesktopView != NULL)
|
|
||||||
DesktopView->AddRef();
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnViewWindowActive(IShellView *ppshv)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnDefaultCommand(IShellView *ppshv)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnStateChange(IShellView *ppshv, ULONG uChange)
|
|
||||||
{
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::IncludeObject(IShellView *ppshv, LPCITEMIDLIST pidl)
|
|
||||||
{
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryService(REFGUID guidService, REFIID riid, PVOID *ppv)
|
|
||||||
{
|
|
||||||
/* FIXME - handle guidService */
|
|
||||||
return QueryInterface(riid, ppv);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CDesktopBrowser::MessageLoop()
|
|
||||||
{
|
|
||||||
MSG Msg;
|
|
||||||
BOOL bRet;
|
|
||||||
|
|
||||||
while ((bRet = GetMessageW(&Msg, NULL, 0, 0)) != 0)
|
|
||||||
{
|
|
||||||
if (bRet != -1)
|
|
||||||
{
|
|
||||||
TranslateMessage(&Msg);
|
|
||||||
DispatchMessageW(&Msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT CALLBACK CDesktopBrowser::ProgmanWindowProc(IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
|
|
||||||
{
|
|
||||||
CDesktopBrowser *pThis = NULL;
|
|
||||||
LRESULT Ret = FALSE;
|
|
||||||
|
|
||||||
if (uMsg != WM_NCCREATE)
|
|
||||||
{
|
|
||||||
pThis = reinterpret_cast<CDesktopBrowser*>(GetWindowLongPtrW(hwnd, 0));
|
|
||||||
if (pThis == NULL)
|
|
||||||
goto DefMsgHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pThis != NULL || uMsg == WM_NCCREATE)
|
|
||||||
{
|
|
||||||
switch (uMsg)
|
|
||||||
{
|
|
||||||
case WM_ERASEBKGND:
|
|
||||||
return (LRESULT) PaintDesktop(reinterpret_cast<HDC>(wParam));
|
|
||||||
|
|
||||||
case WM_GETISHELLBROWSER:
|
|
||||||
Ret = reinterpret_cast<LRESULT>(static_cast<IShellBrowser *>(pThis));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_SIZE:
|
|
||||||
if (wParam == SIZE_MINIMIZED)
|
|
||||||
{
|
|
||||||
/* Hey, we're the desktop!!! */
|
|
||||||
ShowWindow(hwnd,
|
|
||||||
SW_RESTORE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
/* FIXME: Update work area */
|
|
||||||
#if 0
|
|
||||||
RECT rcDesktop;
|
|
||||||
|
|
||||||
rcDesktop.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
|
||||||
rcDesktop.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
|
||||||
rcDesktop.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
|
||||||
rcDesktop.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_SYSCOLORCHANGE:
|
|
||||||
case WM_SETTINGCHANGE:
|
|
||||||
{
|
|
||||||
if (uMsg == WM_SYSCOLORCHANGE || wParam == SPI_SETDESKWALLPAPER || wParam == 0)
|
|
||||||
{
|
|
||||||
if (pThis->hWndShellView != NULL)
|
|
||||||
{
|
|
||||||
/* Forward the message */
|
|
||||||
SendMessageW(pThis->hWndShellView,
|
|
||||||
uMsg,
|
|
||||||
wParam,
|
|
||||||
lParam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WM_CREATE:
|
|
||||||
{
|
|
||||||
pThis->ShellDesk->RegisterDesktopWindow(pThis->hWnd);
|
|
||||||
|
|
||||||
if (!pThis->CreateDeskWnd())
|
|
||||||
WARN("Could not create the desktop view control!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WM_NCCREATE:
|
|
||||||
{
|
|
||||||
LPCREATESTRUCT CreateStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
|
|
||||||
pThis = SHDESK_Create(hwnd, CreateStruct);
|
|
||||||
if (pThis == NULL)
|
|
||||||
{
|
|
||||||
WARN("Failed to create desktop structure\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetWindowLongPtrW(hwnd,
|
|
||||||
0,
|
|
||||||
reinterpret_cast<LONG_PTR>(pThis));
|
|
||||||
Ret = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WM_NCDESTROY:
|
|
||||||
{
|
|
||||||
pThis->Release();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
DefMsgHandler :
|
|
||||||
Ret = DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL
|
|
||||||
RegisterProgmanWindowClass(VOID)
|
|
||||||
{
|
|
||||||
WNDCLASSW wcProgman;
|
|
||||||
|
|
||||||
wcProgman.style = CS_DBLCLKS;
|
|
||||||
wcProgman.lpfnWndProc = CDesktopBrowser::ProgmanWindowProc;
|
|
||||||
wcProgman.cbClsExtra = 0;
|
|
||||||
wcProgman.cbWndExtra = sizeof(CDesktopBrowser *);
|
|
||||||
wcProgman.hInstance = shell32_hInstance;
|
|
||||||
wcProgman.hIcon = NULL;
|
|
||||||
wcProgman.hCursor = LoadCursorW(NULL, IDC_ARROW);
|
|
||||||
wcProgman.hbrBackground = NULL;
|
|
||||||
wcProgman.lpszMenuName = NULL;
|
|
||||||
wcProgman.lpszClassName = szProgmanClassName;
|
|
||||||
|
|
||||||
return RegisterClassW(&wcProgman) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
* SHCreateDesktop [SHELL32.200]
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
HANDLE WINAPI SHCreateDesktop(IShellDesktopTray *ShellDesk)
|
|
||||||
{
|
|
||||||
HWND hWndDesk;
|
|
||||||
RECT rcDesk;
|
|
||||||
|
|
||||||
if (ShellDesk == NULL)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RegisterProgmanWindowClass() == 0)
|
|
||||||
{
|
|
||||||
WARN("Failed to register the Progman window class!\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
rcDesk.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
|
||||||
rcDesk.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
|
||||||
rcDesk.right = rcDesk.left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
|
||||||
rcDesk.bottom = rcDesk.top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
|
||||||
|
|
||||||
if (IsRectEmpty(&rcDesk))
|
|
||||||
{
|
|
||||||
rcDesk.left = rcDesk.top = 0;
|
|
||||||
rcDesk.right = GetSystemMetrics(SM_CXSCREEN);
|
|
||||||
rcDesk.bottom = GetSystemMetrics(SM_CYSCREEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
hWndDesk = CreateWindowExW(WS_EX_TOOLWINDOW, szProgmanClassName, szProgmanWindowName,
|
|
||||||
WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
|
||||||
rcDesk.left, rcDesk.top, rcDesk.right, rcDesk.bottom,
|
|
||||||
NULL, NULL, shell32_hInstance, reinterpret_cast<LPVOID>(ShellDesk));
|
|
||||||
if (hWndDesk != NULL)
|
|
||||||
return (HANDLE) GetWindowLongPtrW(hWndDesk, 0);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
* SHCreateDesktop [SHELL32.201]
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
BOOL WINAPI SHDesktopMessageLoop(HANDLE hDesktop)
|
|
||||||
{
|
|
||||||
CDesktopBrowser *Desk = reinterpret_cast<CDesktopBrowser *>(hDesktop);
|
|
||||||
|
|
||||||
if (Desk == NULL || Desk->Tag != SHDESK_TAG)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Desk->MessageLoop();
|
|
||||||
}
|
|
|
@ -8,14 +8,12 @@ include_directories(${REACTOS_SOURCE_DIR}/lib/atl)
|
||||||
|
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
CBandSite.cpp
|
CBandSite.cpp
|
||||||
CDesktopBrowser.cpp
|
|
||||||
CMenuBand.cpp
|
CMenuBand.cpp
|
||||||
CMenuDeskBar.cpp
|
CMenuDeskBar.cpp
|
||||||
CMenuFocusManager.cpp
|
CMenuFocusManager.cpp
|
||||||
CMenuSite.cpp
|
CMenuSite.cpp
|
||||||
CMenuToolbars.cpp
|
CMenuToolbars.cpp
|
||||||
CMergedFolder.cpp
|
CMergedFolder.cpp
|
||||||
CStartMenu.cpp
|
CStartMenu.cpp)
|
||||||
ShellDDE.cpp)
|
|
||||||
|
|
||||||
add_library(shellmenu ${SOURCE})
|
add_library(shellmenu ${SOURCE})
|
||||||
|
|
|
@ -1,411 +0,0 @@
|
||||||
/*
|
|
||||||
* Shell DDE Handling
|
|
||||||
*
|
|
||||||
* Copyright 2004 Robert Shearman
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "shellmenu.h"
|
|
||||||
#include <ddeml.h>
|
|
||||||
#include <strsafe.h>
|
|
||||||
#include <shlwapi_undoc.h>
|
|
||||||
|
|
||||||
/* WARNING: Although this is a functional implementation of the DDE parsing, the handlers are not implemented here.
|
|
||||||
The actual working implementation is in shell32 instead. */
|
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(shelldde);
|
|
||||||
|
|
||||||
typedef DWORD(CALLBACK * pfnCommandHandler)(PWSTR strCommand, PWSTR strPath, LPITEMIDLIST pidl, INT unkS);
|
|
||||||
|
|
||||||
struct DDECommandHandler
|
|
||||||
{
|
|
||||||
WCHAR Command[32];
|
|
||||||
pfnCommandHandler Handler;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern DDECommandHandler HandlerList [];
|
|
||||||
extern const int HandlerListLength;
|
|
||||||
|
|
||||||
/* DDE Instance ID */
|
|
||||||
static DWORD dwDDEInst;
|
|
||||||
|
|
||||||
/* String handles */
|
|
||||||
static HSZ hszProgmanTopic;
|
|
||||||
static HSZ hszProgmanService;
|
|
||||||
static HSZ hszShell;
|
|
||||||
static HSZ hszAppProperties;
|
|
||||||
static HSZ hszFolders;
|
|
||||||
|
|
||||||
static BOOL bInitialized;
|
|
||||||
|
|
||||||
static BOOL Dde_OnConnect(HSZ hszTopic, HSZ hszService)
|
|
||||||
{
|
|
||||||
WCHAR szTopic[MAX_PATH];
|
|
||||||
WCHAR szService[MAX_PATH];
|
|
||||||
|
|
||||||
DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE);
|
|
||||||
DdeQueryStringW(dwDDEInst, hszService, szService, _countof(szService), CP_WINUNICODE);
|
|
||||||
|
|
||||||
TRACE("Dde_OnConnect: topic=%S, service=%S\n", szTopic, szService);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Dde_OnConnectConfirm(HCONV hconv, HSZ hszTopic, HSZ hszService)
|
|
||||||
{
|
|
||||||
WCHAR szTopic[MAX_PATH];
|
|
||||||
WCHAR szService[MAX_PATH];
|
|
||||||
|
|
||||||
DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE);
|
|
||||||
DdeQueryStringW(dwDDEInst, hszService, szService, _countof(szService), CP_WINUNICODE);
|
|
||||||
|
|
||||||
TRACE("Dde_OnConnectConfirm: hconv=%p, topic=%S, service=%S\n", hconv, szTopic, szService);
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL Dde_OnWildConnect(HSZ hszTopic, HSZ hszService)
|
|
||||||
{
|
|
||||||
WCHAR szTopic[MAX_PATH];
|
|
||||||
WCHAR szService[MAX_PATH];
|
|
||||||
|
|
||||||
DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE);
|
|
||||||
DdeQueryStringW(dwDDEInst, hszService, szService, _countof(szService), CP_WINUNICODE);
|
|
||||||
|
|
||||||
TRACE("Dde_OnWildConnect: topic=%S, service=%S\n", szTopic, szService);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HDDEDATA Dde_OnRequest(UINT uFmt, HCONV hconv, HSZ hszTopic, HSZ hszItem)
|
|
||||||
{
|
|
||||||
WCHAR szTopic[MAX_PATH];
|
|
||||||
WCHAR szItem[MAX_PATH];
|
|
||||||
|
|
||||||
DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE);
|
|
||||||
DdeQueryStringW(dwDDEInst, hszItem, szItem, _countof(szItem), CP_WINUNICODE);
|
|
||||||
|
|
||||||
TRACE("Dde_OnRequest: uFmt=%d, hconv=%p, topic=%S, item=%S\n", hconv, szTopic, szItem);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static LPITEMIDLIST _ILReadFromSharedMemory(PCWSTR strField)
|
|
||||||
{
|
|
||||||
LPITEMIDLIST ret = NULL;
|
|
||||||
|
|
||||||
// Ensure it really is an IDLIST-formatted parameter
|
|
||||||
// Format for IDLIST params: ":pid:shared"
|
|
||||||
if (*strField != L':')
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
HANDLE hData = (HANDLE) StrToIntW(strField + 1);
|
|
||||||
PWSTR strSecond = StrChrW(strField + 1, L':');
|
|
||||||
|
|
||||||
if (strSecond)
|
|
||||||
{
|
|
||||||
int pid = StrToIntW(strSecond + 1);
|
|
||||||
void* pvShared = SHLockShared(hData, pid);
|
|
||||||
if (pvShared)
|
|
||||||
{
|
|
||||||
ret = ILClone((LPCITEMIDLIST) pvShared);
|
|
||||||
SHUnlockShared(pvShared);
|
|
||||||
SHFreeShared(hData, pid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DWORD Dde_OnExecute(HCONV hconv, HSZ hszTopic, HDDEDATA hdata)
|
|
||||||
{
|
|
||||||
WCHAR szTopic[MAX_PATH];
|
|
||||||
WCHAR szCommand[MAX_PATH];
|
|
||||||
WCHAR *pszCommand;
|
|
||||||
|
|
||||||
DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE);
|
|
||||||
|
|
||||||
pszCommand = (WCHAR*) DdeAccessData(hdata, NULL);
|
|
||||||
if (!pszCommand)
|
|
||||||
return DDE_FNOTPROCESSED;
|
|
||||||
|
|
||||||
StringCchCopyW(szCommand, _countof(szCommand), pszCommand);
|
|
||||||
|
|
||||||
DdeUnaccessData(hdata);
|
|
||||||
|
|
||||||
TRACE("Dde_OnExecute: hconv=%p, topic=%S, command=%S\n", hconv, szTopic, pszCommand);
|
|
||||||
|
|
||||||
/*
|
|
||||||
[ViewFolder("%l", %I, %S)] -- Open a folder in standard mode
|
|
||||||
[ExploreFolder("%l", %I, %S)] -- Open a folder in "explore" mode (file tree is shown to the left by default)
|
|
||||||
[FindFolder("%l", %I)] -- Open a folder in "find" mode (search panel is shown to the left by default)
|
|
||||||
[ShellFile("%1","%1",%S)] -- Execute the contents of the specified .SCF file
|
|
||||||
|
|
||||||
Approximate grammar (Upper names define rules, <lower> names define terminals, single-quotes are literals):
|
|
||||||
|
|
||||||
Rules
|
|
||||||
Command = ('[' Function ']') | Function
|
|
||||||
Function = <identifier> '(' Parameters ')'
|
|
||||||
Parameters = (<quoted-string> (',' <idlist> (',' <number>)?)?)?
|
|
||||||
|
|
||||||
Terminals
|
|
||||||
<identifier> = [a-zA-Z]+
|
|
||||||
<quoted-string> = \"([^\"]|\\.)\"
|
|
||||||
<idlist> = \:[0-9]+\:[0-9]+
|
|
||||||
<number> = [0-9]+
|
|
||||||
*/
|
|
||||||
|
|
||||||
WCHAR Command[MAX_PATH] = L"";
|
|
||||||
WCHAR Path[MAX_PATH] = L"";
|
|
||||||
LPITEMIDLIST IdList = NULL;
|
|
||||||
INT UnknownParameter = 0;
|
|
||||||
|
|
||||||
// Simplified parsing (assumes the command will not be TOO broken):
|
|
||||||
|
|
||||||
PWSTR cmd = szCommand;
|
|
||||||
// 1. if starts with [, skip first char
|
|
||||||
if (*cmd == L'[')
|
|
||||||
cmd++;
|
|
||||||
|
|
||||||
if (*cmd == L']')
|
|
||||||
{
|
|
||||||
ERR("Empty command. Nothing to run.\n");
|
|
||||||
return DDE_FNOTPROCESSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read until first (, and take text before ( as command name
|
|
||||||
{
|
|
||||||
PWSTR cmdEnd = StrChrW(cmd, L'(');
|
|
||||||
|
|
||||||
if (!cmdEnd)
|
|
||||||
{
|
|
||||||
ERR("Could not find '('. Invalid command.\n");
|
|
||||||
return DDE_FNOTPROCESSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
*cmdEnd = 0;
|
|
||||||
|
|
||||||
StringCchCopy(Command, _countof(Command), cmd);
|
|
||||||
|
|
||||||
cmd = cmdEnd + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read first param after (, expecting quoted string
|
|
||||||
if (*cmd != L')')
|
|
||||||
{
|
|
||||||
// Copy unescaped string
|
|
||||||
PWSTR dst = Path;
|
|
||||||
BOOL isQuote = FALSE;
|
|
||||||
|
|
||||||
PWSTR arg = cmd;
|
|
||||||
|
|
||||||
while (*arg && (isQuote || *arg != L','))
|
|
||||||
{
|
|
||||||
if (*arg == L'"')
|
|
||||||
{
|
|
||||||
isQuote = !isQuote;
|
|
||||||
if (isQuote && arg != cmd) // do not copy the " at the beginning of the string
|
|
||||||
{
|
|
||||||
*(dst++) = L'"';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*(dst++) = *arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
arg++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd = arg + 1;
|
|
||||||
|
|
||||||
while (*cmd == L' ')
|
|
||||||
cmd++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read second param, expecting an idlist in shared memory
|
|
||||||
if (*cmd != L')')
|
|
||||||
{
|
|
||||||
if (*cmd != ':')
|
|
||||||
{
|
|
||||||
ERR("Expected ':'. Invalid command.\n");
|
|
||||||
return DDE_FNOTPROCESSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
PWSTR idlistEnd = StrChrW(cmd, L',');
|
|
||||||
|
|
||||||
if (!idlistEnd)
|
|
||||||
idlistEnd = StrChrW(cmd, L')');
|
|
||||||
|
|
||||||
if (!idlistEnd)
|
|
||||||
{
|
|
||||||
ERR("Expected ',' or ')'. Invalid command.\n");
|
|
||||||
return DDE_FNOTPROCESSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
IdList = _ILReadFromSharedMemory(cmd);
|
|
||||||
|
|
||||||
cmd = idlistEnd + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read third param, expecting an integer
|
|
||||||
if (*cmd != L')')
|
|
||||||
{
|
|
||||||
UnknownParameter = StrToIntW(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("Parse end: cmd=%S, S=%d, pidl=%p, path=%S\n", Command, UnknownParameter, IdList, Path);
|
|
||||||
|
|
||||||
// Find handler in list
|
|
||||||
for (int i = 0; i < HandlerListLength; i++)
|
|
||||||
{
|
|
||||||
DDECommandHandler & handler = HandlerList[i];
|
|
||||||
if (StrCmpW(handler.Command, Command) == 0)
|
|
||||||
{
|
|
||||||
return handler.Handler(Command, Path, IdList, UnknownParameter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No handler found
|
|
||||||
ERR("Unknown command %S\n", Command);
|
|
||||||
return DDE_FNOTPROCESSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Dde_OnDisconnect(HCONV hconv)
|
|
||||||
{
|
|
||||||
TRACE("Dde_OnDisconnect: hconv=%p\n", hconv);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HDDEDATA CALLBACK DdeCallback(
|
|
||||||
UINT uType,
|
|
||||||
UINT uFmt,
|
|
||||||
HCONV hconv,
|
|
||||||
HSZ hsz1,
|
|
||||||
HSZ hsz2,
|
|
||||||
HDDEDATA hdata,
|
|
||||||
ULONG_PTR dwData1,
|
|
||||||
ULONG_PTR dwData2)
|
|
||||||
{
|
|
||||||
switch (uType)
|
|
||||||
{
|
|
||||||
case XTYP_CONNECT:
|
|
||||||
return (HDDEDATA) (DWORD_PTR) Dde_OnConnect(hsz1, hsz2);
|
|
||||||
case XTYP_CONNECT_CONFIRM:
|
|
||||||
Dde_OnConnectConfirm(hconv, hsz1, hsz2);
|
|
||||||
return NULL;
|
|
||||||
case XTYP_WILDCONNECT:
|
|
||||||
return (HDDEDATA) (DWORD_PTR) Dde_OnWildConnect(hsz1, hsz2);
|
|
||||||
case XTYP_REQUEST:
|
|
||||||
return Dde_OnRequest(uFmt, hconv, hsz1, hsz2);
|
|
||||||
case XTYP_EXECUTE:
|
|
||||||
return (HDDEDATA) (DWORD_PTR) Dde_OnExecute(hconv, hsz1, hdata);
|
|
||||||
case XTYP_DISCONNECT:
|
|
||||||
Dde_OnDisconnect(hconv);
|
|
||||||
return NULL;
|
|
||||||
case XTYP_REGISTER:
|
|
||||||
return NULL;
|
|
||||||
default:
|
|
||||||
TRACE("DdeCallback: unknown uType=%d\n", uType);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*************************************************************************
|
|
||||||
* ShellDDEInit (SHELL32.@)
|
|
||||||
*
|
|
||||||
* Registers the Shell DDE services with the system so that applications
|
|
||||||
* can use them.
|
|
||||||
*
|
|
||||||
* PARAMS
|
|
||||||
* bInit [I] TRUE to initialize the services, FALSE to uninitialize.
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
* Nothing.
|
|
||||||
*/
|
|
||||||
EXTERN_C void WINAPI ShellDDEInit(BOOL bInit)
|
|
||||||
{
|
|
||||||
TRACE("ShellDDEInit bInit = %s\n", bInit ? "TRUE" : "FALSE");
|
|
||||||
|
|
||||||
if (bInit && !bInitialized)
|
|
||||||
{
|
|
||||||
DdeInitializeW(&dwDDEInst, DdeCallback, CBF_FAIL_ADVISES | CBF_FAIL_POKES, 0);
|
|
||||||
|
|
||||||
hszProgmanTopic = DdeCreateStringHandleW(dwDDEInst, L"Progman", CP_WINUNICODE);
|
|
||||||
hszProgmanService = DdeCreateStringHandleW(dwDDEInst, L"Progman", CP_WINUNICODE);
|
|
||||||
hszShell = DdeCreateStringHandleW(dwDDEInst, L"Shell", CP_WINUNICODE);
|
|
||||||
hszAppProperties = DdeCreateStringHandleW(dwDDEInst, L"AppProperties", CP_WINUNICODE);
|
|
||||||
hszFolders = DdeCreateStringHandleW(dwDDEInst, L"Folders", CP_WINUNICODE);
|
|
||||||
|
|
||||||
if (hszProgmanTopic && hszProgmanService &&
|
|
||||||
hszShell && hszAppProperties && hszFolders &&
|
|
||||||
DdeNameService(dwDDEInst, hszFolders, 0, DNS_REGISTER) &&
|
|
||||||
DdeNameService(dwDDEInst, hszProgmanService, 0, DNS_REGISTER) &&
|
|
||||||
DdeNameService(dwDDEInst, hszShell, 0, DNS_REGISTER))
|
|
||||||
{
|
|
||||||
bInitialized = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!bInit && bInitialized)
|
|
||||||
{
|
|
||||||
/* unregister all services */
|
|
||||||
DdeNameService(dwDDEInst, 0, 0, DNS_UNREGISTER);
|
|
||||||
|
|
||||||
if (hszFolders)
|
|
||||||
DdeFreeStringHandle(dwDDEInst, hszFolders);
|
|
||||||
if (hszAppProperties)
|
|
||||||
DdeFreeStringHandle(dwDDEInst, hszAppProperties);
|
|
||||||
if (hszShell)
|
|
||||||
DdeFreeStringHandle(dwDDEInst, hszShell);
|
|
||||||
if (hszProgmanService)
|
|
||||||
DdeFreeStringHandle(dwDDEInst, hszProgmanService);
|
|
||||||
if (hszProgmanTopic)
|
|
||||||
DdeFreeStringHandle(dwDDEInst, hszProgmanTopic);
|
|
||||||
|
|
||||||
DdeUninitialize(dwDDEInst);
|
|
||||||
|
|
||||||
bInitialized = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static DWORD CALLBACK DDE_OnViewFolder(PWSTR strCommand, PWSTR strPath, LPITEMIDLIST pidl, INT unkS)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
return DDE_FACK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DWORD CALLBACK DDW_OnExploreFolder(PWSTR strCommand, PWSTR strPath, LPITEMIDLIST pidl, INT unkS)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
return DDE_FACK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DWORD CALLBACK DDE_OnFindFolder(PWSTR strCommand, PWSTR strPath, LPITEMIDLIST pidl, INT unkS)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
return DDE_FNOTPROCESSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DWORD CALLBACK DDE_OnShellFile(PWSTR strCommand, PWSTR strPath, LPITEMIDLIST pidl, INT unkS)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
return DDE_FNOTPROCESSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
DDECommandHandler HandlerList [] = {
|
|
||||||
|
|
||||||
{ L"ViewFolder", DDE_OnViewFolder },
|
|
||||||
{ L"ExploreFolder", DDW_OnExploreFolder },
|
|
||||||
{ L"FindFolder", DDE_OnFindFolder },
|
|
||||||
{ L"ShellFile", DDE_OnShellFile }
|
|
||||||
};
|
|
||||||
|
|
||||||
const int HandlerListLength = _countof(HandlerList);
|
|
|
@ -69,8 +69,6 @@
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern HINSTANCE shell32_hInstance;
|
|
||||||
|
|
||||||
extern "C" HRESULT WINAPI CStartMenu_Constructor(REFIID riid, void **ppv);
|
extern "C" HRESULT WINAPI CStartMenu_Constructor(REFIID riid, void **ppv);
|
||||||
extern "C" HRESULT WINAPI CMenuDeskBar_Constructor(REFIID riid, LPVOID *ppv);
|
extern "C" HRESULT WINAPI CMenuDeskBar_Constructor(REFIID riid, LPVOID *ppv);
|
||||||
extern "C" HRESULT WINAPI CMenuSite_Constructor(REFIID riid, LPVOID *ppv);
|
extern "C" HRESULT WINAPI CMenuSite_Constructor(REFIID riid, LPVOID *ppv);
|
||||||
|
|
Loading…
Reference in a new issue