Files
reactos/reactos/subsys/system/explorer/desktop/desktop.cpp
T
2003-09-28 19:51:05 +00:00

290 lines
7.0 KiB
C++

/*
* Copyright 2003 Martin Fuchs
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// Explorer clone
//
// desktop.cpp
//
// Martin Fuchs, 09.08.2003
//
#include "../utility/utility.h"
#include "../utility/shellclasses.h"
#include "../utility/shellbrowserimpl.h"
#include "../utility/window.h"
#include "desktop.h"
#include "../taskbar/desktopbar.h"
#include "../shell/mainframe.h" // for MainFrame::Create()
#include "../externals.h"
#include "../explorer_intres.h"
static BOOL (WINAPI*SetShellWindow)(HWND);
static BOOL (WINAPI*SetShellWindowEx)(HWND, HWND);
BOOL IsAnyDesktopRunning()
{
HINSTANCE shell32 = GetModuleHandle(_T("user32"));
SetShellWindow = (BOOL(WINAPI*)(HWND)) GetProcAddress(shell32, "SetShellWindow");
SetShellWindowEx = (BOOL(WINAPI*)(HWND,HWND)) GetProcAddress(shell32, "SetShellWindowEx");
return GetShellWindow() != 0;
}
static void draw_desktop_background(HWND hwnd, HDC hdc)
{
ClientRect rect(hwnd);
PaintDesktop(hdc);
/*
HBRUSH bkgndBrush = CreateSolidBrush(RGB(0,32,160)); // dark blue
FillRect(hdc, &rect, bkgndBrush);
DeleteBrush(bkgndBrush);
*/
rect.left = rect.right - 280;
rect.top = rect.bottom - 56 - DESKTOPBARBAR_HEIGHT;
rect.right = rect.left + 250;
rect.bottom = rect.top + 40;
#include "../buildno.h"
static const LPCTSTR BkgndText = _T("ReactOS ")_T(KERNEL_VERSION_STR)_T(" Explorer\nby Martin Fuchs");
BkMode bkMode(hdc, TRANSPARENT);
TextColor textColor(hdc, RGB(128,128,192));
DrawText(hdc, BkgndText, -1, &rect, DT_RIGHT);
SetTextColor(hdc, RGB(255,255,255));
--rect.right;
++rect.top;
DrawText(hdc, BkgndText, -1, &rect, DT_RIGHT);
}
LRESULT BackgroundWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
{
switch(nmsg) {
case WM_ERASEBKGND:
PaintDesktop((HDC)wparam);
return TRUE;
case WM_MBUTTONDBLCLK:
explorer_show_frame(_hwnd, SW_SHOWNORMAL);
break;
default:
return super::WndProc(nmsg, wparam, lparam);
}
return 0;
}
DesktopWindow::DesktopWindow(HWND hwnd)
: super(hwnd)
{
_pShellView = NULL;
}
DesktopWindow::~DesktopWindow()
{
if (_pShellView)
_pShellView->Release();
}
HWND DesktopWindow::Create()
{
IconWindowClass wcDesktop(_T("Progman"), IDI_REACTOS, CS_DBLCLKS);
wcDesktop.hbrBackground = (HBRUSH)(COLOR_BACKGROUND+1);
int width = GetSystemMetrics(SM_CXSCREEN);
int height = GetSystemMetrics(SM_CYSCREEN);
HWND hwndDesktop = Window::Create(WINDOW_CREATOR(DesktopWindow),
WS_EX_TOOLWINDOW, wcDesktop, _T("Program Manager"), WS_POPUP|WS_VISIBLE|WS_CLIPCHILDREN,
0, 0, width, height, 0);
// work around to display desktop bar in Wine
ShowWindow(GET_WINDOW(DesktopWindow, hwndDesktop)->_desktopBar, SW_SHOW);
// work around for Windows NT, Win 98, ...
// Without this the desktop has mysteriously only a size of 800x600 pixels.
MoveWindow(hwndDesktop, 0, 0, width, height, TRUE);
return hwndDesktop;
}
LRESULT DesktopWindow::Init(LPCREATESTRUCT pcs)
{
if (super::Init(pcs))
return 1;
HRESULT hr = Desktop()->CreateViewObject(_hwnd, IID_IShellView, (void**)&_pShellView);
/* also possible:
SFV_CREATE sfv_create;
sfv_create.cbSize = sizeof(SFV_CREATE);
sfv_create.pshf = Desktop();
sfv_create.psvOuter = NULL;
sfv_create.psfvcb = NULL;
HRESULT hr = SHCreateShellFolderView(&sfv_create, &_pShellView);
*/
HWND hWndView = 0;
if (SUCCEEDED(hr)) {
FOLDERSETTINGS fs;
fs.ViewMode = FVM_ICON;
fs.fFlags = FWF_DESKTOP|FWF_NOCLIENTEDGE|FWF_NOSCROLL|FWF_BESTFITWINDOW|FWF_SNAPTOGRID;
ClientRect rect(_hwnd);
hr = _pShellView->CreateViewWindow(NULL, &fs, this, &rect, &hWndView);
//TODO: use IShellBrowser::GetViewStateStream() to restore previous view state -> see SHOpenRegStream()
if (SUCCEEDED(hr)) {
_pShellView->UIActivate(SVUIA_ACTIVATE_FOCUS);
/*
IShellView2* pShellView2;
hr = _pShellView->QueryInterface(IID_IShellView2, (void**)&pShellView2);
SV2CVW2_PARAMS params;
params.cbSize = sizeof(SV2CVW2_PARAMS);
params.psvPrev = _pShellView;
params.pfs = &fs;
params.psbOwner = this;
params.prcView = ▭
params.pvid = params.pvid;//@@
hr = pShellView2->CreateViewWindow2(&params);
params.pvid;
*/
/*
IFolderView* pFolderView;
hr = _pShellView->QueryInterface(IID_IFolderView, (void**)&pFolderView);
if (SUCCEEDED(hr)) {
hr = pFolderView->GetAutoArrange();
hr = pFolderView->SetCurrentViewMode(FVM_DETAILS);
}
*/
HWND hwndFolderView = ::GetNextWindow(hWndView, GW_CHILD);
// work around for Windows NT, Win 98, ...
// Without this the desktop has mysteriously only a size of 800x600 pixels.
MoveWindow(hwndFolderView, 0, 0, rect.right, rect.bottom, TRUE);
new BackgroundWindow(hwndFolderView);
}
}
if (hWndView && SetShellWindowEx)
SetShellWindowEx(_hwnd, hWndView);
else if (SetShellWindow)
SetShellWindow(_hwnd);
// create the explorer bar
_desktopBar = DesktopBar::Create();
return 0;
}
LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
{
switch(nmsg) {
case WM_PAINT:
draw_desktop_background(_hwnd, PaintCanvas(_hwnd));
break;
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
explorer_show_frame(_hwnd, SW_SHOWNORMAL);
break;
case WM_GETISHELLBROWSER:
return (LRESULT)static_cast<IShellBrowser*>(this);
case WM_DESTROY:
//TODO: use IShellBrowser::GetViewStateStream() and _pShellView->SaveViewState() to store view state
if (SetShellWindow)
SetShellWindow(0);
break;
case WM_CLOSE:
break; // Over-ride close. We need to close desktop some other way.
case WM_SYSCOMMAND:
if (wparam == SC_TASKLIST) {
if (_desktopBar)
SendMessage(_desktopBar, nmsg, wparam, lparam);
}
goto def;
default: def:
return super::WndProc(nmsg, wparam, lparam);
}
return 0;
}
HRESULT DesktopWindow::OnDefaultCommand(LPIDA pIDList)
{
HRESULT ret = E_NOTIMPL;
int cnt = pIDList->cidl;
for(int i=0; ++i<=cnt; ) {
/* We know, the parent folder is the desktop, so we do not need to look at pIDList->aoffset[0]
UINT folderOffset = pIDList->aoffset[0];
LPITEMIDLIST pidlFolder = (LPITEMIDLIST)((LPBYTE)pIDList+folderOffset);
*/
LPCITEMIDLIST pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]);
SFGAOF attribs = SFGAO_FOLDER;
HRESULT hr = Desktop()->GetAttributesOf(1, &pidl, &attribs);
if (SUCCEEDED(hr) && (attribs&SFGAO_FOLDER))
if (MainFrame::Create(pidl, FALSE))
ret = S_OK;
}
return ret;
}