Implementation of standard startmenu folders

svn path=/trunk/; revision=5678
This commit is contained in:
Martin Fuchs 2003-08-19 21:04:37 +00:00
parent cb15da56e1
commit c5ddf7eb05
10 changed files with 333 additions and 101 deletions

View file

@ -14,6 +14,9 @@
#define IDS_PROGRAMS 10
#define IDS_SETTINGS 11
#define IDS_EXPLORE 12
#define IDS_EMPTY 13
#define IDS_RECENT 14
#define IDS_ADMIN 15
#define IDI_REACTOS 100
#define IDI_EXPLORER 101
#define IDI_STARTMENU 102
@ -59,7 +62,7 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 125
#define _APS_NEXT_RESOURCE_VALUE 126
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101

View file

@ -251,6 +251,9 @@ BEGIN
IDS_PROGRAMS "Programs"
IDS_SETTINGS "Settings"
IDS_EXPLORE "Explore"
IDS_EMPTY "(Empty)"
IDS_RECENT "Recent Documents"
IDS_ADMIN "Administration"
END
#endif // German (Germany) resources

View file

@ -30,6 +30,7 @@
#include "../utility/shellclasses.h"
#include "../globals.h"
#include "entries.h"
#include "shellfs.h"
@ -243,22 +244,18 @@ void ShellDirectory::read_directory()
HRESULT hr = _folder->GetAttributesOf(1, (LPCITEMIDLIST*)&pidls[n], &attribs);
if (SUCCEEDED(hr)) {
if (attribs != ~SFGAO_FILESYSTEM) {
if (attribs != ~SFGAO_FILESYSTEM)
bhfi_valid = fill_w32fdata_shell(pidls[n], attribs, &w32fd, &bhfi);
} else
else
attribs = 0;
} else
attribs = 0;
Entry* entry;
if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
IShellFolder* child = NULL;
/*hr = */_folder->BindToObject(pidls[n], 0, IID_IShellFolder, (void**)&child);
entry = new ShellDirectory(this, child, pidls[n], _hwnd);
} else
if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
entry = new ShellDirectory(this, pidls[n], _hwnd);
else
entry = new ShellEntry(this, pidls[n]);
if (!first_entry)

View file

@ -62,9 +62,9 @@ struct ShellDirectory : public ShellEntry, public Directory
_path = pFolder;
}
explicit ShellDirectory(ShellDirectory* parent, IShellFolder* shell_root, LPITEMIDLIST shell_path, HWND hwnd)
explicit ShellDirectory(ShellDirectory* parent, LPITEMIDLIST shell_path, HWND hwnd)
: ShellEntry(parent, shell_path),
_folder(shell_root),
_folder(parent->_folder, shell_path),
_hwnd(hwnd)
{
/* not neccessary - the caller will fill the info
@ -72,8 +72,18 @@ struct ShellDirectory : public ShellEntry, public Directory
_data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
_shell_attribs = SFGAO_FOLDER; */
shell_root->AddRef();
_path = shell_root;
_folder->AddRef();
_path = _folder;
}
ShellDirectory(const ShellDirectory& other)
: ShellEntry(other),
Directory(other),
_folder(other._folder),
_hwnd(other._hwnd)
{
IShellFolder* pFolder = (IShellFolder*)_path;
pFolder->AddRef();
}
~ShellDirectory()

View file

@ -51,7 +51,8 @@ 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));
if (*it)
_dirs.push_back(ShellDirectory(Desktop(), *it, _hwnd));
_next_id = IDC_FIRST_MENU;
}
@ -65,33 +66,50 @@ HWND StartMenu::Create(int x, int y, HWND hwndParent)
}
*/
HWND StartMenu::Create(int x, int y, const StartMenuFolders& folders, HWND hwndParent)
Window::CREATORFUNC StartMenu::s_def_creator = STARTMENU_CREATOR(StartMenu);
HWND StartMenu::Create(int x, int y, const StartMenuFolders& folders, HWND hwndParent, CREATORFUNC creator)
{
return Window::Create(WINDOW_CREATOR_INFO(StartMenu,StartMenuFolders), &folders, 0, s_wcStartMenu, NULL,
return Window::Create(creator, &folders, 0, s_wcStartMenu, NULL,
WS_POPUP|WS_THICKFRAME|WS_CLIPCHILDREN|WS_VISIBLE, x, y, STARTMENU_WIDTH, 4, hwndParent);
}
LRESULT StartMenu::Init(LPCREATESTRUCT pcs)
{
WaitCursor wait;
AddEntries();
if (super::Init(pcs))
return 1;
WaitCursor wait;
for(StartMenuShellDirs::iterator it=_dirs.begin(); it!=_dirs.end(); ++it) {
ShellDirectory& dir = *it;
for(ShellEntryMap::const_iterator it=_entries.begin(); it!=_entries.end(); ++it) {
const StartMenuEntry& sme = it->second;
dir.smart_scan();
AddShellEntries(dir);
AddButton(sme._title, sme._hIcon, it->first);
}
return 0;
}
void StartMenu::AddShellEntries(const ShellDirectory& dir, bool subfolders)
void StartMenu::AddEntries()
{
for(StartMenuShellDirs::iterator it=_dirs.begin(); it!=_dirs.end(); ++it) {
StartMenuDirectory& smd = *it;
ShellDirectory& dir = smd._dir;
dir.smart_scan();
AddShellEntries(dir, -1, smd._subfolders);
}
}
void StartMenu::AddShellEntries(const ShellDirectory& dir, int max, bool subfolders)
{
int cnt = 0;
for(const Entry*entry=dir._down; entry; entry=entry->_next) {
// hide files like "desktop.ini"
if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
@ -102,14 +120,17 @@ void StartMenu::AddShellEntries(const ShellDirectory& dir, bool subfolders)
if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
continue;
// only 'max' entries shall be added.
if (++cnt == max)
break;
const ShellEntry* shell_entry = static_cast<const ShellEntry*>(entry);
AddButton(dir._folder, shell_entry);
AddEntry(dir._folder, shell_entry);
}
}
LRESULT StartMenu::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
{
switch(nmsg) {
@ -141,10 +162,13 @@ int StartMenu::Command(int id, int code)
break;
default: {
ShellEntryMap::const_iterator found = _entry_map.find(id);
ShellEntryMap::const_iterator found = _entries.find(id);
if (found != _entry_map.end()) {
ActivateEntry(const_cast<ShellEntry*>(found->second));
if (found != _entries.end()) {
ShellEntry* entry = const_cast<ShellEntry*>(found->second._entry);
if (entry)
ActivateEntry(id, entry);
break;
}
@ -154,11 +178,39 @@ int StartMenu::Command(int id, int code)
return 0;
}
UINT StartMenu::AddButton(LPCTSTR text, HICON hIcon, UINT id)
StartMenuEntry& StartMenu::AddEntry(LPCTSTR title, HICON hIcon, UINT id)
{
if (id == (UINT)-1)
id = ++_next_id;
StartMenuEntry& sme = _entries[id];
sme._title = title;
sme._hIcon = hIcon;
return sme;
}
StartMenuEntry& StartMenu::AddEntry(const ShellFolder folder, const ShellEntry* entry)
{
HICON hIcon = entry->_hicon;
if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
hIcon = SmallIcon(IDI_EXPLORER);
const String& entry_name = folder.get_name(entry->_pidl);
StartMenuEntry& sme = AddEntry(entry_name, hIcon);
sme._entry = entry;
return sme;
}
void StartMenu::AddButton(LPCTSTR title, HICON hIcon, UINT id)
{
WindowRect rect(_hwnd);
rect.top -= STARTMENU_LINE_HEIGHT;
@ -170,36 +222,86 @@ UINT StartMenu::AddButton(LPCTSTR text, HICON hIcon, UINT id)
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);
return id;
StartMenuButton(_hwnd, rect.bottom-rect.top-STARTMENU_LINE_HEIGHT-4, title, id, hIcon);
}
UINT StartMenu::AddButton(const ShellFolder folder, const ShellEntry* entry)
void StartMenu::AddSeparator()
{
HICON hIcon = entry->_hicon;
WindowRect rect(_hwnd);
if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
hIcon = SmallIcon(IDI_EXPLORER);
rect.top -= STARTMENU_SEP_HEIGHT;
const String& entry_name = folder.get_name(entry->_pidl);
if (rect.top < 0) {
rect.top += STARTMENU_LINE_HEIGHT;
rect.bottom += STARTMENU_LINE_HEIGHT;
}
UINT id = AddButton(entry_name, hIcon);
MoveWindow(_hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE);
_entry_map[id] = entry;
return id;
StartMenuSeparator(_hwnd, rect.bottom-rect.top-STARTMENU_SEP_HEIGHT-4);
}
void StartMenu::ActivateEntry(ShellEntry* entry)
void StartMenu::CreateSubmenu(int id, const StartMenuFolders& new_folders, CREATORFUNC creator)
{
HWND btn = GetDlgItem(_hwnd, id);
int x, y;
if (btn) {
WindowRect pos(btn);
x = pos.right;
y = pos.top+STARTMENU_HEIGHT-4;
} else {
WindowRect pos(_hwnd);
x = pos.right;
y = pos.top+STARTMENU_HEIGHT-4;
}
StartMenu::Create(x, y, new_folders, _hwnd, creator);
}
void StartMenu::CreateSubmenu(int id, int folder_id, CREATORFUNC creator)
{
StartMenuFolders new_folders;
SpecialFolder folder(folder_id, _hwnd);
if (folder)
new_folders.push_back(folder);
CreateSubmenu(id, new_folders, creator);
}
void StartMenu::CreateSubmenu(int id, int folder_id1, int folder_id2, CREATORFUNC creator)
{
StartMenuFolders new_folders;
SpecialFolder folder1(folder_id1, _hwnd);
if (folder1)
new_folders.push_back(folder1);
if (folder_id2 != -1) {
SpecialFolder folder2(folder_id2, _hwnd);
if (folder2)
new_folders.push_back(folder2);
}
CreateSubmenu(id, new_folders, creator);
}
void StartMenu::ActivateEntry(int id, ShellEntry* entry)
{
if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
StartMenuFolders new_folders;
new_folders.push_back(entry->create_absolute_pidl(_hwnd));
WindowRect my_pos(_hwnd);
StartMenu::Create(my_pos.right, my_pos.top+STARTMENU_HEIGHT-4, new_folders, _hwnd);
CreateSubmenu(id, new_folders);
} else {
entry->launch_entry(_hwnd);
}
@ -209,6 +311,13 @@ void StartMenu::ActivateEntry(ShellEntry* entry)
StartMenuRoot::StartMenuRoot(HWND hwnd)
: super(hwnd)
{
// insert directory "All Users\Start Menu"
ShellDirectory cmn_startmenu(Desktop(), SpecialFolder(CSIDL_COMMON_STARTMENU, _hwnd), _hwnd);
_dirs.push_back(StartMenuDirectory(cmn_startmenu, false)); // dont't add subfolders
// insert directory "<user name>\Start Menu"
ShellDirectory usr_startmenu(Desktop(), SpecialFolder(CSIDL_STARTMENU, _hwnd), _hwnd);
_dirs.push_back(StartMenuDirectory(usr_startmenu, false)); // dont't add subfolders
}
HWND StartMenuRoot::Create(int x, int y, HWND hwndParent)
@ -219,29 +328,26 @@ HWND StartMenuRoot::Create(int x, int y, HWND hwndParent)
LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs)
{
// add buttons for entries in _entries
if (super::Init(pcs))
return 1;
WaitCursor wait;
// insert start menu entries links from "All Users\Start Menu" and "<user name>\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);
AddSeparator();
// 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_RECENT), 0, IDC_RECENT);
AddButton(ResString(IDS_SETTINGS), 0, IDC_SETTINGS);
AddButton(ResString(IDS_ADMIN), 0, IDC_ADMIN);
AddButton(ResString(IDS_SEARCH), 0, IDC_SEARCH);
AddButton(ResString(IDS_START_HELP),0, IDC_START_HELP);
AddButton(ResString(IDS_LAUNCH), 0, IDC_LAUNCH);
AddSeparator();
AddButton(ResString(IDS_SHUTDOWN), SmallIcon(IDI_LOGOFF), IDC_SHUTDOWN);
AddButton(ResString(IDS_LOGOFF), SmallIcon(IDI_LOGOFF), IDC_LOGOFF);
@ -251,20 +357,34 @@ LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs)
int StartMenuRoot::Command(int id, int code)
{
switch(id) {
case IDC_PROGRAMS: {
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);
break;}
case IDC_PROGRAMS:
CreateSubmenu(id, CSIDL_COMMON_PROGRAMS, CSIDL_PROGRAMS);
break;
case IDC_EXPLORE:
explorer_show_frame(_hwnd, SW_SHOWNORMAL);
break;
case IDC_DOCUMENTS:
CreateSubmenu(id, CSIDL_PERSONAL);
break;
case IDC_RECENT:
CreateSubmenu(id, CSIDL_RECENT, STARTMENU_CREATOR(RecentStartMenu));
break;
case IDC_SETTINGS:
CreateSubmenu(id, CSIDL_CONTROLS);
break;
case IDC_FAVORITES:
CreateSubmenu(id, CSIDL_FAVORITES);
break;
case IDC_ADMIN:
CreateSubmenu(id, CSIDL_COMMON_ADMINTOOLS, CSIDL_ADMINTOOLS);
break;
case IDC_LOGOFF:
DestroyWindow(GetParent(_hwnd)); //TODO: show dialog and ask for acknowledge
break;
@ -279,3 +399,22 @@ int StartMenuRoot::Command(int id, int code)
return 0;
}
RecentStartMenu::RecentStartMenu(HWND hwnd, const StartMenuFolders& info)
: super(hwnd, info)
{
}
void RecentStartMenu::AddEntries()
{
for(StartMenuShellDirs::iterator it=_dirs.begin(); it!=_dirs.end(); ++it) {
StartMenuDirectory& smd = *it;
ShellDirectory& dir = smd._dir;
dir.smart_scan();
dir.sort_directory(SORT_DATE);
AddShellEntries(dir, 16, smd._subfolders); //TODO: read max. count of entries from registry
}
}

View file

@ -36,9 +36,9 @@
// 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)
StartMenuButton(HWND parent, int y, LPCTSTR title,
UINT id, HICON hIcon=0, DWORD style=WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_OWNERDRAW, DWORD exStyle=0)
: Button(parent, title, 2, y, STARTMENU_WIDTH-4, STARTMENU_LINE_HEIGHT, id, style, exStyle)
{
*new StartmenuEntry(_hwnd, hIcon);
@ -47,9 +47,41 @@ struct StartMenuButton : public Button
};
struct StartMenuSeparator : public Static
{
StartMenuSeparator(HWND parent, int y, DWORD style=WS_VISIBLE|WS_CHILD|SS_ETCHEDHORZ, DWORD exStyle=0)
: Static(parent, NULL, 2, y+STARTMENU_SEP_HEIGHT/2-1, STARTMENU_WIDTH-4, 2, -1, style, exStyle)
{
}
};
struct StartMenuDirectory
{
StartMenuDirectory(const ShellDirectory& dir, bool subfolders=true)
: _dir(dir), _subfolders(subfolders) {}
ShellDirectory _dir;
bool _subfolders;
};
typedef list<StartMenuDirectory> StartMenuShellDirs;
struct StartMenuEntry
{
StartMenuEntry() : _entry(NULL), _hIcon(0) {}
String _title;
HICON _hIcon;
const ShellEntry* _entry;
};
typedef map<UINT, StartMenuEntry> ShellEntryMap;
typedef list<ShellPath> StartMenuFolders;
typedef list<ShellDirectory> StartMenuShellDirs;
typedef map<UINT, const ShellEntry*> ShellEntryMap;
#define STARTMENU_CREATOR(WND_CLASS) WINDOW_CREATOR_INFO(WND_CLASS, StartMenuFolders)
// Startmenu window
@ -61,12 +93,13 @@ struct StartMenu : public OwnerDrawParent<Dialog>
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);
static HWND Create(int x, int y, const StartMenuFolders&, HWND hwndParent=0, CREATORFUNC creator=s_def_creator);
static CREATORFUNC s_def_creator;
protected:
int _next_id;
ShellEntryMap _entries;
StartMenuShellDirs _dirs;
ShellEntryMap _entry_map;
static BtnWindowClass s_wcStartMenu;
@ -74,12 +107,20 @@ protected:
LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
int Command(int id, int code);
UINT AddButton(LPCTSTR text, HICON hIcon=0, UINT id=(UINT)-1);
UINT AddButton(const ShellFolder folder, const ShellEntry* entry);
virtual void AddEntries();
void AddShellEntries(const ShellDirectory& dir, bool subfolders=true);
StartMenuEntry& AddEntry(LPCTSTR title, HICON hIcon=0, UINT id=(UINT)-1);
StartMenuEntry& AddEntry(const ShellFolder folder, const ShellEntry* entry);
void ActivateEntry(ShellEntry* entry);
void AddShellEntries(const ShellDirectory& dir, int max=-1, bool subfolders=true);
void AddButton(LPCTSTR title, HICON hIcon=0, UINT id=(UINT)-1);
void AddSeparator();
void CreateSubmenu(int id, const StartMenuFolders& new_folders, CREATORFUNC creator=s_def_creator);
void CreateSubmenu(int id, int folder1, int folder2, CREATORFUNC creator=s_def_creator);
void CreateSubmenu(int id, int folder, CREATORFUNC creator=s_def_creator);
void ActivateEntry(int id, ShellEntry* entry);
};
@ -96,3 +137,14 @@ protected:
LRESULT Init(LPCREATESTRUCT pcs);
int Command(int id, int code);
};
struct RecentStartMenu : public StartMenu
{
typedef StartMenu super;
RecentStartMenu(HWND hwnd, const StartMenuFolders& info);
protected:
virtual void AddEntries();
};

View file

@ -37,6 +37,7 @@
#define STARTMENU_WIDTH 150
#define STARTMENU_HEIGHT 4
#define STARTMENU_LINE_HEIGHT 22
#define STARTMENU_SEP_HEIGHT (STARTMENU_LINE_HEIGHT/2)
#define WM_SHELLHOOK_NOTIFY (WM_APP+0x10)
@ -55,10 +56,12 @@
#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_ADMIN 0x1007
#define IDC_DOCUMENTS 0x1008
#define IDC_RECENT 0x1009
#define IDC_FAVORITES 0x100A
#define IDC_PROGRAMS 0x100B
#define IDC_EXPLORE 0x100C
#define IDC_FIRST_APP 0x2000
#define IDC_FIRST_MENU 0x3000

View file

@ -139,7 +139,7 @@ ShellFolder::ShellFolder(IShellFolder* parent, LPCITEMIDLIST pidl)
{
IShellFolder* ptr;
if (pidl->mkid.cb)
if (pidl && pidl->mkid.cb)
CheckError(parent->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&ptr));
else
ptr = parent;
@ -153,7 +153,7 @@ ShellFolder::ShellFolder(LPCITEMIDLIST pidl)
IShellFolder* ptr;
IShellFolder* parent = Desktop();
if (pidl->mkid.cb)
if (pidl && pidl->mkid.cb)
CheckError(parent->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&ptr));
else
ptr = parent;
@ -166,7 +166,7 @@ void ShellFolder::attach(IShellFolder* parent, LPCITEMIDLIST pidl)
{
IShellFolder* ptr;
if (pidl->mkid.cb)
if (pidl && pidl->mkid.cb)
CheckError(parent->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&ptr));
else
ptr = parent;
@ -192,7 +192,7 @@ ShellFolder::ShellFolder(IShellFolder* p)
ShellFolder::ShellFolder(IShellFolder* parent, LPCITEMIDLIST pidl)
{
if (pidl->mkid.cb)
if (pidl && pidl->mkid.cb)
CheckError(parent->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&_p));
else
_p = Desktop();
@ -202,7 +202,7 @@ ShellFolder::ShellFolder(IShellFolder* parent, LPCITEMIDLIST pidl)
ShellFolder::ShellFolder(LPCITEMIDLIST pidl)
{
if (pidl->mkid.cb)
if (pidl && pidl->mkid.cb)
CheckError(Desktop()->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&_p));
else
_p = Desktop();

View file

@ -58,11 +58,11 @@ IconWindowClass::IconWindowClass(LPCTSTR classname, UINT nid, UINT style, WNDPRO
HHOOK Window::s_hcbtHook = 0;
Window::WINDOWCREATORFUNC Window::s_window_creator = NULL;
Window::CREATORFUNC Window::s_window_creator = NULL;
const void* Window::s_new_info = NULL;
HWND Window::Create(WINDOWCREATORFUNC creator, DWORD dwExStyle,
HWND Window::Create(CREATORFUNC creator, DWORD dwExStyle,
LPCTSTR lpClassName, LPCTSTR lpWindowName,
DWORD dwStyle, int x, int y, int w, int h,
HWND hwndParent, HMENU hMenu, LPVOID lpParam)
@ -75,7 +75,7 @@ HWND Window::Create(WINDOWCREATORFUNC creator, DWORD dwExStyle,
hwndParent, hMenu, g_Globals._hInstance, 0/*lpParam*/);
}
HWND Window::Create(WINDOWCREATORFUNC creator, const void* info, DWORD dwExStyle,
HWND Window::Create(CREATORFUNC creator, const void* info, DWORD dwExStyle,
LPCTSTR lpClassName, LPCTSTR lpWindowName,
DWORD dwStyle, int x, int y, int w, int h,
HWND hwndParent, HMENU hMenu, LPVOID lpParam)
@ -91,7 +91,7 @@ HWND Window::Create(WINDOWCREATORFUNC creator, const void* info, DWORD dwExStyle
static Window* s_new_child_wnd = NULL;
Window* Window::create_mdi_child(HWND hmdiclient, const MDICREATESTRUCT& mcs, WINDOWCREATORFUNC creator, const void* info)
Window* Window::create_mdi_child(HWND hmdiclient, const MDICREATESTRUCT& mcs, CREATORFUNC creator, const void* info)
{
s_window_creator = creator;
s_new_info = info;
@ -141,7 +141,7 @@ Window* Window::get_window(HWND hwnd)
const void* info = s_new_info;
s_new_info = NULL;
WINDOWCREATORFUNC window_creator = s_window_creator;
CREATORFUNC window_creator = s_window_creator;
s_window_creator = NULL;
wnd = window_creator(hwnd, info);
@ -227,7 +227,7 @@ ChildWindow::ChildWindow(HWND hwnd)
}
ChildWindow* ChildWindow::create(HWND hmdiclient, const RECT& rect, WINDOWCREATORFUNC creator, LPCTSTR classname, LPCTSTR title)
ChildWindow* ChildWindow::create(HWND hmdiclient, const RECT& rect, CREATORFUNC creator, LPCTSTR classname, LPCTSTR title)
{
MDICREATESTRUCT mcs;
@ -464,7 +464,7 @@ int Window::MessageLoop()
Button::Button(HWND parent, LPCTSTR text, int left, int top, int width, int height,
UINT id, DWORD flags, DWORD exStyle)
int id, DWORD flags, DWORD exStyle)
{
_hwnd = CreateWindowEx(exStyle, TEXT("BUTTON"), text, flags, left, top, width, height,
parent, (HMENU)id, g_Globals._hInstance, 0);
@ -481,6 +481,14 @@ LRESULT OwnerdrawnButton::WndProc(UINT message, WPARAM wparam, LPARAM lparam)
}
Static::Static(HWND parent, LPCTSTR text, int left, int top, int width, int height,
int id, DWORD flags, DWORD exStyle)
{
_hwnd = CreateWindowEx(exStyle, TEXT("STATIC"), text, flags, left, top, width, height,
parent, (HMENU)id, g_Globals._hInstance, 0);
}
static RECT s_MyDrawText_Rect = {0, 0, 0, 0};
static BOOL CALLBACK MyDrawText(HDC hdc, LPARAM data, int cnt)

View file

@ -68,19 +68,19 @@ struct Window
operator HWND() const {return _hwnd;}
typedef Window* (*WINDOWCREATORFUNC)(HWND, const void*);
typedef Window* (*CREATORFUNC)(HWND, const void*);
static HWND Create(WINDOWCREATORFUNC creator, DWORD dwExStyle,
static HWND Create(CREATORFUNC creator, DWORD dwExStyle,
LPCTSTR lpClassName, LPCTSTR lpWindowName,
DWORD dwStyle, int x, int y, int w, int h,
HWND hwndParent=0, HMENU hMenu=0, LPVOID lpParam=0);
static HWND Create(WINDOWCREATORFUNC creator, const void* info,
static HWND Create(CREATORFUNC creator, const void* info,
DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName,
DWORD dwStyle, int x, int y, int w, int h,
HWND hwndParent=0, HMENU hMenu=0, LPVOID lpParam=0);
static Window* create_mdi_child(HWND hmdiclient, const MDICREATESTRUCT& mcs, WINDOWCREATORFUNC creator, const void* info=NULL);
static Window* create_mdi_child(HWND hmdiclient, const MDICREATESTRUCT& mcs, CREATORFUNC creator, const void* info=NULL);
static LRESULT CALLBACK WindowWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
static Window* get_window(HWND hwnd);
@ -108,7 +108,7 @@ protected:
static const void* s_new_info; //TODO: protect for multithreaded access
static WINDOWCREATORFUNC s_window_creator; //TODO: protect for multithreaded access
static CREATORFUNC s_window_creator; //TODO: protect for multithreaded access
// MDI child creation
static HHOOK s_hcbtHook;
@ -147,7 +147,7 @@ template<typename WND_CLASS> struct WindowCreator
};
#define WINDOW_CREATOR(WND_CLASS) \
(Window::WINDOWCREATORFUNC) WindowCreator<WND_CLASS>::window_creator
(Window::CREATORFUNC) WindowCreator<WND_CLASS>::window_creator
template<typename WND_CLASS, typename INFO_CLASS> struct WindowCreatorInfo
@ -159,7 +159,7 @@ template<typename WND_CLASS, typename INFO_CLASS> struct WindowCreatorInfo
};
#define WINDOW_CREATOR_INFO(WND_CLASS, INFO_CLASS) \
(Window::WINDOWCREATORFUNC) WindowCreatorInfo<WND_CLASS, INFO_CLASS>::window_creator
(Window::CREATORFUNC) WindowCreatorInfo<WND_CLASS, INFO_CLASS>::window_creator
/**
@ -239,7 +239,7 @@ struct ChildWindow : public Window
ChildWindow(HWND hwnd);
static ChildWindow* create(HWND hmdiclient, const RECT& rect,
WINDOWCREATORFUNC creator, LPCTSTR classname, LPCTSTR title=NULL);
CREATORFUNC creator, LPCTSTR classname, LPCTSTR title=NULL);
protected:
LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
@ -295,7 +295,24 @@ struct Dialog : public Window
struct Button
{
Button(HWND parent, LPCTSTR text, int left, int top, int width, int height,
UINT id, DWORD flags=WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON, DWORD ex_flags=0);
int id, DWORD flags=WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON, DWORD exStyle=0);
operator HWND() const {return _hwnd;}
protected:
HWND _hwnd;
};
/**
This class constructs static controls.
The control will remain existent when the C++ object is destroyed.
There is no conjunction between C++ object and windows control life time.
*/
struct Static
{
Static(HWND parent, LPCTSTR text, int left, int top, int width, int height,
int id, DWORD flags=WS_VISIBLE|WS_CHILD|SS_SIMPLE, DWORD ex_flags=0);
operator HWND() const {return _hwnd;}