--- /dev/null
+/*
+ * 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
+ //
+ // desktopbar.cpp
+ //
+ // Martin Fuchs, 22.08.2003
+ //
+
+
+#include "../utility/utility.h"
+
+#include "../explorer.h"
+#include "../globals.h"
+#include "../externals.h"
+#include "../explorer_intres.h"
+
+#include "desktopbar.h"
+#include "taskbar.h"
+#include "startmenu.h"
+#include "traynotify.h"
+#include "quicklaunch.h"
+
+
+DesktopBar::DesktopBar(HWND hwnd)
+ : super(hwnd),
+ // initialize Common Controls library
+ WM_TASKBARCREATED(RegisterWindowMessage(WINMSG_TASKBARCREATED))
+{
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &_work_area_org, 0);
+}
+
+DesktopBar::~DesktopBar()
+{
+ // restore work area to the previous size
+ SystemParametersInfo(SPI_SETWORKAREA, 0, &_work_area_org, 0);
+ PostMessage(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETWORKAREA, 0);
+
+ // exit application after destroying desktop window
+ PostQuitMessage(0);
+}
+
+
+HWND DesktopBar::Create()
+{
+ RECT rect;
+
+ rect.left = -2; // hide left border
+#ifdef TASKBAR_AT_TOP
+ rect.top = -2; // hide top border
+#else
+ rect.top = GetSystemMetrics(SM_CYSCREEN) - DESKTOPBARBAR_HEIGHT;
+#endif
+ rect.right = GetSystemMetrics(SM_CXSCREEN) + 2;
+ rect.bottom = rect.top + DESKTOPBARBAR_HEIGHT + 2;
+
+ return Window::Create(WINDOW_CREATOR(DesktopBar), WS_EX_PALETTEWINDOW,
+ BtnWindowClass(CLASSNAME_EXPLORERBAR), TITLE_EXPLORERBAR,
+ WS_POPUP|WS_THICKFRAME|WS_CLIPCHILDREN|WS_VISIBLE,
+ rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0);
+}
+
+
+LRESULT DesktopBar::Init(LPCREATESTRUCT pcs)
+{
+ if (super::Init(pcs))
+ return 1;
+
+ // create start button
+ new PictureButton(Button(_hwnd, ResString(IDS_START), 2, 2, STARTBUTTON_WIDTH, DESKTOPBARBAR_HEIGHT-8, IDC_START, WS_VISIBLE|WS_CHILD|BS_OWNERDRAW),
+ SmallIcon(IDI_STARTMENU)/*, GetStockBrush(WHITE_BRUSH)*/);
+
+ // create task bar
+ _hwndTaskBar = TaskBar::Create(_hwnd);
+
+ // create tray notification area
+ _hwndNotify = NotifyArea::Create(_hwnd);
+
+ _hwndQuickLaunch = QuickLaunchBar::Create(_hwnd);
+
+ RegisterHotkeys();
+
+ // notify all top level windows about the successfully created desktop bar
+ PostMessage(HWND_BROADCAST, WM_TASKBARCREATED, 0, 0);
+
+ return 0;
+}
+
+
+void DesktopBar::RegisterHotkeys()
+{
+ // register hotkey WIN+E opening explorer
+ RegisterHotKey(_hwnd, 0, MOD_WIN, 'E');
+
+ //TODO: register all common hotkeys
+}
+
+void DesktopBar::ProcessHotKey(int id_hotkey)
+{
+ switch(id_hotkey) {
+ case 0: explorer_show_frame(_hwnd, SW_SHOWNORMAL); break;
+ //TODO: implement all common hotkeys
+ }
+}
+
+
+LRESULT DesktopBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ switch(nmsg) {
+ case WM_NCHITTEST: {
+ LRESULT res = super::WndProc(nmsg, wparam, lparam);
+
+ if (res>=HTSIZEFIRST && res<=HTSIZELAST) {
+#ifdef TASKBAR_AT_TOP
+ if (res == HTBOTTOM) // enable vertical resizing at the lower border
+#else
+ if (res == HTTOP) // enable vertical resizing at the upper border
+#endif
+ return res;
+ else
+ return HTCLIENT; // disable any other resizing
+ }
+ return res;}
+
+ case WM_SYSCOMMAND:
+ if ((wparam&0xFFF0) == SC_SIZE) {
+#ifdef TASKBAR_AT_TOP
+ if (wparam == SC_SIZE+6)// enable vertical resizing at the lower border
+#else
+ if (wparam == SC_SIZE+3)// enable vertical resizing at the upper border
+#endif
+ goto def;
+ else
+ return 0; // disable any other resizing
+ } else if (wparam == SC_TASKLIST)
+ ShowStartMenu();
+ goto def;
+
+ case WM_SIZE: {
+ int cx = LOWORD(lparam);
+ int cy = HIWORD(lparam);
+
+ if (_hwndTaskBar)
+ MoveWindow(_hwndTaskBar, TASKBAR_LEFT+QUICKLAUNCH_WIDTH, 0, cx-TASKBAR_LEFT-QUICKLAUNCH_WIDTH-(NOTIFYAREA_WIDTH+1), cy, TRUE);
+
+ if (_hwndNotify)
+ MoveWindow(_hwndNotify, cx-(NOTIFYAREA_WIDTH+1), 1, NOTIFYAREA_WIDTH, cy-2, TRUE);
+
+ if (_hwndQuickLaunch)
+ MoveWindow(_hwndQuickLaunch, TASKBAR_LEFT, 1, QUICKLAUNCH_WIDTH, cy-2, TRUE);
+
+ WindowRect rect(_hwnd);
+ RECT work_area = {0, 0, GetSystemMetrics(SM_CXSCREEN), rect.top};
+ SystemParametersInfo(SPI_SETWORKAREA, 0, &work_area, 0); // don't use SPIF_SENDCHANGE because then we have to wait for any message being delivered
+ PostMessage(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETWORKAREA, 0);
+ break;}
+
+ case WM_CLOSE:
+ break;
+
+ case WM_HOTKEY:
+ ProcessHotKey(wparam);
+ break;
+
+ case WM_COPYDATA:
+ return ProcessCopyData((COPYDATASTRUCT*)lparam);
+
+ default: def:
+ return super::WndProc(nmsg, wparam, lparam);
+ }
+
+ return 0;
+}
+
+
+int DesktopBar::Command(int id, int code)
+{
+ switch(id) {
+ case IDC_START: //TODO: startmenu should popup for WM_LBUTTONDOWN, not for WM_COMMAND
+ ShowStartMenu();
+ break;
+
+ default:
+ if ((id&~0xFF) == IDC_FIRST_QUICK_ID)
+ SendMessage(_hwndQuickLaunch, WM_COMMAND, MAKEWPARAM(id,code), 0);
+ }
+
+ return 0;
+}
+
+
+void DesktopBar::ShowStartMenu()
+{
+ // create Startmenu
+ StartMenuRoot* startMenuRoot = GET_WINDOW(StartMenuRoot, StartMenuRoot::Create(_hwnd));
+
+ if (startMenuRoot)
+ startMenuRoot->TrackStartmenu();
+}
+
+
+ /// copy data structure for tray notifications
+struct TrayNotifyCDS {
+ DWORD cookie;
+ DWORD notify_code;
+ NOTIFYICONDATA nicon_data;
+};
+
+LRESULT DesktopBar::ProcessCopyData(COPYDATASTRUCT* pcd)
+{
+ // Is this a tray notification message?
+ if (pcd->dwData == 1) {
+ TrayNotifyCDS* ptr = (TrayNotifyCDS*) pcd->lpData;
+
+ //TODO: process the differnt versions of the NOTIFYICONDATA structure (look at cbSize to decide which one)
+
+ NotifyArea* notify_area = GET_WINDOW(NotifyArea, _hwndNotify);
+
+ if (notify_area)
+ return notify_area->ProcessTrayNotification(ptr->notify_code, &ptr->nicon_data);
+ }
+
+ return 0;
+}