diff --git a/reactos/ChangeLog b/reactos/ChangeLog index ebd39a88334..c17bd257bd6 100644 --- a/reactos/ChangeLog +++ b/reactos/ChangeLog @@ -1,3 +1,8 @@ +2003-08-16 Martin Fuchs + + * subsys/system/explorer/taskbar/taskbar.cpp: + first draft of explorer start menu + 2003-08-17 James Tabor * include/csrss/: csrss.h: implemented Ctrl Event handler diff --git a/reactos/subsys/system/explorer/desktop/desktop.cpp b/reactos/subsys/system/explorer/desktop/desktop.cpp index aaf6dde02cc..f6e312a3bc0 100644 --- a/reactos/subsys/system/explorer/desktop/desktop.cpp +++ b/reactos/subsys/system/explorer/desktop/desktop.cpp @@ -230,7 +230,7 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) } -HWND create_desktop_window(HINSTANCE hInstance) +HWND create_desktop_window() { IconWindowClass wcDesktop(_T("Progman"), IDI_REACTOS, CS_DBLCLKS); wcDesktop.hbrBackground = (HBRUSH)(COLOR_BACKGROUND+1); @@ -239,6 +239,6 @@ HWND create_desktop_window(HINSTANCE hInstance) int height = GetSystemMetrics(SM_CYSCREEN); return Window::Create(WINDOW_CREATOR(DesktopWindow), - WS_EX_TOOLWINDOW, (LPCTSTR)(int)wcDesktop.Register(), _T("Program Manager"), WS_POPUP|WS_VISIBLE|WS_CLIPCHILDREN, + WS_EX_TOOLWINDOW, wcDesktop, _T("Program Manager"), WS_POPUP|WS_VISIBLE|WS_CLIPCHILDREN, 0, 0, width, height, 0); } diff --git a/reactos/subsys/system/explorer/doc/TODO.txt b/reactos/subsys/system/explorer/doc/TODO.txt index 0b821515c38..7e47cc7210e 100644 --- a/reactos/subsys/system/explorer/doc/TODO.txt +++ b/reactos/subsys/system/explorer/doc/TODO.txt @@ -7,6 +7,7 @@ - Drag Drop on desktop does not work. - implement Drag Drop from the tree view. - activate accelerator keys like in shell view folders +- short cut Ctrl+ESC to activate start menu - progman DDE server - command line parameters like "/e,/root,c:\" - Windows-key combos diff --git a/reactos/subsys/system/explorer/doc/changes.txt b/reactos/subsys/system/explorer/doc/changes.txt index b011e14ee28..c1c11578e47 100644 --- a/reactos/subsys/system/explorer/doc/changes.txt +++ b/reactos/subsys/system/explorer/doc/changes.txt @@ -16,3 +16,4 @@ open child folders by double click in ShellBrowserChild 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 +18.08.2003 m. fuchs first draft of explorer start menu diff --git a/reactos/subsys/system/explorer/explorer.cpp b/reactos/subsys/system/explorer/explorer.cpp index af6c81d8ae5..36cbc024ad8 100644 --- a/reactos/subsys/system/explorer/explorer.cpp +++ b/reactos/subsys/system/explorer/explorer.cpp @@ -80,13 +80,8 @@ void explorer_show_frame(HWND hwndDesktop, int cmdshow) g_Globals._prescan_nodes = false; - HMENU hMenuFrame = LoadMenu(g_Globals._hInstance, MAKEINTRESOURCE(IDM_MAINFRAME)); - // create main window - g_Globals._hMainWnd = Window::Create(WINDOW_CREATOR(MainFrame), 0, - (LPCTSTR)(int)g_Globals._hframeClass, ResString(IDS_TITLE), WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - 0/*hwndDesktop*/, hMenuFrame); + g_Globals._hMainWnd = MainFrame::Create(); ShowWindow(g_Globals._hMainWnd, cmdshow); @@ -102,7 +97,7 @@ static void InitInstance(HINSTANCE hInstance) setlocale(LC_COLLATE, ""); // set collating rules to local settings for compareName // register frame window class - g_Globals._hframeClass = IconWindowClass(CLASSNAME_FRAME,IDI_EXPLORER).Register(); + g_Globals._hframeClass = IconWindowClass(CLASSNAME_FRAME,IDI_EXPLORER); // register child windows class WindowClass(CLASSNAME_CHILDWND, CS_CLASSDC|CS_DBLCLKS|CS_VREDRAW).Register(); @@ -168,7 +163,7 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL if (startup_desktop) { - hwndDesktop = create_desktop_window(hInstance); + hwndDesktop = create_desktop_window(); // Initialize the explorer bar HWND hwndExplorerBar = InitializeExplorerBar(hInstance); diff --git a/reactos/subsys/system/explorer/explorer.dsp b/reactos/subsys/system/explorer/explorer.dsp index 0537967f482..2682570d12f 100644 --- a/reactos/subsys/system/explorer/explorer.dsp +++ b/reactos/subsys/system/explorer/explorer.dsp @@ -295,6 +295,14 @@ SOURCE=.\res\images.bmp # End Source File # Begin Source File +SOURCE=.\res\logoff.ico +# End Source File +# Begin Source File + +SOURCE=.\res\reactos.ico +# End Source File +# Begin Source File + SOURCE=.\resource.rc !IF "$(CFG)" == "explorer - Win32 Release" @@ -324,6 +332,14 @@ SOURCE=.\resource.rc # End Source File # Begin Source File +SOURCE=.\res\startmenu.bmp +# End Source File +# Begin Source File + +SOURCE=.\res\startmenu.ico +# End Source File +# Begin Source File + SOURCE=.\res\toolbar.bmp # End Source File # End Group @@ -367,6 +383,9 @@ SOURCE=.\doc\readme.txt SOURCE=.\doc\TODO.txt # End Source File # End Group +# Begin Group "shell" + +# PROP Default_Filter "" # Begin Source File SOURCE=.\shell\entries.cpp @@ -377,18 +396,6 @@ SOURCE=.\shell\entries.h # End Source File # Begin Source File -SOURCE=.\explorer.cpp -# End Source File -# Begin Source File - -SOURCE=.\explorer.h -# End Source File -# Begin Source File - -SOURCE=.\externals.h -# End Source File -# Begin Source File - SOURCE=.\shell\filechild.cpp # End Source File # Begin Source File @@ -397,18 +404,6 @@ SOURCE=.\shell\filechild.h # End Source File # Begin Source File -SOURCE=.\globals.h -# End Source File -# Begin Source File - -SOURCE=.\res\icon1.ico -# End Source File -# Begin Source File - -SOURCE=.\res\logoff.ico -# End Source File -# Begin Source File - SOURCE=.\shell\mainframe.cpp # End Source File # Begin Source File @@ -425,10 +420,6 @@ SOURCE=.\shell\pane.h # End Source File # Begin Source File -SOURCE=.\res\reactos.ico -# End Source File -# Begin Source File - SOURCE=.\shell\shellbrowser.cpp # End Source File # Begin Source File @@ -445,14 +436,6 @@ SOURCE=.\shell\shellfs.h # End Source File # Begin Source File -SOURCE=.\res\startmenu.bmp -# End Source File -# Begin Source File - -SOURCE=.\res\startmenu.ico -# End Source File -# Begin Source File - SOURCE=.\shell\startup.c # End Source File # Begin Source File @@ -471,5 +454,22 @@ SOURCE=.\shell\winfs.cpp SOURCE=.\shell\winfs.h # End Source File +# End Group +# Begin Source File + +SOURCE=.\explorer.cpp +# End Source File +# Begin Source File + +SOURCE=.\explorer.h +# End Source File +# Begin Source File + +SOURCE=.\externals.h +# End Source File +# Begin Source File + +SOURCE=.\globals.h +# End Source File # End Target # End Project diff --git a/reactos/subsys/system/explorer/explorer_intres.h b/reactos/subsys/system/explorer/explorer_intres.h index bab365d3a10..4d68a29b2a3 100644 --- a/reactos/subsys/system/explorer/explorer_intres.h +++ b/reactos/subsys/system/explorer/explorer_intres.h @@ -5,6 +5,15 @@ #define IDS_TITLE 1 #define IDS_START 2 #define IDS_LOGOFF 3 +#define IDS_SHUTDOWN 4 +#define IDS_LAUNCH 5 +#define IDS_START_HELP 6 +#define IDS_SEARCH 7 +#define IDS_DOCUMENTS 8 +#define IDS_FAVORITES 9 +#define IDS_PROGRAMS 10 +#define IDS_SETTINGS 11 +#define IDS_EXPLORE 12 #define IDI_REACTOS 100 #define IDI_EXPLORER 101 #define IDI_STARTMENU 102 diff --git a/reactos/subsys/system/explorer/explorer_intres.rc b/reactos/subsys/system/explorer/explorer_intres.rc index a700a651da5..7728ae0c9be 100644 --- a/reactos/subsys/system/explorer/explorer_intres.rc +++ b/reactos/subsys/system/explorer/explorer_intres.rc @@ -241,7 +241,16 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TITLE "Reactos Explorer" IDS_START "Start" - IDS_LOGOFF "Logoff" + IDS_LOGOFF "Log Off..." + IDS_SHUTDOWN "Turn Off..." + IDS_LAUNCH "Run..." + IDS_START_HELP "Help" + IDS_SEARCH "Search..." + IDS_DOCUMENTS "Documents" + IDS_FAVORITES "Favorites" + IDS_PROGRAMS "Programs" + IDS_SETTINGS "Settings" + IDS_EXPLORE "Explore" END #endif // German (Germany) resources diff --git a/reactos/subsys/system/explorer/externals.h b/reactos/subsys/system/explorer/externals.h index acd10ac865f..b7babf56d1e 100644 --- a/reactos/subsys/system/explorer/externals.h +++ b/reactos/subsys/system/explorer/externals.h @@ -41,7 +41,7 @@ extern int explorer_main(HINSTANCE hinstance, HWND hwndDesktop, int cmdshow); extern void explorer_show_frame(HWND hwndDesktop, int cmdshow); // create desktop window -extern HWND create_desktop_window(HINSTANCE hInstance); +extern HWND create_desktop_window(); // test for already running desktop instance extern BOOL IsAnyDesktopRunning(); diff --git a/reactos/subsys/system/explorer/shell/entries.h b/reactos/subsys/system/explorer/shell/entries.h index ea59de12c95..a36f3b78916 100644 --- a/reactos/subsys/system/explorer/shell/entries.h +++ b/reactos/subsys/system/explorer/shell/entries.h @@ -48,7 +48,7 @@ protected: Entry(Entry* parent); public: - ~Entry(); + virtual ~Entry(); Entry* _next; Entry* _down; @@ -84,8 +84,9 @@ public: struct Directory { protected: + Directory() : _path(NULL) {} Directory(void* path) : _path(path) {} - ~Directory() {free(_path);} + virtual ~Directory() {} void* _path; }; @@ -102,4 +103,3 @@ struct Root { DWORD _drive_type; DWORD _fs_flags; }; - diff --git a/reactos/subsys/system/explorer/shell/filechild.cpp b/reactos/subsys/system/explorer/shell/filechild.cpp index 734d3f0c3dc..01f50affe30 100644 --- a/reactos/subsys/system/explorer/shell/filechild.cpp +++ b/reactos/subsys/system/explorer/shell/filechild.cpp @@ -81,7 +81,7 @@ FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info) lstrcpy(_root._fs, TEXT("Shell")); const ShellChildWndInfo& shell_info = static_cast(info); - _root._entry = new ShellDirectory(ShellFolder(shell_info._root_shell_path), shell_info._shell_path, hwnd); + _root._entry = new ShellDirectory(Desktop(), shell_info._shell_path, hwnd); entry = _root._entry->read_tree((LPCTSTR)&*shell_info._shell_path, SORT_NAME/*_sortOrder*/); } else @@ -251,7 +251,7 @@ FileChildWindow* FileChildWindow::create(HWND hmdiclient, const FileChildWndInfo mcs.lParam = 0; FileChildWindow* child = static_cast( - create_mdi_child(hmdiclient, mcs, WINDOW_CREATOR_INFO(FileChildWindow, FileChildWndInfo), &info)); + create_mdi_child(hmdiclient, mcs, WINDOW_CREATOR_INFO(FileChildWindow,FileChildWndInfo), &info)); return child; } diff --git a/reactos/subsys/system/explorer/shell/mainframe.cpp b/reactos/subsys/system/explorer/shell/mainframe.cpp index d9d09616757..14059353ae0 100644 --- a/reactos/subsys/system/explorer/shell/mainframe.cpp +++ b/reactos/subsys/system/explorer/shell/mainframe.cpp @@ -157,6 +157,17 @@ MainFrame::~MainFrame() } +HWND MainFrame::Create() +{ + HMENU hMenuFrame = LoadMenu(g_Globals._hInstance, MAKEINTRESOURCE(IDM_MAINFRAME)); + + return super::Create(WINDOW_CREATOR(MainFrame), 0, + (LPCTSTR)(int)g_Globals._hframeClass, ResString(IDS_TITLE), WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + 0/*hwndDesktop*/, hMenuFrame); +} + + LRESULT MainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) { switch(nmsg) { diff --git a/reactos/subsys/system/explorer/shell/mainframe.h b/reactos/subsys/system/explorer/shell/mainframe.h index 768442459ce..090235b2dc3 100644 --- a/reactos/subsys/system/explorer/shell/mainframe.h +++ b/reactos/subsys/system/explorer/shell/mainframe.h @@ -33,6 +33,8 @@ struct MainFrame : public PreTranslateWindow MainFrame(HWND hwnd); ~MainFrame(); + static HWND Create(); + protected: FullScreenParameters _fullscreen; diff --git a/reactos/subsys/system/explorer/shell/pane.h b/reactos/subsys/system/explorer/shell/pane.h index 37d71c87bd9..dae21988184 100644 --- a/reactos/subsys/system/explorer/shell/pane.h +++ b/reactos/subsys/system/explorer/shell/pane.h @@ -48,7 +48,8 @@ enum COLUMN_FLAGS { }; -struct OutputWorker { +struct OutputWorker +{ OutputWorker(); void init_output(HWND hwnd); diff --git a/reactos/subsys/system/explorer/shell/shellfs.h b/reactos/subsys/system/explorer/shell/shellfs.h index 1c9addb0124..c9ffd9ab1da 100644 --- a/reactos/subsys/system/explorer/shell/shellfs.h +++ b/reactos/subsys/system/explorer/shell/shellfs.h @@ -26,7 +26,8 @@ // -struct ShellEntry : public Entry { +struct ShellEntry : public Entry +{ ShellEntry(Entry* parent, LPITEMIDLIST shell_path) : Entry(parent), _pidl(shell_path) {} ShellEntry(Entry* parent, const ShellPath& shell_path) : Entry(parent), _pidl(shell_path) {} @@ -42,12 +43,17 @@ protected: ShellEntry(const ShellPath& shell_path) : Entry(ET_SHELL), _pidl(shell_path) {} }; -struct ShellDirectory : public ShellEntry, public Directory { +struct ShellDirectory : public ShellEntry, public Directory +{ ShellDirectory(IShellFolder* shell_root, const ShellPath& shell_path, HWND hwnd) : ShellEntry(shell_path), - Directory(shell_root), + _folder(shell_root, shell_path), _hwnd(hwnd) { + ShellFolder folder(shell_root, shell_path); + IShellFolder* pFolder = folder; + pFolder->AddRef(); + _path = pFolder; } ShellDirectory(ShellDirectory* parent, IShellFolder* shell_root, LPITEMIDLIST shell_path, HWND hwnd) @@ -56,6 +62,14 @@ struct ShellDirectory : public ShellEntry, public Directory { _folder(shell_root), _hwnd(hwnd) { + shell_root->AddRef(); + } + + ~ShellDirectory() + { + IShellFolder* pFolder = (IShellFolder*)_path; + _path = NULL; + pFolder->Release(); } virtual void read_directory(); @@ -70,4 +84,3 @@ struct ShellDirectory : public ShellEntry, public Directory { protected: bool fill_w32fdata_shell(LPCITEMIDLIST pidl, SFGAOF attribs, WIN32_FIND_DATA*, BY_HANDLE_FILE_INFORMATION*); }; - diff --git a/reactos/subsys/system/explorer/shell/unixfs.h b/reactos/subsys/system/explorer/shell/unixfs.h index bbf7ff993f8..09f8c2ea146 100644 --- a/reactos/subsys/system/explorer/shell/unixfs.h +++ b/reactos/subsys/system/explorer/shell/unixfs.h @@ -28,7 +28,8 @@ #ifdef __linux__ -struct UnixEntry : public Entry { +struct UnixEntry : public Entry +{ UnixEntry(Entry* parent) : Entry(parent) {} protected: @@ -37,7 +38,8 @@ protected: virtual void get_path(PTSTR path); }; -struct UnixDirectory : public UnixEntry, public Directory { +struct UnixDirectory : public UnixEntry, public Directory +{ UnixDirectory(LPCTSTR root_path) : UnixEntry(), Directory(_tcsdup(root_path)) diff --git a/reactos/subsys/system/explorer/shell/winfs.h b/reactos/subsys/system/explorer/shell/winfs.h index 0146fd3bb5d..6b694a3f538 100644 --- a/reactos/subsys/system/explorer/shell/winfs.h +++ b/reactos/subsys/system/explorer/shell/winfs.h @@ -26,7 +26,8 @@ // -struct WinEntry : public Entry { +struct WinEntry : public Entry +{ WinEntry(Entry* parent) : Entry(parent) {} protected: @@ -35,7 +36,8 @@ protected: virtual void get_path(PTSTR path); }; -struct WinDirectory : public WinEntry, public Directory { +struct WinDirectory : public WinEntry, public Directory +{ WinDirectory(LPCTSTR root_path) : WinEntry(), Directory(_tcsdup(root_path)) @@ -48,8 +50,13 @@ struct WinDirectory : public WinEntry, public Directory { { } + ~WinDirectory() + { + free(_path); + _path = NULL; + } + virtual void read_directory(); virtual const void* get_next_path_component(const void*); virtual Entry* find_entry(const void*); }; - diff --git a/reactos/subsys/system/explorer/taskbar/taskbar.cpp b/reactos/subsys/system/explorer/taskbar/taskbar.cpp index 8e3a531e422..6896805ef98 100644 --- a/reactos/subsys/system/explorer/taskbar/taskbar.cpp +++ b/reactos/subsys/system/explorer/taskbar/taskbar.cpp @@ -39,6 +39,16 @@ #define IDC_START 0x1000 #define IDC_LOGOFF 0x1001 +#define IDC_SHUTDOWN 0x1002 +#define IDC_LAUNCH 0x1003 +#define IDC_START_HELP 0x1004 +#define IDC_SEARCH 0x1005 +#define IDC_SETTINGS 0x1006 +#define IDC_DOCUMENTS 0x1007 +#define IDC_FAVORITES 0x1008 +#define IDC_PROGRAMS 0x1009 +#define IDC_EXPLORE 0x100A + #define IDC_FIRST_APP 0x2000 #define IDC_FIRST_MENU 0x3000 @@ -57,7 +67,7 @@ HWND InitializeExplorerBar(HINSTANCE hInstance) rect.bottom = rect.top + TASKBAR_HEIGHT + 2; return Window::Create(WINDOW_CREATOR(DesktopBar), WS_EX_PALETTEWINDOW, - (LPCTSTR)(int)BtnWindowClass(CLASSNAME_EXPLORERBAR).Register(), TITLE_EXPLORERBAR, + 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); } @@ -85,11 +95,11 @@ LRESULT DesktopBar::Init(LPCREATESTRUCT pcs) // create start button new PictureButton(Button(_hwnd, ResString(IDS_START), 2, 2, STARTBUTTON_WIDTH, TASKBAR_HEIGHT-8, IDC_START, WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_OWNERDRAW), - ResIcon(IDI_STARTMENU)); + SmallIcon(IDI_STARTMENU)); // create task bar _hwndTaskBar = Window::Create(WINDOW_CREATOR(TaskBar), 0, - (LPCTSTR)(int)BtnWindowClass(CLASSNAME_TASKBAR).Register(), TITLE_TASKBAR, WS_CHILD|WS_VISIBLE, + BtnWindowClass(CLASSNAME_TASKBAR), TITLE_TASKBAR, WS_CHILD|WS_VISIBLE, TASKBAR_LEFT, 0, ClientRect(_hwnd).right-TASKBAR_LEFT, TASKBAR_HEIGHT, _hwnd); TaskBar* taskbar = static_cast(Window::get_window(_hwndTaskBar)); @@ -104,12 +114,7 @@ void DesktopBar::create_startmenu() { WindowRect my_pos(_hwnd); - static BtnWindowClass wcStartMenu(CLASSNAME_STARTMENU); - - _hwndStartMenu = Window::Create(WINDOW_CREATOR(StartMenu), 0, - (LPCTSTR)(int)wcStartMenu.Register(), TITLE_STARTMENU, - WS_POPUP|WS_THICKFRAME|WS_CLIPCHILDREN|WS_VISIBLE, - my_pos.left, my_pos.top-STARTMENU_HEIGHT, STARTMENU_WIDTH, STARTMENU_HEIGHT, _hwnd); + _hwndStartMenu = StartMenuRoot::Create(my_pos.left, my_pos.top-4, _hwnd); } @@ -475,30 +480,74 @@ TaskBarMap::iterator TaskBarMap::find_id(int id) } +BtnWindowClass StartMenu::s_wcStartMenu(CLASSNAME_STARTMENU); + StartMenu::StartMenu(HWND hwnd) : super(hwnd) { + _next_id = IDC_FIRST_MENU; } -StartMenu::~StartMenu() +StartMenu::StartMenu(HWND hwnd, const StartMenuFolders& info) + : super(hwnd) { + for(StartMenuFolders::const_iterator it=info.begin(); it!=info.end(); ++it) + _dirs.push_back(ShellDirectory(Desktop(), *it, _hwnd)); } + +/* +HWND StartMenu::Create(int x, int y, HWND hwndParent) +{ + return Window::Create(WINDOW_CREATOR(StartMenu), NULL, s_wcStartMenu, TITLE_STARTMENU, + WS_POPUP|WS_THICKFRAME|WS_CLIPCHILDREN|WS_VISIBLE, x, y, STARTMENU_WIDTH, 4, hwndParent); +} +*/ + +HWND StartMenu::Create(int x, int y, const StartMenuFolders& folders, HWND hwndParent) +{ + return Window::Create(WINDOW_CREATOR_INFO(StartMenu,StartMenuFolders), &folders, 0, s_wcStartMenu, NULL, + WS_POPUP|WS_THICKFRAME|WS_CLIPCHILDREN|WS_VISIBLE, x, y, STARTMENU_WIDTH, 4, hwndParent); +} + + LRESULT StartMenu::Init(LPCREATESTRUCT pcs) { if (super::Init(pcs)) return 1; - ClientRect clnt(_hwnd); + WaitCursor wait; + + for(StartMenuShellDirs::iterator it=_dirs.begin(); it!=_dirs.end(); ++it) { + ShellDirectory& dir = *it; - SetWindowFont(*new PictureButton(Button(_hwnd, ResString(IDS_LOGOFF), 2, clnt.bottom-STARTMENU_LINE_HEIGHT, clnt.right-2, STARTMENU_LINE_HEIGHT, - IDC_LOGOFF, WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_OWNERDRAW), - ResIcon(IDI_LOGOFF)), - GetStockFont(DEFAULT_GUI_FONT), FALSE); + dir.smart_scan(); + + AddShellEntries(dir); + } return 0; } +void StartMenu::AddShellEntries(const ShellDirectory& dir, bool subfolders) +{ + for(const Entry*entry=dir._down; entry; entry=entry->_next) { + if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) + continue; + + HICON hIcon = entry->_hicon; + + if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if (!subfolders) + continue; + + hIcon = SmallIcon(IDI_EXPLORER); + } + + AddButton(dir._folder.get_name(&*static_cast(entry)->_pidl).c_str(), hIcon); + } +} + LRESULT StartMenu::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) { /*@@ @@ -508,21 +557,110 @@ LRESULT StartMenu::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) } return 0; -*/ - return super::WndProc(nmsg, wparam, lparam); +*/ return super::WndProc(nmsg, wparam, lparam); } int StartMenu::Command(int id, int code) { switch(id) { - case IDC_LOGOFF: - DestroyWindow(GetParent(_hwnd)); - break; - case IDCANCEL: DestroyWindow(_hwnd); break; + + default: + return super::Command(id, code); } - return super::Command(id, code); + return 0; +} + +void StartMenu::AddButton(LPCTSTR text, HICON hIcon, UINT id) +{ + if (id == (UINT)-1) + id = ++_next_id; + + WindowRect rect(_hwnd); + + rect.top -= STARTMENU_LINE_HEIGHT; + + if (rect.top < 0) { + rect.top += STARTMENU_LINE_HEIGHT; + rect.bottom += STARTMENU_LINE_HEIGHT; + } + + MoveWindow(_hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE); + + StartMenuButton(_hwnd, rect.bottom-rect.top-STARTMENU_LINE_HEIGHT-4, text, id, hIcon); +} + + +StartMenuRoot::StartMenuRoot(HWND hwnd) + : super(hwnd) +{ +} + +HWND StartMenuRoot::Create(int x, int y, HWND hwndParent) +{ + return Window::Create(WINDOW_CREATOR(StartMenuRoot), 0, s_wcStartMenu, TITLE_STARTMENU, + WS_POPUP|WS_THICKFRAME|WS_CLIPCHILDREN|WS_VISIBLE, x, y, STARTMENU_WIDTH, 4, hwndParent); +} + +LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs) +{ + if (super::Init(pcs)) + return 1; + + WaitCursor wait; + + // insert start menu entries links from "All Users\Start Menu" and "\Start Menu" + ShellDirectory cmn_startmenu(Desktop(), SpecialFolder(CSIDL_COMMON_STARTMENU, _hwnd), _hwnd); + cmn_startmenu.read_directory(); + AddShellEntries(cmn_startmenu, false); + + ShellDirectory usr_startmenu(Desktop(), SpecialFolder(CSIDL_STARTMENU, _hwnd), _hwnd); + usr_startmenu.read_directory(); + AddShellEntries(usr_startmenu, false); + + // insert hard coded start entries + //AddButton(ResString(IDS_PROGRAMS),0, IDC_PROGRAMS); + AddButton(ResString(IDS_EXPLORE), SmallIcon(IDI_EXPLORER), IDC_EXPLORE); + AddButton(ResString(IDS_FAVORITES), 0, IDC_FAVORITES); + AddButton(ResString(IDS_DOCUMENTS), 0, IDC_DOCUMENTS); + AddButton(ResString(IDS_SETTINGS), 0, IDC_SETTINGS); + AddButton(ResString(IDS_SEARCH), 0, IDC_SEARCH); + AddButton(ResString(IDS_START_HELP),0, IDC_START_HELP); + AddButton(ResString(IDS_LAUNCH), 0, IDC_LAUNCH); + AddButton(ResString(IDS_SHUTDOWN), SmallIcon(IDI_LOGOFF), IDC_SHUTDOWN); + AddButton(ResString(IDS_LOGOFF), SmallIcon(IDI_LOGOFF), IDC_LOGOFF); + + + //TEST: open programs menu folder + StartMenuFolders prg_folders; + + prg_folders.push_back(SpecialFolder(CSIDL_COMMON_PROGRAMS, _hwnd)); + prg_folders.push_back(SpecialFolder(CSIDL_PROGRAMS, _hwnd)); + + WindowRect my_pos(_hwnd); + StartMenu::Create(my_pos.right, my_pos.top+STARTMENU_HEIGHT-4, prg_folders, _hwnd); + + + return 0; +} + +int StartMenuRoot::Command(int id, int code) +{ + switch(id) { + case IDC_LOGOFF: + DestroyWindow(GetParent(_hwnd)); //TODO: show dialog and ask for acknowledge + break; + + case IDC_SHUTDOWN: + DestroyWindow(GetParent(_hwnd)); //TODO: show dialog box and shut down system + break; + + default: + return super::Command(id, code); + } + + return 0; } diff --git a/reactos/subsys/system/explorer/taskbar/taskbar.h b/reactos/subsys/system/explorer/taskbar/taskbar.h index e3ece5d74f4..afbd1679c25 100644 --- a/reactos/subsys/system/explorer/taskbar/taskbar.h +++ b/reactos/subsys/system/explorer/taskbar/taskbar.h @@ -26,6 +26,8 @@ // +#include + //#include "shellhook.h" @@ -35,8 +37,8 @@ //#define TASKBAR_AT_TOP #define STARTMENU_WIDTH 150 -#define STARTMENU_HEIGHT 400 -#define STARTMENU_LINE_HEIGHT 30 +#define STARTMENU_HEIGHT 4 +#define STARTMENU_LINE_HEIGHT 22 #define WM_SHELLHOOK_NOTIFY (WM_APP+0x10) @@ -72,6 +74,7 @@ protected: #define IDW_TASKTOOLBAR 100 + // internal task bar button management entry struct TaskBarEntry { TaskBarEntry(); @@ -85,6 +88,7 @@ struct TaskBarEntry BYTE _fsState; }; + // map for managing the task bar buttons struct TaskBarMap : public map { ~TaskBarMap(); @@ -92,6 +96,7 @@ struct TaskBarMap : public map iterator find_id(int id); }; + // Taskbar window struct TaskBar : public Window { typedef Window super; @@ -116,15 +121,60 @@ protected: void Refresh(); }; + + // Startmenu button +struct StartMenuButton : public Button +{ + StartMenuButton(HWND parent, int y, LPCTSTR text, + UINT id, HICON hIcon, DWORD style=WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_OWNERDRAW, DWORD exStyle=0) + : Button(parent, text, 2, y, STARTMENU_WIDTH-4, STARTMENU_LINE_HEIGHT, id, style, exStyle) + { + *new StartmenuEntry(_hwnd, hIcon); + + SetWindowFont(_hwnd, GetStockFont(DEFAULT_GUI_FONT), FALSE); + } +}; + + +typedef list StartMenuFolders; +typedef list StartMenuShellDirs; + + // Startmenu window struct StartMenu : public OwnerDrawParent { typedef OwnerDrawParent super; StartMenu(HWND hwnd); - ~StartMenu(); + StartMenu(HWND hwnd, const StartMenuFolders& info); + + static HWND Create(int x, int y, HWND hwndParent=0); + static HWND Create(int x, int y, const StartMenuFolders&, HWND hwndParent=0); protected: + int _next_id; + StartMenuShellDirs _dirs; + + static BtnWindowClass s_wcStartMenu; + LRESULT Init(LPCREATESTRUCT pcs); LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); int Command(int id, int code); + + void AddButton(LPCTSTR text, HICON hIcon=0, UINT id=(UINT)-1); + void AddShellEntries(const ShellDirectory& dir, bool subfolders=true); +}; + + + // Startmenu root window +struct StartMenuRoot : public StartMenu +{ + typedef StartMenu super; + + StartMenuRoot(HWND hwnd); + + static HWND Create(int x, int y, HWND hwndParent=0); + +protected: + LRESULT Init(LPCREATESTRUCT pcs); + int Command(int id, int code); }; diff --git a/reactos/subsys/system/explorer/utility/shellclasses.cpp b/reactos/subsys/system/explorer/utility/shellclasses.cpp index d4e7385b75c..a2487075004 100644 --- a/reactos/subsys/system/explorer/utility/shellclasses.cpp +++ b/reactos/subsys/system/explorer/utility/shellclasses.cpp @@ -126,10 +126,11 @@ ShellFolder::ShellFolder() CheckError(SHGetDesktopFolder(&desktop)); super::Attach(desktop); + desktop->AddRef(); } ShellFolder::ShellFolder(IShellFolder* p) - : IShellFolderPtr(p) + : IShellFolderPtr(p) { } @@ -143,6 +144,7 @@ ShellFolder::ShellFolder(IShellFolder* parent, LPCITEMIDLIST pidl) ptr = parent; super::Attach(ptr); + ptr->AddRef(); } ShellFolder::ShellFolder(LPCITEMIDLIST pidl) @@ -155,7 +157,8 @@ ShellFolder::ShellFolder(LPCITEMIDLIST pidl) else ptr = parent; - super::Attach(Desktop()); + super::Attach(ptr); + ptr->AddRef(); } void ShellFolder::attach(IShellFolder* parent, LPCITEMIDLIST pidl) @@ -168,17 +171,7 @@ void ShellFolder::attach(IShellFolder* parent, LPCITEMIDLIST pidl) ptr = parent; super::Attach(ptr); -} - -string ShellFolder::get_name(LPITEMIDLIST pidl, SHGDNF flags) -{ - char buffer[MAX_PATH]; - StrRetA strret; - - CheckError(((IShellFolder*)*this)->GetDisplayNameOf(pidl, flags, &strret)); - strret.GetString(pidl->mkid, buffer, MAX_PATH); - - return buffer; + ptr->AddRef(); } #else // _com_ptr not available -> use SIfacePtr @@ -189,7 +182,7 @@ ShellFolder::ShellFolder() } ShellFolder::ShellFolder(IShellFolder* p) - : SIfacePtr(p) + : SIfacePtr(p) { } @@ -217,6 +210,17 @@ void ShellFolder::attach(IShellFolder* parent, LPCITEMIDLIST pidl) #endif +String ShellFolder::get_name(LPCITEMIDLIST pidl, SHGDNF flags) const +{ + TCHAR buffer[MAX_PATH]; + StrRet strret; + + CheckError(((IShellFolder*)*const_cast(this))->GetDisplayNameOf(pidl, flags, &strret)); + strret.GetString(pidl->mkid, buffer, MAX_PATH); + + return buffer; +} + // helper function for string copying diff --git a/reactos/subsys/system/explorer/utility/shellclasses.h b/reactos/subsys/system/explorer/utility/shellclasses.h index b22570b8ef8..a468d031fa9 100644 --- a/reactos/subsys/system/explorer/utility/shellclasses.h +++ b/reactos/subsys/system/explorer/utility/shellclasses.h @@ -361,7 +361,7 @@ struct ShellFolder : public IShellFolderPtr // IShellFolderPtr uses intrinsic ex ShellFolder(LPCITEMIDLIST pidl); void attach(IShellFolder* parent, LPCITEMIDLIST pidl); - string get_name(LPITEMIDLIST pidl, SHGDNF flags=SHGDN_NORMAL); + String get_name(LPCITEMIDLIST pidl, SHGDNF flags=SHGDN_NORMAL) const; bool empty() const {return !operator bool();} //NOTE: see SIfacePtr::empty() }; @@ -377,7 +377,8 @@ struct ShellFolder : public SIfacePtr ShellFolder(IShellFolder* parent, LPCITEMIDLIST pidl); ShellFolder(LPCITEMIDLIST pidl); - void attach(IShellFolder* parent, LPCITEMIDLIST pidl); + void attach(IShellFolder* parent, LPCITEMIDLIST pidl); + String get_name(LPCITEMIDLIST pidl, SHGDNF flags=SHGDN_NORMAL) const; }; #endif @@ -720,7 +721,7 @@ struct SpecialFolder : public ShellPath { SpecialFolder(int folder, HWND hwnd) { - SHGetSpecialFolderLocation(hwnd, folder, &_p); + HRESULT hr = SHGetSpecialFolderLocation(hwnd, folder, &_p); } }; @@ -759,7 +760,7 @@ struct SpecialFolderPath : public FileSysShellPath { SpecialFolderPath(int folder, HWND hwnd) { - SHGetSpecialFolderLocation(hwnd, folder, &_p); + HRESULT hr = SHGetSpecialFolderLocation(hwnd, folder, &_p); } }; diff --git a/reactos/subsys/system/explorer/utility/shelltests.cpp b/reactos/subsys/system/explorer/utility/shelltests.cpp index 8362de8d797..b0878b19830 100644 --- a/reactos/subsys/system/explorer/utility/shelltests.cpp +++ b/reactos/subsys/system/explorer/utility/shelltests.cpp @@ -26,10 +26,11 @@ // -#define WIN32_LEAN_AND_MEAN -#define WIN32_EXTRA_LEAN -#include +//#define WIN32_LEAN_AND_MEAN +//#define WIN32_EXTRA_LEAN +//#include +#include "utility.h" // for String #include "shellclasses.h" diff --git a/reactos/subsys/system/explorer/utility/utility.h b/reactos/subsys/system/explorer/utility/utility.h index 1b0e6ea6d62..d233c66e17d 100644 --- a/reactos/subsys/system/explorer/utility/utility.h +++ b/reactos/subsys/system/explorer/utility/utility.h @@ -162,6 +162,16 @@ struct String : public string #endif { +#ifdef UNICODE + typedef wstring super; +#else + typedef string super; +#endif + + String() {} + String(LPCTSTR s) : super(s) {} + String(const String& other) : super(other) {} + String& operator=(LPCTSTR s) {assign(s); return *this;} operator LPCTSTR() const {return c_str();} }; diff --git a/reactos/subsys/system/explorer/utility/window.cpp b/reactos/subsys/system/explorer/utility/window.cpp index 0d59fe77467..8d2755871e9 100644 --- a/reactos/subsys/system/explorer/utility/window.cpp +++ b/reactos/subsys/system/explorer/utility/window.cpp @@ -460,9 +460,9 @@ int Window::MessageLoop() Button::Button(HWND parent, LPCTSTR text, int left, int top, int width, int height, - UINT id, DWORD flags, DWORD ex_flags) + UINT id, DWORD flags, DWORD exStyle) { - _hwnd = CreateWindowEx(ex_flags, TEXT("BUTTON"), text, flags, left, top, width, height, + _hwnd = CreateWindowEx(exStyle, TEXT("BUTTON"), text, flags, left, top, width, height, parent, (HMENU)id, g_Globals._hInstance, 0); } @@ -556,7 +556,7 @@ LRESULT PictureButton::WndProc(UINT message, WPARAM wparam, LPARAM lparam) style |= DFCS_INACTIVE; POINT iconPos = {dis->rcItem.left+2, (dis->rcItem.top+dis->rcItem.bottom-16)/2}; - RECT textRect = {dis->rcItem.left+16+2, dis->rcItem.top+2, dis->rcItem.right-4, dis->rcItem.bottom-4}; + RECT textRect = {dis->rcItem.left+16+4, dis->rcItem.top+2, dis->rcItem.right-4, dis->rcItem.bottom-4}; if (dis->itemState & ODS_SELECTED) { style |= DFCS_PUSHED; @@ -565,10 +565,10 @@ LRESULT PictureButton::WndProc(UINT message, WPARAM wparam, LPARAM lparam) ++textRect.right; ++textRect.bottom; } -/*@@ if (_flat) { - if (GetWindowStyle(_hwnd) & BS_FLAT) // Nur wenn zusätzlich BS_FLAT gesetzt ist, wird ohne Highlight ein Rahmen gezeichnet. + if (_flat) { + if (GetWindowStyle(_hwnd) & BS_FLAT) // Only with BS_FLAT set, there will be drawn a frame without highlight. DrawEdge(dis->hDC, &dis->rcItem, EDGE_RAISED, BF_RECT|BF_FLAT); - } else*/ + } else DrawFrameControl(dis->hDC, &dis->rcItem, DFC_BUTTON, style); DrawIconEx(dis->hDC, iconPos.x, iconPos.y, _hicon, 16, 16, 0, GetSysColorBrush(COLOR_BTNFACE), DI_NORMAL); @@ -583,16 +583,16 @@ LRESULT PictureButton::WndProc(UINT message, WPARAM wparam, LPARAM lparam) { TextColor lcColor(dis->hDC, GetSysColor(COLOR_BTNHIGHLIGHT)); RECT shadowRect = {textRect.left+1, textRect.top+1, textRect.right+1, textRect.bottom+1}; - DrawText(dis->hDC, text, -1, &shadowRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); + DrawText(dis->hDC, text, -1, &shadowRect, DT_SINGLELINE|DT_VCENTER/*|DT_CENTER*/); } BkMode mode(dis->hDC, TRANSPARENT); TextColor lcColor(dis->hDC, gray); - DrawText(dis->hDC, text, -1, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); + DrawText(dis->hDC, text, -1, &textRect, DT_SINGLELINE|DT_VCENTER/*|DT_CENTER*/); } else { int old_r = textRect.right; int old_b = textRect.bottom; - DrawText(dis->hDC, text, -1, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER|DT_CALCRECT); + DrawText(dis->hDC, text, -1, &textRect, DT_SINGLELINE|DT_VCENTER/*|DT_CENTER*/|DT_CALCRECT); int x = textRect.left + (old_r-textRect.right)/2; int y = textRect.top + (old_b-textRect.bottom)/2; int w = textRect.right-textRect.left; @@ -602,8 +602,9 @@ LRESULT PictureButton::WndProc(UINT message, WPARAM wparam, LPARAM lparam) GrayString(dis->hDC, GetSysColorBrush(COLOR_GRAYTEXT), MyDrawText, (LPARAM)text, -1, x, y, w, h); } } else { - //TextColor lcColor(dis->hDC, _textColor); - DrawText(dis->hDC, text, -1, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); + //BkMode mode(dis->hDC, TRANSPARENT); + TextColor lcColor(dis->hDC, GetSysColor(COLOR_BTNTEXT)); + DrawText(dis->hDC, text, -1, &textRect, DT_SINGLELINE|DT_VCENTER/*|DT_CENTER*/); } if (dis->itemState & ODS_FOCUS) { @@ -622,3 +623,75 @@ LRESULT PictureButton::WndProc(UINT message, WPARAM wparam, LPARAM lparam) } else return super::WndProc(message, wparam, lparam); } + + +LRESULT StartmenuEntry::WndProc(UINT message, WPARAM wparam, LPARAM lparam) +{ + if (message == WM_DISPATCH_DRAWITEM) { + LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT) lparam; + UINT style = DFCS_BUTTONPUSH; + + if (dis->itemState & ODS_DISABLED) + style |= DFCS_INACTIVE; + + POINT iconPos = {dis->rcItem.left+2, (dis->rcItem.top+dis->rcItem.bottom-16)/2}; + RECT textRect = {dis->rcItem.left+16+4, dis->rcItem.top+2, dis->rcItem.right-4, dis->rcItem.bottom-4}; + + if (dis->itemState & ODS_SELECTED) { + style |= DFCS_PUSHED; + ++iconPos.x; ++iconPos.y; + ++textRect.left; ++textRect.top; + ++textRect.right; ++textRect.bottom; + } + + int bk_color = COLOR_BTNFACE; + int text_color = COLOR_BTNTEXT; + + if (dis->itemState & ODS_FOCUS) { + bk_color = COLOR_HIGHLIGHT; + text_color = COLOR_HIGHLIGHTTEXT; + } + + HBRUSH bk_brush = GetSysColorBrush(bk_color); + + FillRect(dis->hDC, &dis->rcItem, bk_brush); + DrawIconEx(dis->hDC, iconPos.x, iconPos.y, _hicon, 16, 16, 0, bk_brush, DI_NORMAL); + + TCHAR text[BUFFER_LEN]; + GetWindowText(_hwnd, text, BUFFER_LEN); + + if (dis->itemState & (ODS_DISABLED|ODS_GRAYED)) { + COLORREF gray = GetSysColor(COLOR_GRAYTEXT); + + if (gray) { + { + TextColor lcColor(dis->hDC, GetSysColor(COLOR_BTNHIGHLIGHT)); + RECT shadowRect = {textRect.left+1, textRect.top+1, textRect.right+1, textRect.bottom+1}; + DrawText(dis->hDC, text, -1, &shadowRect, DT_SINGLELINE|DT_VCENTER/*|DT_CENTER*/); + } + + BkMode mode(dis->hDC, TRANSPARENT); + TextColor lcColor(dis->hDC, gray); + DrawText(dis->hDC, text, -1, &textRect, DT_SINGLELINE|DT_VCENTER/*|DT_CENTER*/); + } else { + int old_r = textRect.right; + int old_b = textRect.bottom; + DrawText(dis->hDC, text, -1, &textRect, DT_SINGLELINE|DT_VCENTER/*|DT_CENTER*/|DT_CALCRECT); + int x = textRect.left + (old_r-textRect.right)/2; + int y = textRect.top + (old_b-textRect.bottom)/2; + int w = textRect.right-textRect.left; + int h = textRect.bottom-textRect.top; + s_MyDrawText_Rect.right = w; + s_MyDrawText_Rect.bottom = h; + GrayString(dis->hDC, GetSysColorBrush(COLOR_GRAYTEXT), MyDrawText, (LPARAM)text, -1, x, y, w, h); + } + } else { + BkMode mode(dis->hDC, TRANSPARENT); + TextColor lcColor(dis->hDC, GetSysColor(text_color)); + DrawText(dis->hDC, text, -1, &textRect, DT_SINGLELINE|DT_VCENTER/*|DT_CENTER*/); + } + + return TRUE; + } else + return super::WndProc(message, wparam, lparam); +} diff --git a/reactos/subsys/system/explorer/utility/window.h b/reactos/subsys/system/explorer/utility/window.h index 6e432293999..29d7945e35f 100644 --- a/reactos/subsys/system/explorer/utility/window.h +++ b/reactos/subsys/system/explorer/utility/window.h @@ -33,6 +33,20 @@ typedef set WindowSet; + /* + Classes are declared using "struct", not "class" because the default + access mode is "public". This way we can list the member functions in a + natural order without explicitly specifying any access mode at the begin + of the definition. + First are public constructors and destructor, then public member functions. + After that we list protected member varibables and functions. If needed, + private implemenation varibales and functions are positioned at the end. + */ + + + /** + Class Window is the base class for several C++ window wrapper classes. + */ struct Window { Window(HWND hwnd) @@ -150,13 +164,16 @@ struct WindowClass : public WNDCLASSEX return _atomClass; } - operator ATOM() const {return _atomClass;} + operator ATOM() {return Register();} + + // return LPCTSTR for the CreateWindowEx() parameter + operator LPCTSTR() {return (LPCTSTR)(int)Register();} protected: ATOM _atomClass; }; - // window class with gray background color + /// window class with gray background color struct BtnWindowClass : public WindowClass { BtnWindowClass(LPCTSTR classname, UINT style=0, WNDPROC wndproc=Window::WindowWndProc) @@ -166,7 +183,7 @@ struct BtnWindowClass : public WindowClass } }; - // window class with gray background color + /// window class with specified icon from resources struct IconWindowClass : public WindowClass { IconWindowClass(LPCTSTR classname, UINT nid, UINT style=0, WNDPROC wndproc=Window::WindowWndProc); @@ -193,6 +210,10 @@ struct MenuInfo #define Frame_GetMenuInfo(hwnd) ((MenuInfo*)SNDMSG(hwnd, FRM_GET_MENUINFO, 0, 0)) + /** + Class ChildWindow represents MDI child windows. + It is used with class MainFrame. + */ struct ChildWindow : public Window { typedef Window super; @@ -228,6 +249,12 @@ struct PreTranslateWindow : public Window }; + /** + The class Dialog implements modeless dialogs, which are managed by + Window::dispatch_dialog_msg() in Window::MessageLoop(). + A Dialog object should be constructed by calling Window::Create() + and specifying the class using the WINDOW_CREATOR() macro. + */ struct Dialog : public Window { typedef Window super; @@ -237,7 +264,11 @@ struct Dialog : public Window }; - // create button controls + /** + This class constructs button controls. + The button will remain existent when the C++ Button object is destroyed. + There is no conjunction between C++ object and windows control life time. + */ struct Button { Button(HWND parent, LPCTSTR text, int left, int top, int width, int height, @@ -314,8 +345,10 @@ template struct OwnerDrawParent : public BASE }; - // Subclass button controls to paint colored text labels. - // The owning window should use the OwnerDrawParent template to route woner draw messages to the buttons. + /** + Subclass button controls to paint colored text labels. + The owning window should use the OwnerDrawParent template to route woner draw messages to the buttons. + */ struct ColorButton : public SubclassedWindow { typedef SubclassedWindow super; @@ -330,18 +363,37 @@ protected: }; - // Subclass button controls to paint pictures left to the labels. - // The buttons should have set the style bit BS_OWNERDRAW. - // The owning window should use the OwnerDrawParent template to route woner draw messages to the buttons. + /** + Subclass button controls to paint pictures left to the labels. + The buttons should have set the style bit BS_OWNERDRAW. + The owning window should use the OwnerDrawParent template to route woner draw messages to the buttons. + */ struct PictureButton : public SubclassedWindow { typedef SubclassedWindow super; - PictureButton(HWND hwnd, HICON hicon) - : super(hwnd), _hicon(hicon) {} + PictureButton(HWND hwnd, HICON hicon, bool flat=false) + : super(hwnd), _hicon(hicon), _flat(flat) {} protected: LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); HICON _hicon; + bool _flat; +}; + + + /// start menu button +struct StartmenuEntry : public SubclassedWindow +{ + typedef SubclassedWindow super; + + StartmenuEntry(HWND hwnd, HICON hicon, bool flat=false) + : super(hwnd), _hicon(hicon), _flat(flat) {} + +protected: + LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); + + HICON _hicon; + bool _flat; };