working start menu; beginning of tray notification area

Start menu popup is now closed when clicking in another window.

svn path=/trunk/; revision=5724
This commit is contained in:
Martin Fuchs 2003-08-21 17:11:49 +00:00
parent 6d6caffd7d
commit afbf3c66b6
21 changed files with 303 additions and 85 deletions

View file

@ -32,6 +32,9 @@
#include "../explorer_intres.h" #include "../explorer_intres.h"
UINT PM_DESKTOP_GOT_FOCUS = RegisterWindowMessage(WINMSG_DESKTOP_GOT_FOCUS);
static BOOL (WINAPI*SetShellWindow)(HWND); static BOOL (WINAPI*SetShellWindow)(HWND);
static BOOL (WINAPI*SetShellWindowEx)(HWND, HWND); static BOOL (WINAPI*SetShellWindowEx)(HWND, HWND);
@ -208,6 +211,12 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
explorer_show_frame(_hwnd, SW_SHOWNORMAL); explorer_show_frame(_hwnd, SW_SHOWNORMAL);
break; break;
case WM_SETFOCUS:
// notify Startmenu of focus change
if (wparam)
SendMessage((HWND)wparam, PM_DESKTOP_GOT_FOCUS, 0, 0);
goto def;
case WM_GETISHELLBROWSER: case WM_GETISHELLBROWSER:
return (LRESULT)static_cast<IShellBrowser*>(this); return (LRESULT)static_cast<IShellBrowser*>(this);
@ -222,7 +231,7 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
case WM_CLOSE: case WM_CLOSE:
break; // Over-ride close. We need to close desktop some other way. break; // Over-ride close. We need to close desktop some other way.
default: default: def:
return super::WndProc(nmsg, wparam, lparam); return super::WndProc(nmsg, wparam, lparam);
} }

View file

@ -34,6 +34,9 @@
#include "../externals.h" #include "../externals.h"
#define WINMSG_DESKTOP_GOT_FOCUS _T("DesktopWindowGotFocus")
struct BackgroundWindow : public SubclassedWindow struct BackgroundWindow : public SubclassedWindow
{ {
typedef SubclassedWindow super; typedef SubclassedWindow super;

View file

@ -1,6 +1,5 @@
- extend shell view code in Wine - extend shell view code in Wine
- iplement taskbar and additional deskbands - implement additional deskbands
- taskbar notification area (aka "tray")
- paint desktop background: configurable colors, background image, ... - paint desktop background: configurable colors, background image, ...
- Drag Drop on desktop does not work. - Drag Drop on desktop does not work.
- implement Drag Drop from the tree view. - implement Drag Drop from the tree view.

View file

@ -17,3 +17,5 @@
13.08.2003 m. fuchs make explorer bar look more like windows taskbar bar 13.08.2003 m. fuchs make explorer bar look more like windows taskbar bar
16.08.2003 m. fuchs first draft of working task bar 16.08.2003 m. fuchs first draft of working task bar
18.08.2003 m. fuchs first draft of explorer start menu 18.08.2003 m. fuchs first draft of explorer start menu
21.08.2003 m. fuchs working start menu; beginning of tray notification area
Start menu popup is now closed when clicking in another window.

View file

@ -87,7 +87,7 @@ void explorer_show_frame(HWND hwndDesktop, int cmdshow)
UpdateWindow(g_Globals._hMainWnd); UpdateWindow(g_Globals._hMainWnd);
// Open the first child window after initialiszing the whole application // Open the first child window after initialiszing the whole application
PostMessage(g_Globals._hMainWnd, WM_OPEN_WINDOW, 0, 0); PostMessage(g_Globals._hMainWnd, PM_OPEN_WINDOW, 0, 0);
} }

View file

@ -43,14 +43,14 @@
#define IDW_FIRST_CHILD 0xC000 /*0x200*/ #define IDW_FIRST_CHILD 0xC000 /*0x200*/
#define WM_GET_FILEWND_PTR (WM_APP+0x03) #define PM_GET_FILEWND_PTR (WM_APP+0x03)
#define FRM_CALC_CLIENT (WM_APP+0x04) #define PM_FRM_CALC_CLIENT (WM_APP+0x04)
#define Frame_CalcFrameClient(hwnd, prt) ((BOOL)SNDMSG(hwnd, FRM_CALC_CLIENT, 0, (LPARAM)(PRECT)prt)) #define Frame_CalcFrameClient(hwnd, prt) ((BOOL)SNDMSG(hwnd, PM_FRM_CALC_CLIENT, 0, (LPARAM)(PRECT)prt))
#define WM_OPEN_WINDOW (WM_APP+0x05) #define PM_OPEN_WINDOW (WM_APP+0x05)
#define WM_GET_CONTROLWINDOW (WM_APP+0x06) #define PM_GET_CONTROLWINDOW (WM_APP+0x06)
#define CLASSNAME_FRAME TEXT("CabinetWClass") // same class name for frame window as in MS Explorer #define CLASSNAME_FRAME TEXT("CabinetWClass") // same class name for frame window as in MS Explorer

View file

@ -38,6 +38,8 @@ extern struct ExplorerGlobals
bool _desktop_mode; bool _desktop_mode;
} g_Globals; } g_Globals;
extern UINT PM_DESKTOP_GOT_FOCUS;
struct ResString : public String struct ResString : public String
{ {

View file

@ -41,7 +41,7 @@ CFG=make_explorer - Win32 Debug
# PROP Use_Debug_Libraries 0 # PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release" # PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release" # PROP Intermediate_Dir "Release"
# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make" # PROP Cmd_Line "msdevfilt -gcc make"
# PROP Rebuild_Opt "clean all" # PROP Rebuild_Opt "clean all"
# PROP Target_File "explorer.exe" # PROP Target_File "explorer.exe"
# PROP Bsc_Name "" # PROP Bsc_Name ""

View file

@ -311,7 +311,7 @@ LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
resize_children(LOWORD(lparam), HIWORD(lparam)); resize_children(LOWORD(lparam), HIWORD(lparam));
return DefMDIChildProc(_hwnd, nmsg, wparam, lparam); return DefMDIChildProc(_hwnd, nmsg, wparam, lparam);
case WM_GET_FILEWND_PTR: case PM_GET_FILEWND_PTR:
return (LRESULT)this; return (LRESULT)this;
case WM_SETFOCUS: { case WM_SETFOCUS: {
@ -325,7 +325,7 @@ LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
SetFocus(_focus_pane? _right_hwnd: _left_hwnd); SetFocus(_focus_pane? _right_hwnd: _left_hwnd);
break;} break;}
case WM_DISPATCH_COMMAND: { case PM_DISPATCH_COMMAND: {
Pane* pane = GetFocus()==_left_hwnd? _left: _right; Pane* pane = GetFocus()==_left_hwnd? _left: _right;
switch(LOWORD(wparam)) { switch(LOWORD(wparam)) {

View file

@ -170,7 +170,7 @@ HWND MainFrame::Create()
LRESULT MainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) LRESULT MainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
{ {
switch(nmsg) { switch(nmsg) {
case WM_TRANSLATE_MSG: { case PM_TRANSLATE_MSG: {
MSG* pmsg = (MSG*) lparam; MSG* pmsg = (MSG*) lparam;
#ifndef _NO_MDI #ifndef _NO_MDI
@ -202,14 +202,14 @@ LRESULT MainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
lpmmi->ptMaxTrackSize.y <<= 1;/*2*GetSystemMetrics(SM_CYSCREEN) / SM_CYVIRTUALSCREEN */ lpmmi->ptMaxTrackSize.y <<= 1;/*2*GetSystemMetrics(SM_CYSCREEN) / SM_CYVIRTUALSCREEN */
break;} break;}
case FRM_CALC_CLIENT: case PM_FRM_CALC_CLIENT:
frame_get_clientspace((PRECT)lparam); frame_get_clientspace((PRECT)lparam);
return TRUE; return TRUE;
case FRM_GET_MENUINFO: case PM_FRM_GET_MENUINFO:
return (LPARAM)&_menu_info; return (LPARAM)&_menu_info;
case WM_OPEN_WINDOW: { case PM_OPEN_WINDOW: {
TCHAR path[MAX_PATH]; TCHAR path[MAX_PATH];
//TODO: read paths and window placements from registry //TODO: read paths and window placements from registry
@ -228,7 +228,7 @@ LRESULT MainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
ShellBrowserChild::create(_hmdiclient, create_info); ShellBrowserChild::create(_hmdiclient, create_info);
break;} break;}
case WM_GET_CONTROLWINDOW: case PM_GET_CONTROLWINDOW:
if (wparam == FCW_STATUS) if (wparam == FCW_STATUS)
return (LRESULT)(HWND)_hstatusbar; return (LRESULT)(HWND)_hstatusbar;
break; break;
@ -250,7 +250,7 @@ int MainFrame::Command(int id, int code)
#ifndef _NO_MDI #ifndef _NO_MDI
HWND hwndClient = (HWND) SendMessage(_hmdiclient, WM_MDIGETACTIVE, 0, 0); HWND hwndClient = (HWND) SendMessage(_hmdiclient, WM_MDIGETACTIVE, 0, 0);
if (SendMessage(hwndClient, WM_DISPATCH_COMMAND, MAKELONG(id,code), 0)) if (SendMessage(hwndClient, PM_DISPATCH_COMMAND, MAKELONG(id,code), 0))
return 0; return 0;
#endif #endif
@ -575,7 +575,7 @@ bool MainFrame::activate_drive_window(LPCTSTR path)
// search for a already open window for the same drive // search for a already open window for the same drive
for(child_wnd=::GetNextWindow(_hmdiclient,GW_CHILD); child_wnd; child_wnd=::GetNextWindow(child_wnd, GW_HWNDNEXT)) { for(child_wnd=::GetNextWindow(_hmdiclient,GW_CHILD); child_wnd; child_wnd=::GetNextWindow(child_wnd, GW_HWNDNEXT)) {
FileChildWindow* child = (FileChildWindow*) SendMessage(child_wnd, WM_GET_FILEWND_PTR, 0, 0); FileChildWindow* child = (FileChildWindow*) SendMessage(child_wnd, PM_GET_FILEWND_PTR, 0, 0);
if (child) { if (child) {
_tsplitpath(child->get_root()._path, drv2, 0, 0, 0); _tsplitpath(child->get_root()._path, drv2, 0, 0, 0);
@ -600,7 +600,7 @@ bool MainFrame::activate_fs_window(LPCTSTR filesys)
// search for a already open window of the given file system name // search for a already open window of the given file system name
for(child_wnd=::GetNextWindow(_hmdiclient,GW_CHILD); child_wnd; child_wnd=::GetNextWindow(child_wnd, GW_HWNDNEXT)) { for(child_wnd=::GetNextWindow(_hmdiclient,GW_CHILD); child_wnd; child_wnd=::GetNextWindow(child_wnd, GW_HWNDNEXT)) {
FileChildWindow* child = (FileChildWindow*) SendMessage(child_wnd, WM_GET_FILEWND_PTR, 0, 0); FileChildWindow* child = (FileChildWindow*) SendMessage(child_wnd, PM_GET_FILEWND_PTR, 0, 0);
if (child) { if (child) {
if (!lstrcmpi(child->get_root()._fs, filesys)) { if (!lstrcmpi(child->get_root()._fs, filesys)) {

View file

@ -136,7 +136,7 @@ LRESULT Pane::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
break; break;
case WM_SETFOCUS: { case WM_SETFOCUS: {
FileChildWindow* child = (FileChildWindow*) SendMessage(GetParent(_hwnd), WM_GET_FILEWND_PTR, 0, 0); FileChildWindow* child = (FileChildWindow*) SendMessage(GetParent(_hwnd), PM_GET_FILEWND_PTR, 0, 0);
child->set_focus_pane(this); child->set_focus_pane(this);
ListBox_SetSel(_hwnd, TRUE, 1); ListBox_SetSel(_hwnd, TRUE, 1);
@ -144,7 +144,7 @@ LRESULT Pane::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
break;} break;}
case WM_KEYDOWN: { case WM_KEYDOWN: {
FileChildWindow* child = (FileChildWindow*) SendMessage(GetParent(_hwnd), WM_GET_FILEWND_PTR, 0, 0); FileChildWindow* child = (FileChildWindow*) SendMessage(GetParent(_hwnd), PM_GET_FILEWND_PTR, 0, 0);
if (wparam == VK_TAB) { if (wparam == VK_TAB) {
/*TODO: SetFocus(g_Globals.hdrivebar) */ /*TODO: SetFocus(g_Globals.hdrivebar) */

View file

@ -74,7 +74,7 @@ struct ShellBrowserChild : public ChildWindow, public IShellBrowserImpl
return S_OK; return S_OK;
} }
HWND hwnd = (HWND)SendMessage(_hWndFrame, WM_GET_CONTROLWINDOW, id, 0); HWND hwnd = (HWND)SendMessage(_hWndFrame, PM_GET_CONTROLWINDOW, id, 0);
if (hwnd) { if (hwnd) {
*lphwnd = hwnd; *lphwnd = hwnd;
@ -89,7 +89,7 @@ struct ShellBrowserChild : public ChildWindow, public IShellBrowserImpl
if (!pret) if (!pret)
return E_POINTER; return E_POINTER;
HWND hstatusbar = (HWND)SendMessage(_hWndFrame, WM_GET_CONTROLWINDOW, id, 0); HWND hstatusbar = (HWND)SendMessage(_hWndFrame, PM_GET_CONTROLWINDOW, id, 0);
if (hstatusbar) { if (hstatusbar) {
*pret = ::SendMessage(hstatusbar, uMsg, wParam, lParam); *pret = ::SendMessage(hstatusbar, uMsg, wParam, lParam);

View file

@ -147,7 +147,7 @@ BOOL ShellEntry::launch_entry(HWND hwnd, UINT nCmdShow)
SHELLEXECUTEINFO shexinfo; SHELLEXECUTEINFO shexinfo;
shexinfo.cbSize = sizeof(SHELLEXECUTEINFO); shexinfo.cbSize = sizeof(SHELLEXECUTEINFO);
shexinfo.fMask = SEE_MASK_IDLIST; shexinfo.fMask = SEE_MASK_INVOKEIDLIST;//@@SEE_MASK_IDLIST;
shexinfo.hwnd = hwnd; shexinfo.hwnd = hwnd;
shexinfo.lpVerb = NULL; shexinfo.lpVerb = NULL;
shexinfo.lpFile = NULL; shexinfo.lpFile = NULL;

View file

@ -61,7 +61,7 @@ StartMenu::StartMenu(HWND hwnd, const StartMenuFolders& info)
StartMenu::~StartMenu() StartMenu::~StartMenu()
{ {
SendParent(WM_STARTMENU_CLOSED); SendParent(PM_STARTMENU_CLOSED);
} }
@ -167,7 +167,17 @@ LRESULT StartMenu::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
return 0; // disable window resizing return 0; // disable window resizing
goto def; goto def;
case WM_STARTENTRY_FOCUSED: { case WM_ACTIVATEAPP:
// close start menu when activating another application
if (!wparam)
CloseStartMenu();
goto def;
case WM_CANCELMODE:
CloseStartMenu();
break;
case PM_STARTENTRY_FOCUSED: {
BOOL hasSubmenu = wparam; BOOL hasSubmenu = wparam;
HWND hctrl = (HWND)lparam; HWND hctrl = (HWND)lparam;
@ -182,17 +192,23 @@ LRESULT StartMenu::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
} }
break;} break;}
case WM_STARTENTRY_LAUNCHED: case PM_STARTENTRY_LAUNCHED:
// route message to the parent menu and close menus after launching an entry // route message to the parent menu and close menus after launching an entry
if (!SendParent(nmsg, wparam, lparam)) if (!SendParent(nmsg, wparam, lparam))
DestroyWindow(_hwnd); DestroyWindow(_hwnd);
return 1; // signal that we have received and processed the message return 1; // signal that we have received and processed the message
case WM_STARTMENU_CLOSED: case PM_STARTMENU_CLOSED:
_submenu = 0; _submenu = 0;
break; break;
default: def: default:
if (nmsg == PM_DESKTOP_GOT_FOCUS) {
CloseStartMenu();
return 0;
}
def:
return super::WndProc(nmsg, wparam, lparam); return super::WndProc(nmsg, wparam, lparam);
} }
@ -321,14 +337,18 @@ void StartMenu::AddSeparator()
bool StartMenu::CloseOtherSubmenus(int id) bool StartMenu::CloseOtherSubmenus(int id)
{ {
if (_submenu && IsWindow(_submenu)) { if (_submenu) {
if (_submenu_id == id) if (IsWindow(_submenu)) {
return false; if (_submenu_id == id)
else { return false;
DestroyWindow(_submenu); else {
_submenu_id = 0; DestroyWindow(_submenu);
_submenu = 0; // safetly first - should be reset automatically by WM_STARTMENU_CLOSED _submenu_id = 0;
// _submenu should be reset automatically by PM_STARTMENU_CLOSED, but safety first...
}
} }
_submenu = 0;
} }
return true; return true;
@ -405,15 +425,16 @@ void StartMenu::ActivateEntry(int id, ShellEntry* entry)
} else { } else {
entry->launch_entry(_hwnd); //TODO: launch in the background entry->launch_entry(_hwnd); //TODO: launch in the background
// close start menus after launching the selected entry
CloseStartMenu(id); CloseStartMenu(id);
} }
} }
/// close all windows of the start menu popup
void StartMenu::CloseStartMenu(int id) void StartMenu::CloseStartMenu(int id)
{ {
// close start menus after launching the selected entry if (!SendParent(PM_STARTENTRY_LAUNCHED, id, (LPARAM)_hwnd))
if (!SendParent(WM_STARTENTRY_LAUNCHED, id, (LPARAM)_hwnd))
DestroyWindow(_hwnd); DestroyWindow(_hwnd);
} }
@ -433,9 +454,9 @@ int StartMenuButton::GetTextWidth(LPCTSTR title)
} }
LRESULT StartMenuButton::WndProc(UINT message, WPARAM wparam, LPARAM lparam) LRESULT StartMenuButton::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
{ {
switch(message) { switch(nmsg) {
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
// automatically set the focus to startmenu entries when moving the mouse over them // automatically set the focus to startmenu entries when moving the mouse over them
if (GetFocus()!=_hwnd && !(GetWindowStyle(_hwnd)&WS_DISABLED)) if (GetFocus()!=_hwnd && !(GetWindowStyle(_hwnd)&WS_DISABLED))
@ -443,11 +464,15 @@ LRESULT StartMenuButton::WndProc(UINT message, WPARAM wparam, LPARAM lparam)
break; break;
case WM_SETFOCUS: case WM_SETFOCUS:
PostParent(WM_STARTENTRY_FOCUSED, _hasSubmenu, (LPARAM)_hwnd); PostParent(PM_STARTENTRY_FOCUSED, _hasSubmenu, (LPARAM)_hwnd);
goto def; goto def;
default: def: default:
return super::WndProc(message, wparam, lparam); if (nmsg == PM_DESKTOP_GOT_FOCUS)
return SendParent(nmsg, wparam, lparam);
def:
return super::WndProc(nmsg, wparam, lparam);
} }
return 0; return 0;

View file

@ -38,9 +38,10 @@
#define STARTMENU_SEP_HEIGHT (STARTMENU_LINE_HEIGHT/2) #define STARTMENU_SEP_HEIGHT (STARTMENU_LINE_HEIGHT/2)
#define WM_STARTMENU_CLOSED (WM_APP+0x11) // private message constants
#define WM_STARTENTRY_FOCUSED (WM_APP+0x12) #define PM_STARTMENU_CLOSED (WM_APP+0x11)
#define WM_STARTENTRY_LAUNCHED (WM_APP+0x13) #define PM_STARTENTRY_FOCUSED (WM_APP+0x12)
#define PM_STARTENTRY_LAUNCHED (WM_APP+0x13)
struct StartMenuDirectory struct StartMenuDirectory

View file

@ -58,7 +58,8 @@ HWND InitializeExplorerBar(HINSTANCE hInstance)
DesktopBar::DesktopBar(HWND hwnd) DesktopBar::DesktopBar(HWND hwnd)
: super(hwnd) : super(hwnd),
WM_TASKBARCREATED(RegisterWindowMessage(WINMSG_TASKBARCREATED))
{ {
} }
@ -84,11 +85,21 @@ LRESULT DesktopBar::Init(LPCREATESTRUCT pcs)
TASKBAR_LEFT, 0, ClientRect(_hwnd).right-TASKBAR_LEFT, TASKBAR_HEIGHT, _hwnd); TASKBAR_LEFT, 0, ClientRect(_hwnd).right-TASKBAR_LEFT, TASKBAR_HEIGHT, _hwnd);
TaskBar* taskbar = static_cast<TaskBar*>(Window::get_window(_hwndTaskBar)); TaskBar* taskbar = static_cast<TaskBar*>(Window::get_window(_hwndTaskBar));
taskbar->_desktop_bar = this; taskbar->_desktop_bar = this;
// create tray notification area
_hwndNotify = Window::Create(WINDOW_CREATOR(NotifyArea), WS_EX_STATICEDGE,
BtnWindowClass(CLASSNAME_TRAYNOTIFY), TITLE_TRAYNOTIFY, WS_CHILD|WS_VISIBLE,
TASKBAR_LEFT, 0, ClientRect(_hwnd).right-TASKBAR_LEFT, TASKBAR_HEIGHT, _hwnd);
NotifyArea* notify_area = static_cast<NotifyArea*>(Window::get_window(_hwndNotify));
notify_area->_desktop_bar = this;
RegisterHotkeys(); RegisterHotkeys();
// notify all top level windows about the successfully created desktop bar
PostMessage(HWND_BROADCAST, WM_TASKBARCREATED, 0, 0);
return 0; return 0;
} }
@ -145,22 +156,35 @@ LRESULT DesktopBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
} }
goto def; goto def;
case WM_SIZE: case WM_SIZE: {
ClientRect clnt(_hwnd);
int cy = HIWORD(lparam);
if (_hwndTaskBar) if (_hwndTaskBar)
MoveWindow(_hwndTaskBar, TASKBAR_LEFT, 0, ClientRect(_hwnd).right-TASKBAR_LEFT, HIWORD(lparam), TRUE); MoveWindow(_hwndTaskBar, TASKBAR_LEFT, 0, clnt.right-TASKBAR_LEFT-NOTIFYAREA_WIDTH, cy, TRUE);
break;
if (_hwndNotify)
MoveWindow(_hwndNotify, clnt.right-NOTIFYAREA_WIDTH, 0, NOTIFYAREA_WIDTH, cy, TRUE);
break;}
case WM_CLOSE: case WM_CLOSE:
break; break;
case WM_STARTMENU_CLOSED: case PM_STARTMENU_CLOSED:
_startMenuRoot = 0; _startMenuRoot = 0;
break; break;
case WM_SETFOCUS:
CloseStartMenu();
goto def;
case WM_HOTKEY: case WM_HOTKEY:
ProcessHotKey(wparam); ProcessHotKey(wparam);
break; break;
case WM_COPYDATA:
return ProcessCopyData((COPYDATASTRUCT*)lparam);
default: def: default: def:
return super::WndProc(nmsg, wparam, lparam); return super::WndProc(nmsg, wparam, lparam);
} }
@ -172,7 +196,7 @@ LRESULT DesktopBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
int DesktopBar::Command(int id, int code) int DesktopBar::Command(int id, int code)
{ {
switch(id) { switch(id) {
case IDC_START: case IDC_START: //TODO: startmenu should popup for WM_LBUTTONDOWN, not for WM_COMMAND
ToggleStartmenu(); ToggleStartmenu();
break; break;
} }
@ -193,6 +217,39 @@ void DesktopBar::ToggleStartmenu()
} }
} }
void DesktopBar::CloseStartMenu()
{
if (_startMenuRoot) {
DestroyWindow(_startMenuRoot);
_startMenuRoot = 0;
}
}
/// copy data structure for tray notifications
struct TrayNotifyCDS {
DWORD cookie;
DWORD notify_code;
DWORD offset;
};
LRESULT DesktopBar::ProcessCopyData(COPYDATASTRUCT* pcd)
{
// Is this a tray notification message?
if (pcd->dwData == 1) {
TrayNotifyCDS* ptr = (TrayNotifyCDS*) pcd->lpData;
NOTIFYICONDATA* pnid = (NOTIFYICONDATA*) (LPBYTE(pcd->lpData)+ptr->offset);
NotifyArea* notify_area = static_cast<NotifyArea*>(Window::get_window(_hwndNotify));
if (notify_area)
return notify_area->ProcessTrayNotification(ptr->notify_code, pnid);
}
return 0;
}
static HICON get_window_icon(HWND hwnd) static HICON get_window_icon(HWND hwnd)
{ {
@ -285,7 +342,7 @@ LRESULT TaskBar::Init(LPCREATESTRUCT pcs)
_next_id = IDC_FIRST_APP; _next_id = IDC_FIRST_APP;
//InstallShellHook(_hwnd, WM_SHELLHOOK_NOTIFY); //InstallShellHook(_hwnd, PM_SHELLHOOK_NOTIFY);
Refresh(); Refresh();
@ -297,8 +354,8 @@ LRESULT TaskBar::Init(LPCREATESTRUCT pcs)
LRESULT TaskBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) LRESULT TaskBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
{ {
switch(nmsg) { switch(nmsg) {
case WM_CLOSE: /* case WM_CLOSE:
break; break; */
case WM_SIZE: case WM_SIZE:
SendMessage(_htoolbar, WM_SIZE, 0, 0); SendMessage(_htoolbar, WM_SIZE, 0, 0);
@ -308,7 +365,7 @@ LRESULT TaskBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
Refresh(); Refresh();
return 0; return 0;
case WM_SHELLHOOK_NOTIFY: { case PM_SHELLHOOK_NOTIFY: {
int code = lparam; int code = lparam;
/* /*
switch(code) { switch(code) {
@ -495,3 +552,63 @@ TaskBarMap::iterator TaskBarMap::find_id(int id)
return end(); return end();
} }
NotifyArea::NotifyArea(HWND hwnd)
: super(hwnd)
{
_desktop_bar = NULL;
}
NotifyArea::~NotifyArea()
{
}
LRESULT NotifyArea::Init(LPCREATESTRUCT pcs)
{
if (super::Init(pcs))
return 1;
return 0;
}
LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
{
/*@@
switch(nmsg) {
default:
return super::WndProc(nmsg, wparam, lparam);
}
*/return super::WndProc(nmsg, wparam, lparam);
return 0;
}
int NotifyArea::Command(int id, int code)
{
return super::Command(id, code);
}
LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pnid)
{
switch(notify_code) {
case NIM_ADD:
break;
case NIM_MODIFY:
break;
case NIM_DELETE:
break;
#if NOTIFYICON_VERSION>=3 // currently (as of 21.08.2003) missing in MinGW headers
case NIM_SETFOCUS:
break;
case NIM_SETVERSION:
break;
#endif
}
return 0;
}

View file

@ -34,15 +34,23 @@
#define TASKBAR_LEFT 70 #define TASKBAR_LEFT 70
//#define TASKBAR_AT_TOP //#define TASKBAR_AT_TOP
#define NOTIFYAREA_WIDTH 100
#define CLASSNAME_EXPLORERBAR _T("Shell_TrayWnd") #define CLASSNAME_EXPLORERBAR _T("Shell_TrayWnd")
#define TITLE_EXPLORERBAR _T("DesktopBar") #define TITLE_EXPLORERBAR _T("DesktopBar") //_T("")
#define CLASSNAME_TASKBAR _T("MSTaskSwWClass") #define CLASSNAME_TASKBAR _T("MSTaskSwWClass")
#define TITLE_TASKBAR _T("Running Applications") #define TITLE_TASKBAR _T("Running Applications")
#define CLASSNAME_TRAYNOTIFY _T("TrayNotifyWnd")
#define TITLE_TRAYNOTIFY _T("")
#define WM_SHELLHOOK_NOTIFY (WM_APP+0x10)
// private message constant
#define PM_SHELLHOOK_NOTIFY (WM_APP+0x10)
#define WINMSG_TASKBARCREATED _T("TaskbarCreated")
#define IDC_START 0x1000 #define IDC_START 0x1000
@ -65,6 +73,7 @@
#define IDC_FIRST_MENU 0x3000 #define IDC_FIRST_MENU 0x3000
/// desktop bar window, also known as "system tray"
struct DesktopBar : public OwnerDrawParent<Window> struct DesktopBar : public OwnerDrawParent<Window>
{ {
typedef OwnerDrawParent<Window> super; typedef OwnerDrawParent<Window> super;
@ -73,6 +82,8 @@ struct DesktopBar : public OwnerDrawParent<Window>
~DesktopBar(); ~DesktopBar();
protected: protected:
int WM_TASKBARCREATED;
LRESULT Init(LPCREATESTRUCT pcs); LRESULT Init(LPCREATESTRUCT pcs);
LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
int Command(int id, int code); int Command(int id, int code);
@ -80,15 +91,18 @@ protected:
void RegisterHotkeys(); void RegisterHotkeys();
void ProcessHotKey(int id_hotkey); void ProcessHotKey(int id_hotkey);
void ToggleStartmenu(); void ToggleStartmenu();
void CloseStartMenu();
LRESULT ProcessCopyData(COPYDATASTRUCT* pcd);
WindowHandle _hwndTaskBar; WindowHandle _hwndTaskBar;
WindowHandle _startMenuRoot; WindowHandle _startMenuRoot;
WindowHandle _hwndNotify;
}; };
#define IDW_TASKTOOLBAR 100 #define IDW_TASKTOOLBAR 100
// internal task bar button management entry /// internal task bar button management entry
struct TaskBarEntry struct TaskBarEntry
{ {
TaskBarEntry(); TaskBarEntry();
@ -102,7 +116,7 @@ struct TaskBarEntry
BYTE _fsState; BYTE _fsState;
}; };
// map for managing the task bar buttons /// map for managing the task bar buttons
struct TaskBarMap : public map<HWND, TaskBarEntry> struct TaskBarMap : public map<HWND, TaskBarEntry>
{ {
~TaskBarMap(); ~TaskBarMap();
@ -110,7 +124,7 @@ struct TaskBarMap : public map<HWND, TaskBarEntry>
iterator find_id(int id); iterator find_id(int id);
}; };
// Taskbar window /// Taskbar window
struct TaskBar : public Window struct TaskBar : public Window
{ {
typedef Window super; typedef Window super;
@ -118,7 +132,7 @@ struct TaskBar : public Window
TaskBar(HWND hwnd); TaskBar(HWND hwnd);
~TaskBar(); ~TaskBar();
DesktopBar* _desktop_bar; DesktopBar* _desktop_bar; // may be not necessary
protected: protected:
WindowHandle _htoolbar; WindowHandle _htoolbar;
@ -134,3 +148,32 @@ protected:
void Refresh(); void Refresh();
}; };
struct NotifyIconIndex {
HWND hWnd;
UINT uID;
};
typedef map<NotifyIconIndex, int> NotifyIconMap;
/// tray notification area aka "tray"
struct NotifyArea : public Window
{
typedef Window super;
NotifyArea(HWND hwnd);
~NotifyArea();
DesktopBar* _desktop_bar;
LRESULT ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pnid);
protected:
NotifyIconMap _icon_map;
LRESULT Init(LPCREATESTRUCT pcs);
LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
int Command(int id, int code);
};

View file

@ -121,6 +121,22 @@ struct WindowRect : public RECT
} }
}; };
struct Point: public POINT
{
Point(LONG x_, LONG y_)
{
x = x_;
y = y_;
}
// constructor for being used in processing WM_MOUSEMOVE, WM_LBUTTONDOWN, ... messages
Point(LPARAM lparam)
{
x = GET_X_LPARAM(lparam);
y = GET_Y_LPARAM(lparam);
}
};
struct TextColor struct TextColor
{ {

View file

@ -286,7 +286,7 @@ LRESULT ChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
break;} break;}
case WM_LBUTTONDOWN: { case WM_LBUTTONDOWN: {
int x = LOWORD(lparam); int x = GET_X_LPARAM(lparam);
ClientRect rt(_hwnd); ClientRect rt(_hwnd);
@ -333,7 +333,7 @@ LRESULT ChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
} }
break; break;
case WM_DISPATCH_COMMAND: case PM_DISPATCH_COMMAND:
return FALSE; return FALSE;
default: def: default: def:
@ -379,7 +379,7 @@ void Window::unregister_pretranslate(HWND hwnd)
BOOL Window::pretranslate_msg(LPMSG pmsg) BOOL Window::pretranslate_msg(LPMSG pmsg)
{ {
for(WindowSet::const_iterator it=Window::s_pretranslate_windows.begin(); it!=s_pretranslate_windows.end(); ++it) for(WindowSet::const_iterator it=Window::s_pretranslate_windows.begin(); it!=s_pretranslate_windows.end(); ++it)
if (SendMessage(*it, WM_TRANSLATE_MSG, 0, (LPARAM)pmsg)) if (SendMessage(*it, PM_TRANSLATE_MSG, 0, (LPARAM)pmsg))
return TRUE; return TRUE;
return FALSE; return FALSE;
@ -491,7 +491,7 @@ Button::Button(HWND parent, LPCTSTR title, int left, int top, int width, int hei
LRESULT OwnerdrawnButton::WndProc(UINT message, WPARAM wparam, LPARAM lparam) LRESULT OwnerdrawnButton::WndProc(UINT message, WPARAM wparam, LPARAM lparam)
{ {
if (message == WM_DISPATCH_DRAWITEM) { if (message == PM_DISPATCH_DRAWITEM) {
DrawItem((LPDRAWITEMSTRUCT)lparam); DrawItem((LPDRAWITEMSTRUCT)lparam);
return TRUE; return TRUE;
} else } else

View file

@ -218,8 +218,9 @@ struct IconWindowClass : public WindowClass
}; };
#define WM_DISPATCH_COMMAND (WM_APP+0x00) // private message constants
#define WM_TRANSLATE_MSG (WM_APP+0x01) #define PM_DISPATCH_COMMAND (WM_APP+0x00)
#define PM_TRANSLATE_MSG (WM_APP+0x01)
#define SPLIT_WIDTH 5 #define SPLIT_WIDTH 5
@ -234,9 +235,9 @@ struct MenuInfo
HMENU _hMenuOptions; HMENU _hMenuOptions;
}; };
#define FRM_GET_MENUINFO (WM_APP+0x02) #define PM_FRM_GET_MENUINFO (WM_APP+0x02)
#define Frame_GetMenuInfo(hwnd) ((MenuInfo*)SNDMSG(hwnd, FRM_GET_MENUINFO, 0, 0)) #define Frame_GetMenuInfo(hwnd) ((MenuInfo*)SNDMSG(hwnd, PM_FRM_GET_MENUINFO, 0, 0))
/** /**
@ -271,7 +272,7 @@ protected:
/** /**
PreTranslateWindow is used to register windows to be called by Window::pretranslate_msg(). PreTranslateWindow is used to register windows to be called by Window::pretranslate_msg().
This way you get WM_TRANSLATE_MSG messages before the message loop dispatches messages. This way you get PM_TRANSLATE_MSG messages before the message loop dispatches messages.
You can then for example use TranslateAccelerator() to implement key shortcuts. You can then for example use TranslateAccelerator() to implement key shortcuts.
*/ */
struct PreTranslateWindow : public Window struct PreTranslateWindow : public Window
@ -325,7 +326,7 @@ struct Static : public WindowHandle
/* /*
// control color message routing for ColorStatic and HyperlinkCtrl // control color message routing for ColorStatic and HyperlinkCtrl
#define WM_DISPATCH_CTLCOLOR (WM_APP+0x07) #define PM_DISPATCH_CTLCOLOR (WM_APP+0x07)
template<typename BASE> struct CtlColorParent : public BASE template<typename BASE> struct CtlColorParent : public BASE
{ {
@ -334,20 +335,20 @@ template<typename BASE> struct CtlColorParent : public BASE
CtlColorParent(HWND hwnd) CtlColorParent(HWND hwnd)
: super(hwnd) {} : super(hwnd) {}
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
{ {
switch(message) { switch(nmsg) {
case WM_CTLCOLOR: case WM_CTLCOLOR:
case WM_CTLCOLORBTN: case WM_CTLCOLORBTN:
case WM_CTLCOLORDLG: case WM_CTLCOLORDLG:
case WM_CTLCOLORSCROLLBAR: case WM_CTLCOLORSCROLLBAR:
case WM_CTLCOLORSTATIC: { case WM_CTLCOLORSTATIC: {
HWND hctl = (HWND) lparam; HWND hctl = (HWND) lparam;
return SendMessage(hctl, WM_DISPATCH_CTLCOLOR, wparam, message); return SendMessage(hctl, PM_DISPATCH_CTLCOLOR, wparam, nmsg);
} }
default: default:
return super::WndProc(message, wparam, lparam); return super::WndProc(nmsg, wparam, lparam);
} }
} }
}; };
@ -356,7 +357,7 @@ template<typename BASE> struct CtlColorParent : public BASE
// owner draw message routing for ColorButton and PictureButton // owner draw message routing for ColorButton and PictureButton
#define WM_DISPATCH_DRAWITEM (WM_APP+0x08) #define PM_DISPATCH_DRAWITEM (WM_APP+0x08)
template<typename BASE> struct OwnerDrawParent : public BASE template<typename BASE> struct OwnerDrawParent : public BASE
{ {
@ -365,29 +366,29 @@ template<typename BASE> struct OwnerDrawParent : public BASE
OwnerDrawParent(HWND hwnd) OwnerDrawParent(HWND hwnd)
: super(hwnd) {} : super(hwnd) {}
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
{ {
switch(message) { switch(nmsg) {
case WM_DRAWITEM: case WM_DRAWITEM:
if (wparam) { // ein Control? if (wparam) { // ein Control?
HWND hctl = GetDlgItem(_hwnd, wparam); HWND hctl = GetDlgItem(_hwnd, wparam);
if (hctl) if (hctl)
return SendMessage(hctl, WM_DISPATCH_DRAWITEM, wparam, lparam); return SendMessage(hctl, PM_DISPATCH_DRAWITEM, wparam, lparam);
} /*else // oder ein Menüeintrag? } /*else // oder ein Menüeintrag?
; */ ; */
return 0; return 0;
default: default:
return super::WndProc(message, wparam, lparam); return super::WndProc(nmsg, wparam, lparam);
} }
} }
}; };
/** /**
Subclass button controls to draw them by using WM_DISPATCH_DRAWITEM Subclass button controls to draw them by using PM_DISPATCH_DRAWITEM
The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons. The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
*/ */
struct OwnerdrawnButton : public SubclassedWindow struct OwnerdrawnButton : public SubclassedWindow

View file

@ -3227,7 +3227,7 @@ LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam
case WM_LBUTTONDOWN: { case WM_LBUTTONDOWN: {
RECT rt; RECT rt;
int x = LOWORD(lparam); int x = GET_X_LPARAM(lparam);
GetClientRect(hwnd, &rt); GetClientRect(hwnd, &rt);