[SHELL32]

- CDesktopBrowser: Convert to an ATL CWindow class, remove unused fields and cleanup.

svn path=/trunk/; revision=72099
This commit is contained in:
Giannis Adamopoulos 2016-08-03 15:52:27 +00:00
parent cdc269d16b
commit 0d767aa90b

View file

@ -22,42 +22,27 @@
WINE_DEFAULT_DEBUG_CHANNEL(desktop); WINE_DEFAULT_DEBUG_CHANNEL(desktop);
#define SHDESK_TAG 'KSED'
static const WCHAR szProgmanClassName[] = L"Progman"; static const WCHAR szProgmanClassName[] = L"Progman";
static const WCHAR szProgmanWindowName[] = L"Program Manager"; static const WCHAR szProgmanWindowName[] = L"Program Manager";
class CDesktopBrowser : class CDesktopBrowser :
public CWindowImpl<CDesktopBrowser, CWindow, CFrameWinTraits>,
public CComObjectRootEx<CComMultiThreadModelNoCS>, public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellBrowser, public IShellBrowser,
public ICommDlgBrowser,
public IServiceProvider public IServiceProvider
{ {
public:
DWORD Tag;
HACCEL m_hAccel;
private: private:
HWND hWnd; HACCEL m_hAccel;
HWND hWndShellView; HWND m_hWndShellView;
HWND hWndDesktopListView; // FIXME: Unused CComPtr<IShellDesktopTray> m_Tray;
CComPtr<IShellDesktopTray> ShellDesk; CComPtr<IShellView> m_ShellView;
CComPtr<IShellView> DesktopView;
CComPtr<IShellBrowser> DefaultShellBrowser;
LPITEMIDLIST pidlDesktopDirectory;
LPITEMIDLIST pidlDesktop;
LRESULT _NotifyTray(UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT _NotifyTray(UINT uMsg, WPARAM wParam, LPARAM lParam);
public: public:
CDesktopBrowser(); CDesktopBrowser();
~CDesktopBrowser(); ~CDesktopBrowser();
HRESULT Initialize(HWND hWndx, IShellDesktopTray *ShellDeskx); HRESULT Initialize(IShellDesktopTray *ShellDeskx);
HWND FindDesktopListView();
BOOL CreateDeskWnd();
HWND DesktopGetWindowControl(IN UINT id);
LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK ProgmanWindowProc(IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam);
BOOL MessageLoop();
// *** IOleWindow methods *** // *** IOleWindow methods ***
virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd); virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
@ -78,128 +63,96 @@ public:
virtual HRESULT STDMETHODCALLTYPE OnViewWindowActive(struct IShellView *ppshv); virtual HRESULT STDMETHODCALLTYPE OnViewWindowActive(struct IShellView *ppshv);
virtual HRESULT STDMETHODCALLTYPE SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags); 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 *** // *** IServiceProvider methods ***
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject); virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
// message handlers
LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnOpenNewWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
DECLARE_WND_CLASS_EX(szProgmanClassName, CS_DBLCLKS, COLOR_DESKTOP)
BEGIN_MSG_MAP(CBaseBar)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
MESSAGE_HANDLER(WM_SIZE, OnSize)
MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSettingChange)
MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
MESSAGE_HANDLER(WM_CLOSE, OnClose)
MESSAGE_HANDLER(WM_EXPLORER_OPEN_NEW_WINDOW, OnOpenNewWindow)
MESSAGE_HANDLER(WM_COMMAND, OnCommand)
MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
END_MSG_MAP()
BEGIN_COM_MAP(CDesktopBrowser) BEGIN_COM_MAP(CDesktopBrowser)
COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
COM_INTERFACE_ENTRY_IID(IID_IShellBrowser, IShellBrowser) COM_INTERFACE_ENTRY_IID(IID_IShellBrowser, IShellBrowser)
COM_INTERFACE_ENTRY_IID(IID_ICommDlgBrowser, ICommDlgBrowser)
COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider) COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
END_COM_MAP() END_COM_MAP()
}; };
CDesktopBrowser::CDesktopBrowser() CDesktopBrowser::CDesktopBrowser():
m_hWndShellView(NULL),
m_hAccel(NULL)
{ {
Tag = SHDESK_TAG;
hWnd = NULL;
hWndShellView = NULL;
hWndDesktopListView = NULL;
DefaultShellBrowser = NULL;
pidlDesktopDirectory = NULL;
pidlDesktop = NULL;
} }
CDesktopBrowser::~CDesktopBrowser() CDesktopBrowser::~CDesktopBrowser()
{ {
if (DesktopView.p != NULL) if (m_ShellView.p != NULL && m_hWndShellView != NULL)
{ {
if (hWndShellView != NULL) m_ShellView->DestroyViewWindow();
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) HRESULT CDesktopBrowser::Initialize(IShellDesktopTray *ShellDesk)
{ {
CComPtr<IShellFolder> psfDesktopFolder; CComPtr<IShellFolder> psfDesktop;
CSFV csfv;
HRESULT hRet; HRESULT hRet;
hRet = SHGetDesktopFolder(&psfDesktop);
hWnd = hWndx; if (FAILED_UNEXPECTEDLY(hRet))
ShellDesk = ShellDeskx;
ShellDesk->AddRef();
pidlDesktopDirectory = SHCloneSpecialIDList(hWnd, CSIDL_DESKTOPDIRECTORY, FALSE);
hRet = SHGetSpecialFolderLocation(hWnd, CSIDL_DESKTOP, &pidlDesktop);
if (FAILED(hRet))
return hRet; return hRet;
hRet = SHGetDesktopFolder(&psfDesktopFolder); /* Calculate the size and pos of the window */
if (FAILED(hRet)) RECT rect;
if (!GetSystemMetrics(SM_CXVIRTUALSCREEN) || GetSystemMetrics(SM_CYVIRTUALSCREEN))
{
SetRect(&rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
}
else
{
SetRect(&rect,
GetSystemMetrics(SM_XVIRTUALSCREEN),
GetSystemMetrics(SM_YVIRTUALSCREEN),
GetSystemMetrics(SM_XVIRTUALSCREEN) + GetSystemMetrics(SM_CXVIRTUALSCREEN),
GetSystemMetrics(SM_YVIRTUALSCREEN) + GetSystemMetrics(SM_CYVIRTUALSCREEN));
}
m_Tray = ShellDesk;
Create(NULL, &rect, szProgmanWindowName, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_TOOLWINDOW);
if (!m_hWnd)
return E_FAIL;
CSFV csfv = {sizeof(CSFV), psfDesktop};
hRet = SHCreateShellFolderViewEx(&csfv, &m_ShellView);
if (FAILED_UNEXPECTEDLY(hRet))
return hRet; return hRet;
ZeroMemory(&csfv, sizeof(csfv)); m_Tray->RegisterDesktopWindow(m_hWnd);
csfv.cbSize = sizeof(csfv); if (FAILED_UNEXPECTEDLY(hRet))
csfv.pshf = psfDesktopFolder; return hRet;
csfv.psvOuter = NULL;
hRet = SHCreateShellFolderViewEx(&csfv, &DesktopView);
return hRet;
}
static CDesktopBrowser *SHDESK_Create(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
CComPtr<IShellDesktopTray> ShellDesk;
CComObject<CDesktopBrowser> *pThis;
HRESULT hRet;
ShellDesk = (IShellDesktopTray *)lpCreateStruct->lpCreateParams;
if (ShellDesk == NULL)
{
WARN("No IShellDesk interface provided!");
return NULL;
}
pThis = new CComObject<CDesktopBrowser>;
pThis->AddRef();
hRet = pThis->Initialize(hWnd, ShellDesk);
if (FAILED(hRet))
{
pThis->Release();
delete pThis;
return NULL;
}
return pThis;
}
HWND CDesktopBrowser::FindDesktopListView()
{
return FindWindowExW(hWndShellView, NULL, WC_LISTVIEW, NULL);
}
BOOL CDesktopBrowser::CreateDeskWnd()
{
FOLDERSETTINGS fs; FOLDERSETTINGS fs;
RECT rcWorkArea; RECT rcWorkArea;
HRESULT hRet;
// FIXME: Add support for multi-monitor? // FIXME: Add support for multi-monitor?
SystemParametersInfoW(SPI_GETWORKAREA, SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcWorkArea, 0);
0, &rcWorkArea, 0);
// TODO: Call GetClientRect for the tray window and make small computation // TODO: Call GetClientRect for the tray window and make small computation
// to be sure the tray window rect is removed from the work area! // to be sure the tray window rect is removed from the work area!
@ -208,38 +161,39 @@ BOOL CDesktopBrowser::CreateDeskWnd()
HWND hWndTray; HWND hWndTray;
/* Get client rect of the taskbar */ /* Get client rect of the taskbar */
hRet = ShellDesk->GetTrayWindow(&hWndTray); hRet = m_Tray->GetTrayWindow(&hWndTray);
if (SUCCEEDED(hRet)) if (SUCCEEDED(hRet))
GetClientRect(hWndTray, &rcTray); GetClientRect(hWndTray, &rcTray);
#endif #endif
fs.ViewMode = FVM_ICON; fs.ViewMode = FVM_ICON;
fs.fFlags = FWF_DESKTOP | FWF_NOCLIENTEDGE | FWF_NOSCROLL | FWF_TRANSPARENT; fs.fFlags = FWF_DESKTOP | FWF_NOCLIENTEDGE | FWF_NOSCROLL | FWF_TRANSPARENT;
hRet = DesktopView->CreateViewWindow(NULL, &fs, (IShellBrowser *)this, &rcWorkArea, &hWndShellView); hRet = m_ShellView->CreateViewWindow(NULL, &fs, (IShellBrowser *)this, &rcWorkArea, &m_hWndShellView);
if (!SUCCEEDED(hRet)) if (FAILED_UNEXPECTEDLY(hRet))
return FALSE; return hRet;
SetShellWindowEx(hWnd, FindDesktopListView()); HWND hwndListView = FindWindowExW(m_hWndShellView, NULL, WC_LISTVIEW, NULL);
SetShellWindowEx(m_hWnd, hwndListView);
m_hAccel = LoadAcceleratorsW(shell32_hInstance, MAKEINTRESOURCEW(IDA_DESKBROWSER));
#if 1 #if 1
/* A Windows8+ specific hack */ /* A Windows8+ specific hack */
::ShowWindow(hWndShellView, SW_SHOW); ::ShowWindow(m_hWndShellView, SW_SHOW);
::ShowWindow(FindDesktopListView(), SW_SHOW); ::ShowWindow(hwndListView, SW_SHOW);
#endif #endif
ShowWindow(SW_SHOW);
UpdateWindow();
return TRUE; return hRet;
} }
HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetWindow(HWND *phwnd) HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetWindow(HWND *lphwnd)
{ {
if (hWnd != NULL) if (lphwnd == NULL)
{ return E_POINTER;
*phwnd = hWnd; *lphwnd = m_hWnd;
return S_OK; return S_OK;
}
*phwnd = NULL;
return E_UNEXPECTED;
} }
HRESULT STDMETHODCALLTYPE CDesktopBrowser::ContextSensitiveHelp(BOOL fEnterMode) HRESULT STDMETHODCALLTYPE CDesktopBrowser::ContextSensitiveHelp(BOOL fEnterMode)
@ -274,7 +228,7 @@ HRESULT STDMETHODCALLTYPE CDesktopBrowser::EnableModelessSB(BOOL fEnable)
HRESULT STDMETHODCALLTYPE CDesktopBrowser::TranslateAcceleratorSB(LPMSG lpmsg, WORD wID) HRESULT STDMETHODCALLTYPE CDesktopBrowser::TranslateAcceleratorSB(LPMSG lpmsg, WORD wID)
{ {
if (!::TranslateAcceleratorW(hWnd, m_hAccel, lpmsg)) if (!::TranslateAcceleratorW(m_hWnd, m_hAccel, lpmsg))
return S_FALSE; return S_FALSE;
return S_OK; return S_OK;
} }
@ -294,62 +248,27 @@ HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetViewStateStream(DWORD grfMode, ISt
return E_NOTIMPL; 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) HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetControlWindow(UINT id, HWND *lphwnd)
{ {
HWND hWnd; if (lphwnd == NULL)
return E_POINTER;
hWnd = DesktopGetWindowControl(id);
if (hWnd != NULL)
{
*lphwnd = hWnd;
return S_OK;
}
*lphwnd = NULL;
return E_NOTIMPL; return E_NOTIMPL;
} }
HRESULT STDMETHODCALLTYPE CDesktopBrowser::SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret) HRESULT STDMETHODCALLTYPE CDesktopBrowser::SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret)
{ {
HWND hWnd;
if (pret == NULL) if (pret == NULL)
return E_POINTER; return E_POINTER;
hWnd = DesktopGetWindowControl(id);
if (hWnd != NULL)
{
*pret = SendMessageW(hWnd,
uMsg,
wParam,
lParam);
return S_OK;
}
return E_NOTIMPL; return E_NOTIMPL;
} }
HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryActiveShellView(IShellView **ppshv) HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryActiveShellView(IShellView **ppshv)
{ {
*ppshv = DesktopView; if (ppshv == NULL)
if (DesktopView != NULL) return E_POINTER;
DesktopView->AddRef(); *ppshv = m_ShellView;
if (m_ShellView != NULL)
m_ShellView->AddRef();
return S_OK; return S_OK;
} }
@ -364,61 +283,25 @@ HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetToolbarItems(LPTBBUTTON lpButtons,
return E_NOTIMPL; 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) HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryService(REFGUID guidService, REFIID riid, PVOID *ppv)
{ {
/* FIXME - handle guidService */ /* FIXME - handle guidService */
return QueryInterface(riid, ppv); return QueryInterface(riid, ppv);
} }
BOOL CDesktopBrowser::MessageLoop()
{
MSG Msg;
BOOL bRet;
while ((bRet = GetMessageW(&Msg, NULL, 0, 0)) != 0)
{
if (bRet != -1)
{
if (DesktopView->TranslateAcceleratorW(&Msg) != S_OK)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
}
return TRUE;
}
LRESULT CDesktopBrowser::_NotifyTray(UINT uMsg, WPARAM wParam, LPARAM lParam) LRESULT CDesktopBrowser::_NotifyTray(UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
HWND hWndTray; HWND hWndTray;
HRESULT hRet; HRESULT hRet;
hRet = ShellDesk->GetTrayWindow(&hWndTray); hRet = m_Tray->GetTrayWindow(&hWndTray);
if (SUCCEEDED(hRet)) if (SUCCEEDED(hRet))
PostMessageW(hWndTray, uMsg, wParam, lParam); ::PostMessageW(hWndTray, uMsg, wParam, lParam);
return 0; return 0;
} }
LRESULT CDesktopBrowser::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam) LRESULT CDesktopBrowser::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{ {
switch (LOWORD(wParam)) switch (LOWORD(wParam))
{ {
@ -439,217 +322,102 @@ LRESULT CDesktopBrowser::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam)
return 0; return 0;
} }
LRESULT CALLBACK CDesktopBrowser::ProgmanWindowProc(IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
LRESULT CDesktopBrowser::OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{ {
CDesktopBrowser *pThis = NULL; return (LRESULT)PaintDesktop((HDC)wParam);
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((HDC)wParam);
case WM_GETISHELLBROWSER:
Ret = (LRESULT)((IShellBrowser *)pThis);
break;
case WM_SIZE:
{
if (wParam == SIZE_MINIMIZED)
{
/* Hey, we're the desktop!!! */
ShowWindow(hwnd, SW_RESTORE);
}
else
{
RECT rcDesktop;
rcDesktop.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
rcDesktop.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
rcDesktop.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
rcDesktop.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
/* FIXME: Update work area */
DBG_UNREFERENCED_LOCAL_VARIABLE(rcDesktop);
}
break;
}
case WM_SYSCOLORCHANGE:
case WM_SETTINGCHANGE:
{
if (pThis->hWndShellView != NULL)
{
/* Forward the message */
SendMessageW(pThis->hWndShellView,
uMsg,
wParam,
lParam);
}
if (uMsg == WM_SETTINGCHANGE && wParam == SPI_SETWORKAREA &&
pThis->hWndShellView != NULL)
{
RECT rcWorkArea;
// FIXME: Add support for multi-monitor!
// FIXME: Maybe merge with the code that retrieves the
// work area in CDesktopBrowser::CreateDeskWnd ?
SystemParametersInfoW(SPI_GETWORKAREA,
0, &rcWorkArea, 0);
SetWindowPos(pThis->hWndShellView, NULL,
rcWorkArea.left, rcWorkArea.top,
rcWorkArea.right - rcWorkArea.left,
rcWorkArea.bottom - rcWorkArea.top,
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER);
}
break;
}
case WM_CREATE:
{
pThis->ShellDesk->RegisterDesktopWindow(pThis->hWnd);
if (!pThis->CreateDeskWnd())
WARN("Could not create the desktop view control!\n");
pThis->m_hAccel = LoadAcceleratorsW(shell32_hInstance, MAKEINTRESOURCEW(IDA_DESKBROWSER));
break;
}
case WM_NCCREATE:
{
LPCREATESTRUCT CreateStruct = (LPCREATESTRUCT)lParam;
// FIXME: This is a "hack" to enforce the window title
// to be set to what it should be *on Windows* only.
// I don't understand why it is reset to NULL whereas
// the creation of the progman window proper is done in
// the standard way... (05/06/2016, hbelusca).
//
::SetWindowTextW(hwnd, CreateStruct->lpszName);
pThis = SHDESK_Create(hwnd, CreateStruct);
if (pThis == NULL)
{
WARN("Failed to create desktop structure\n");
break;
}
SetWindowLongPtrW(hwnd, 0, (LONG_PTR)pThis);
Ret = TRUE;
break;
}
case WM_NCDESTROY:
{
pThis->Release();
break;
}
case WM_CLOSE:
return pThis->_NotifyTray(TWM_DOEXITWINDOWS, 0, 0);
case WM_EXPLORER_OPEN_NEW_WINDOW:
TRACE("Proxy Desktop message 1035 received.\n");
SHOnCWMCommandLine((HANDLE)lParam);
break;
case WM_COMMAND:
return pThis->OnCommand(uMsg, wParam, lParam);
case WM_SETFOCUS:
SetFocus(pThis->hWndShellView);
break;
default:
DefMsgHandler:
Ret = DefWindowProcW(hwnd, uMsg, wParam, lParam);
break;
}
}
return Ret;
} }
static BOOL LRESULT CDesktopBrowser::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
RegisterProgmanWindowClass(VOID)
{ {
WNDCLASSW wcProgman; if (wParam == SIZE_MINIMIZED)
{
/* Hey, we're the desktop!!! */
::ShowWindow(m_hWnd, SW_RESTORE);
}
else
{
RECT rcDesktop;
rcDesktop.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
rcDesktop.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
rcDesktop.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
rcDesktop.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
wcProgman.style = CS_DBLCLKS; /* FIXME: Update work area */
wcProgman.lpfnWndProc = CDesktopBrowser::ProgmanWindowProc; DBG_UNREFERENCED_LOCAL_VARIABLE(rcDesktop);
wcProgman.cbClsExtra = 0; }
wcProgman.cbWndExtra = sizeof(CDesktopBrowser *);
wcProgman.hInstance = shell32_hInstance; return 0;
wcProgman.hIcon = NULL;
wcProgman.hCursor = LoadCursorW(NULL, IDC_ARROW);
wcProgman.hbrBackground = (HBRUSH)(COLOR_DESKTOP + 1);
wcProgman.lpszMenuName = NULL;
wcProgman.lpszClassName = szProgmanClassName;
return RegisterClassW(&wcProgman) != 0;
} }
LRESULT CDesktopBrowser::OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
if (m_hWndShellView)
{
/* Forward the message */
SendMessageW(m_hWndShellView, uMsg, wParam, lParam);
}
if (uMsg == WM_SETTINGCHANGE && wParam == SPI_SETWORKAREA &&
m_hWndShellView != NULL)
{
RECT rcWorkArea;
// FIXME: Add support for multi-monitor!
// FIXME: Maybe merge with the code that retrieves the
// work area in CDesktopBrowser::CreateDeskWnd ?
SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcWorkArea, 0);
::SetWindowPos(m_hWndShellView, NULL,
rcWorkArea.left, rcWorkArea.top,
rcWorkArea.right - rcWorkArea.left,
rcWorkArea.bottom - rcWorkArea.top,
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER);
}
return 0;
}
LRESULT CDesktopBrowser::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
return _NotifyTray(TWM_DOEXITWINDOWS, 0, 0);
}
LRESULT CDesktopBrowser::OnOpenNewWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
TRACE("Proxy Desktop message 1035 received.\n");
SHOnCWMCommandLine((HANDLE)lParam);
return 0;
}
LRESULT CDesktopBrowser::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
::SetFocus(m_hWndShellView);
return 0;
}
HRESULT CDesktopBrowser_CreateInstance(IShellDesktopTray *Tray, REFIID riid, void **ppv)
{
return ShellObjectCreatorInit<CDesktopBrowser, IShellDesktopTray*>(Tray, riid, ppv);
}
/************************************************************************* /*************************************************************************
* SHCreateDesktop [SHELL32.200] * SHCreateDesktop [SHELL32.200]
* *
*/ */
HANDLE WINAPI SHCreateDesktop(IShellDesktopTray *ShellDesk) HANDLE WINAPI SHCreateDesktop(IShellDesktopTray *Tray)
{ {
HWND hWndDesk; if (Tray == NULL)
int x, y, cx, cy;
if (ShellDesk == NULL)
{ {
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
return NULL; return NULL;
} }
if (RegisterProgmanWindowClass() == 0) CComPtr<IShellBrowser> Browser;
{ HRESULT hr = CDesktopBrowser_CreateInstance(Tray, IID_PPV_ARG(IShellBrowser, &Browser));
WARN("Failed to register the Progman window class!\n"); if (FAILED_UNEXPECTEDLY(hr))
return NULL; return NULL;
}
x = GetSystemMetrics(SM_XVIRTUALSCREEN); return static_cast<HANDLE>(Browser.Detach());
y = GetSystemMetrics(SM_YVIRTUALSCREEN);
cx = GetSystemMetrics(SM_CXVIRTUALSCREEN);
cy = GetSystemMetrics(SM_CYVIRTUALSCREEN);
if (!cx || !cy)
{
x = y = 0;
cx = GetSystemMetrics(SM_CXSCREEN);
cy = GetSystemMetrics(SM_CYSCREEN);
}
hWndDesk = ::CreateWindowExW(WS_EX_TOOLWINDOW, szProgmanClassName, szProgmanWindowName,
WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
x, y, cx, cy,
NULL, NULL, shell32_hInstance, (LPVOID)ShellDesk);
if (hWndDesk != NULL)
{
::ShowWindow(hWndDesk, SW_SHOW);
::UpdateWindow(hWndDesk);
return (HANDLE)GetWindowLongPtrW(hWndDesk, 0);
}
return NULL;
} }
/************************************************************************* /*************************************************************************
@ -658,13 +426,34 @@ HANDLE WINAPI SHCreateDesktop(IShellDesktopTray *ShellDesk)
*/ */
BOOL WINAPI SHDesktopMessageLoop(HANDLE hDesktop) BOOL WINAPI SHDesktopMessageLoop(HANDLE hDesktop)
{ {
CDesktopBrowser *Desk = static_cast<CDesktopBrowser *>(hDesktop); if (hDesktop == NULL)
if (Desk == NULL || Desk->Tag != SHDESK_TAG)
{ {
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
return Desk->MessageLoop(); MSG Msg;
BOOL bRet;
CComPtr<IShellBrowser> browser;
CComPtr<IShellView> shellView;
browser.Attach(static_cast<IShellBrowser*>(hDesktop));
HRESULT hr = browser->QueryActiveShellView(&shellView);
if (FAILED_UNEXPECTEDLY(hr))
return FALSE;
while ((bRet = GetMessageW(&Msg, NULL, 0, 0)) != 0)
{
if (bRet != -1)
{
if (shellView->TranslateAcceleratorW(&Msg) != S_OK)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
}
return TRUE;
} }