mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-30 19:26:05 +00:00
290 lines
7.0 KiB
C++
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(¶ms);
|
|
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;
|
|
}
|