Beginnings of "Search Program" dialog

svn path=/trunk/; revision=6207
This commit is contained in:
Martin Fuchs
2003-10-01 23:30:11 +00:00
parent 9a49c3f027
commit d81895f3a3
27 changed files with 771 additions and 45 deletions
@@ -32,7 +32,7 @@ CXXFLAGS = $(CFLAGS)
EXEC_SUFFIX = .exe
RES_SUFFIX = .coff
VPATH = shell utility taskbar desktop
VPATH = shell utility taskbar desktop dialogs
PROGRAM = explorer
@@ -59,7 +59,8 @@ OBJECTS = \
taskbar.o \
startmenu.o \
traynotify.o \
quicklaunch.o
quicklaunch.o \
searchprogram.o
LIBS = gdi32 comctl32 ole32 uuid
+2 -1
View File
@@ -33,7 +33,8 @@ CPP_SRCS = \
taskbar/taskbar.cpp \
taskbar/startmenu.cpp \
taskbar/traynotify.cpp \
taskbar/quicklaunch.cpp
taskbar/quicklaunch.cpp \
dialogs/searchprogram.cpp
RC_SRCS = rsrc.rc
EXTRARCFLAGS = -D__WRC__ -D_WIN32
@@ -0,0 +1,181 @@
/*
* Copyright 2003 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// Explorer clone
//
// searchprogram.cpp
//
// Explorer dialogs
//
// Martin Fuchs, 02.10.2003
//
#include "../utility/utility.h"
#include "../explorer.h"
#include "../globals.h"
#include "../explorer_intres.h"
#include "searchprogram.h"
int CollectProgramsThread::Run()
{
try {
collect_programs(SpecialFolderPath(CSIDL_COMMON_PROGRAMS, _hwnd));
} catch(COMException&) {
}
try {
collect_programs(SpecialFolderPath(CSIDL_PROGRAMS, _hwnd));
} catch(COMException&) {
}
return 0;
}
void CollectProgramsThread::collect_programs(const ShellPath& path)
{
ShellDirectory dir(Desktop(), path, 0);
dir.smart_scan();
for(const Entry*entry=dir._down; entry; entry=entry->_next) {
if (!_alive)
break;
if (entry->_shell_attribs & SFGAO_HIDDEN)
continue;
const ShellEntry* shell_entry = static_cast<const ShellEntry*>(entry);
if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
collect_programs(shell_entry->create_absolute_pidl());
else if (entry->_shell_attribs & SFGAO_LINK)
if (_alive)
_callback(dir._folder, shell_entry, _hwnd);
}
}
FindProgramTopicDlg::FindProgramTopicDlg(HWND hwnd)
: super(hwnd),
_list_ctrl(GetDlgItem(hwnd, IDC_MAILS_FOUND)),
_thread(collect_programs_callback, _list_ctrl)
{
SetWindowIcon(hwnd, IDI_REACTOS/*IDI_SEARCH*/);
_resize_mgr.Add(IDC_TOPIC, RESIZE_X);
_resize_mgr.Add(IDC_MAILS_FOUND,RESIZE);
_resize_mgr.Resize(+520, +300);
_haccel = LoadAccelerators(g_Globals._hInstance, MAKEINTRESOURCE(IDA_SEARCH_PROGRAM));
LV_COLUMN column = {LVCF_TEXT|LVCF_FMT|LVCF_WIDTH, LVCFMT_LEFT, 250};
column.pszText = _T("Name");
ListView_InsertColumn(_list_ctrl, 0, &column);
column.cx = 400;
column.pszText = _T("Path");
ListView_InsertColumn(_list_ctrl, 1, &column);
ListView_SetExtendedListViewStyleEx(_list_ctrl, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
Refresh();
}
void FindProgramTopicDlg::Refresh()
{
WaitCursor wait;
ListView_DeleteAllItems(_list_ctrl);
_thread.Start();
}
void FindProgramTopicDlg::collect_programs_callback(ShellFolder& folder, const ShellEntry* entry, void* param)
{
LPCITEMIDLIST pidl = entry->_pidl;
IShellLink* pShellLink;
HRESULT hr = folder->GetUIObjectOf(NULL, 1, &pidl, IID_IShellLink, NULL, (LPVOID*)&pShellLink);
if (SUCCEEDED(hr)) {
WIN32_FIND_DATA wfd;
/*hr = pShellLink->Resolve(_hwnd, SLR_NO_UI);
if (SUCCEEDED(NOERROR))*/ {
TCHAR path[MAX_PATH];
hr = pShellLink->GetPath(path, MAX_PATH-1, (WIN32_FIND_DATA*)&wfd, SLGP_UNCPRIORITY);
if (SUCCEEDED(hr)) {
if (_tcsstr(path, _T(".exe"))) { //@@
HWND list_ctrl = (HWND)param;
LV_ITEM item = {LVIF_TEXT, INT_MAX};
item.pszText = entry->_display_name;
item.iItem = ListView_InsertItem(list_ctrl, &item);
item.iSubItem = 1;
item.pszText = path;
ListView_SetItem(list_ctrl, &item);
int icon;
hr = pShellLink->GetIconLocation(path, MAX_PATH-1, &icon);
//TODO: display icon
//TODO: store info in ShellPathWithFolder
}
}
}
}
pShellLink->Release();
}
LRESULT FindProgramTopicDlg::WndProc(UINT message, WPARAM wparam, LPARAM lparam)
{
switch(message) {
default:
return super::WndProc(message, wparam, lparam);
}
return FALSE;
}
int FindProgramTopicDlg::Command(int id, int code)
{
switch(id) {
case ID_REFRESH:
Refresh();
break;
default:
return super::Command(id, code);
}
return TRUE;
}
@@ -0,0 +1,78 @@
/*
* Copyright 2003 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// Explorer clone
//
// searchprogram.h
//
// Explorer dialogs
//
// Martin Fuchs, 02.10.2003
//
struct ShellPathWithFolder {
ShellPathWithFolder(const ShellFolder& folder, const ShellPath& path)
: _folder(folder), _path(path) {}
ShellFolder _folder;
ShellPath _path;
};
typedef void (*COLLECT_CALLBACK)(ShellFolder& folder, const ShellEntry* entry, void* param);
struct CollectProgramsThread : public Thread
{
CollectProgramsThread(COLLECT_CALLBACK callback, HWND hwnd)
: _callback(callback),
_hwnd(hwnd)
{
}
int Run();
protected:
COLLECT_CALLBACK _callback;
HWND _hwnd;
void CollectProgramsThread::collect_programs(const ShellPath& path);
};
struct FindProgramTopicDlg : public ResizeController<Dialog>
{
typedef ResizeController<Dialog> super;
FindProgramTopicDlg(HWND hwnd);
protected:
HWND _list_ctrl;
HACCEL _haccel;
CollectProgramsThread _thread;
virtual LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam);
virtual int Command(int id, int code);
void Refresh();
static void collect_programs_callback(ShellFolder& folder, const ShellEntry* entry, void* param);
};
@@ -79,6 +79,16 @@ SmallIcon::SmallIcon(UINT nid)
}
void SetWindowIcon(HWND hwnd, UINT nid)
{
HICON hIcon = ResIcon(nid);
Window_SetIcon(hwnd, ICON_BIG, hIcon);
HICON hIconSmall = SmallIcon(nid);
Window_SetIcon(hwnd, ICON_SMALL, hIconSmall);
}
ResBitmap::ResBitmap(UINT nid)
{
_hBmp = LoadBitmap(g_Globals._hInstance, MAKEINTRESOURCE(nid));
@@ -547,6 +547,18 @@ SOURCE=.\shell\winfs.cpp
SOURCE=.\shell\winfs.h
# End Source File
# End Group
# Begin Group "dialogs"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\dialogs\searchprogram.cpp
# End Source File
# Begin Source File
SOURCE=.\dialogs\searchprogram.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\buildno.h
+1 -5
View File
@@ -43,11 +43,7 @@
#define IDW_FIRST_CHILD 0xC000 /*0x200*/
#define PM_GET_FILEWND_PTR (WM_APP+0x03)
#define PM_FRM_CALC_CLIENT (WM_APP+0x04)
#define Frame_CalcFrameClient(hwnd, prt) ((BOOL)SNDMSG(hwnd, PM_FRM_CALC_CLIENT, 0, (LPARAM)(PRECT)prt))
#define PM_GET_FILEWND_PTR (WM_APP+0x05)
#define PM_GET_CONTROLWINDOW (WM_APP+0x06)
@@ -25,12 +25,14 @@
#define IDS_CONTROL_PANEL 21
#define IDS_PRINTERS 22
#define IDS_BROWSE 23
#define IDS_SEARCH_PRG 24
#define IDI_REACTOS 100
#define IDI_EXPLORER 101
#define IDI_STARTMENU 102
#define IDB_TOOLBAR 103
#define IDA_EXPLORER 104
#define ID_ACTIVATE 105
#define IDD_SEARCH_PROGRAM 105
#define IDB_DRIVEBAR 106
#define IDB_IMAGES 107
#define IDD_EXECUTE 108
@@ -43,12 +45,15 @@
#define IDI_ARROW 125
#define IDI_ARROW_SELECTED 126
#define IDB_LOGOV 129
#define IDA_SEARCH_PROGRAM 133
#define ID_VIEW_NAME 401
#define ID_VIEW_ALL_ATTRIBUTES 402
#define ID_VIEW_SELECTED_ATTRIBUTES 403
#define ID_VIEW_STATUSBAR 503
#define ID_VIEW_DRIVE_BAR 507
#define ID_VIEW_TOOL_BAR 508
#define IDC_TOPIC 1017
#define IDC_MAILS_FOUND 1018
#define ID_REFRESH 1704
#define ID_ABOUT 1803
#define IDC_FILETREE 10001
@@ -75,8 +80,8 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 133
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_RESOURCE_VALUE 134
#define _APS_NEXT_COMMAND_VALUE 40002
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
@@ -111,6 +111,7 @@ BEGIN
IDS_CONTROL_PANEL "Control Panel"
IDS_PRINTERS "Printers"
IDS_BROWSE "Browse Files..."
IDS_SEARCH_PRG "Search Programm..."
END
#endif // Romanian resources
@@ -148,6 +149,11 @@ BEGIN
NOINVERT
END
IDA_SEARCH_PROGRAM ACCELERATORS DISCARDABLE
BEGIN
VK_F5, ID_REFRESH, VIRTKEY, NOINVERT
END
#endif // Neutral resources
/////////////////////////////////////////////////////////////////////////////
@@ -372,6 +378,7 @@ BEGIN
IDS_CONTROL_PANEL "Systemsteuerung"
IDS_PRINTERS "Drucker"
IDS_BROWSE "Dateien..."
IDS_SEARCH_PRG "Suche Programm..."
END
#endif // German (Germany) resources
@@ -551,6 +558,37 @@ BEGIN
PUSHBUTTON "&Help",254,158,43,47,14
END
IDD_SEARCH_PROGRAM DIALOGEX 0, 0, 144, 65
STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION |
WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "Search Program in Startmenu"
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_TOPIC,7,7,130,14,ES_AUTOHSCROLL
CONTROL "List1",IDC_MAILS_FOUND,"SysListView32",LVS_REPORT |
LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,25,130,33
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_SEARCH_PROGRAM, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 137
TOPMARGIN, 7
BOTTOMMARGIN, 58
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
@@ -586,6 +624,7 @@ BEGIN
IDS_CONTROL_PANEL "Control Panel"
IDS_PRINTERS "Printers"
IDS_BROWSE "Browse Files..."
IDS_SEARCH_PRG "Search Programm..."
END
#endif // English (U.S.) resources
+2
View File
@@ -68,6 +68,8 @@ protected:
HICON _hIcon;
};
extern void SetWindowIcon(HWND hwnd, UINT nid);
struct ResBitmap
{
ResBitmap(UINT nid);
+3 -1
View File
@@ -28,6 +28,7 @@ VPATH += shell
VPATH += utility
VPATH += taskbar
VPATH += desktop
VPATH += dialogs
WINE_MODE = yes
@@ -71,7 +72,8 @@ TARGET_OBJECTS = \
taskbar.o \
startmenu.o \
traynotify.o \
quicklaunch.o
quicklaunch.o \
searchprogram.o
include $(PATH_TO_TOP)/rules.mak
@@ -62,6 +62,32 @@ Entry::Entry(Entry* parent)
_display_name = _data.cFileName;
}
Entry::Entry(const Entry& other)
{
_next = NULL;
_down = NULL;
_up = NULL;
assert(!other._next);
assert(!other._down);
assert(!other._up);
_expanded = other._expanded;
_scanned = other._scanned;
_level = other._level;
_data = other._data;
_shell_attribs = other._shell_attribs;
_display_name = other._display_name==other._data.cFileName? _data.cFileName: _tcsdup(other._display_name);
_etype = other._etype;
_hIcon = other._hIcon;
_bhfi = other._bhfi;
_bhfi_valid = other._bhfi_valid;
}
// free a directory entry
Entry::~Entry()
{
@@ -46,6 +46,7 @@ struct Entry
protected:
Entry(ENTRY_TYPE etype);
Entry(Entry* parent);
Entry(const Entry&);
public:
virtual ~Entry();
@@ -82,7 +82,7 @@ FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info)
lstrcpy(_root._fs, TEXT("Shell"));
const ShellChildWndInfo& shell_info = static_cast<const ShellChildWndInfo&>(info);
_root._entry = new ShellDirectory(Desktop(), DesktopFolder(), hwnd);
_root._entry = new ShellDirectory(Desktop(), DesktopFolderPath(), hwnd);
entry = _root._entry->read_tree((LPCTSTR)&*shell_info._shell_path, SORT_NAME/*_sortOrder*/);
}
else
@@ -338,7 +338,7 @@ LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
switch(LOWORD(wparam)) {
case ID_WINDOW_NEW:
if (_root._entry->_etype == ET_SHELL)
FileChildWindow::create(GetParent(_hwnd)/*_hmdiclient*/, ShellChildWndInfo(_path,DesktopFolder()));
FileChildWindow::create(GetParent(_hwnd)/*_hmdiclient*/, ShellChildWndInfo(_path,DesktopFolderPath()));
else
FileChildWindow::create(GetParent(_hwnd)/*_hmdiclient*/, FileChildWndInfo(_path));
break;
@@ -289,7 +289,7 @@ LRESULT MainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
case PM_OPEN_WINDOW: {
TCHAR buffer[MAX_PATH];
LPCTSTR path;
ShellPath shell_path = DesktopFolder();
ShellPath shell_path = DesktopFolderPath();
if (lparam) {
if (wparam & OWM_PIDL) {
@@ -467,7 +467,7 @@ int MainFrame::Command(int id, int code)
GetCurrentDirectory(MAX_PATH, path);
#ifndef _NO_MDI
FileChildWindow::create(_hmdiclient, ShellChildWndInfo(path,DesktopFolder()));
FileChildWindow::create(_hmdiclient, ShellChildWndInfo(path,DesktopFolderPath()));
#else
//TODO: SDI implementation
#endif
@@ -483,7 +483,7 @@ int MainFrame::Command(int id, int code)
GetCurrentDirectory(MAX_PATH, path);
ShellBrowserChild::create(_hmdiclient, ShellChildWndInfo(path,DesktopFolder()));
ShellBrowserChild::create(_hmdiclient, ShellChildWndInfo(path,DesktopFolderPath()));
break;}
//TODO: There are even more menu items!
@@ -26,7 +26,7 @@
//
#define PM_OPEN_WINDOW (WM_APP+0x05)
#define PM_OPEN_WINDOW (WM_APP+0x07)
enum OPEN_WINDOW_MODE {OWM_EXPLORE=1, OWM_DETAILS=2, OWM_PIDL=4};
@@ -105,7 +105,7 @@ bool ShellDirectory::fill_w32fdata_shell(LPCITEMIDLIST pidl, SFGAOF attribs, WIN
}
ShellPath ShellEntry::create_absolute_pidl()
ShellPath ShellEntry::create_absolute_pidl() const
{
if (_up/* && _up->_etype==ET_SHELL*/) {
ShellDirectory* dir = static_cast<ShellDirectory*>(_up);
@@ -35,7 +35,7 @@ struct ShellEntry : public Entry
virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
IShellFolder* get_parent_folder() const;
ShellPath create_absolute_pidl();
ShellPath create_absolute_pidl() const;
ShellPath _pidl; // parent relative PIDL
@@ -57,6 +57,7 @@
#define IDC_CONTROL_PANEL 0x1012
#define IDC_PRINTERS 0x1013
#define IDC_BROWSE 0x1014
#define IDC_SEARCH_PROGRAM 0x1015
#define IDC_FIRST_MENU 0x3000
@@ -37,6 +37,7 @@
#include "desktopbar.h"
#include "startmenu.h"
#include "../dialogs/searchprogram.h"
StartMenu::StartMenu(HWND hwnd)
@@ -65,8 +66,8 @@ StartMenu::~StartMenu()
}
// We need this wrapper function for s_wcStartMenu, it calls to the WIN32 API
// through static C++ initializers are not allowed for Winelib applications.
// We need this wrapper function for s_wcStartMenu, it calls the WIN32 API,
// though static C++ initializers are not allowed for Winelib applications.
BtnWindowClass& StartMenu::GetWndClasss()
{
static BtnWindowClass s_wcStartMenu(CLASSNAME_STARTMENU);
@@ -403,16 +404,12 @@ void StartMenu::CreateSubmenu(int id, int folder_id1, int folder_id2, CREATORFUN
StartMenuFolders new_folders;
try {
SpecialFolderPath folder1(folder_id1, _hwnd);
new_folders.push_back(folder1);
new_folders.push_back(SpecialFolderPath(folder_id1, _hwnd));
} catch(COMException&) {
}
try {
SpecialFolderPath folder2(folder_id2, _hwnd);
new_folders.push_back(folder2);
new_folders.push_back(SpecialFolderPath(folder_id2, _hwnd));
} catch(COMException&) {
}
@@ -673,6 +670,7 @@ LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs)
// insert hard coded start entries
AddButton(ResString(IDS_PROGRAMS), 0, true, IDC_PROGRAMS);
AddButton(ResString(IDS_SEARCH_PRG), 0, false, IDC_SEARCH_PROGRAM);
AddButton(ResString(IDS_DOCUMENTS), 0, true, IDC_DOCUMENTS);
AddButton(ResString(IDS_RECENT), 0, true, IDC_RECENT);
AddButton(ResString(IDS_FAVORITES), 0, true, IDC_FAVORITES);
@@ -736,6 +734,12 @@ int StartMenuRoot::Command(int id, int code)
CreateSubmenu(id, CSIDL_COMMON_PROGRAMS, CSIDL_PROGRAMS);
break;
case IDC_SEARCH_PROGRAM: {
HWND hwndDesktopBar = GetWindow(_hwnd, GW_OWNER);
CloseStartMenu(id);
Dialog::DoModal(IDD_SEARCH_PROGRAM, WINDOW_CREATOR(FindProgramTopicDlg), hwndDesktopBar);
break;}
case IDC_EXPLORE:
explorer_show_frame(_hwnd, SW_SHOWNORMAL);
CloseStartMenu(id);
@@ -125,9 +125,9 @@ typedef map<UINT, StartMenuEntry> ShellEntryMap;
/**
Startmenu window
*/
struct StartMenu : public OwnerDrawParent<Dialog>
struct StartMenu : public OwnerDrawParent<DialogWindow>
{
typedef OwnerDrawParent<Dialog> super;
typedef OwnerDrawParent<DialogWindow> super;
StartMenu(HWND hwnd);
StartMenu(HWND hwnd, const StartMenuFolders& info);
@@ -214,6 +214,8 @@ protected:
LRESULT Init(LPCREATESTRUCT pcs);
LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
SIZE _logo_size;
void AddEntries();
int Command(int id, int code);
@@ -222,8 +224,6 @@ protected:
static void ShowRestartDialog(HWND hwndOwner, UINT flags);
static void ShowSearchDialog();
static void ShowSearchComputer();
SIZE _logo_size;
};
@@ -743,9 +743,9 @@ struct SpecialFolderPath : public ShellPath
}
};
struct DesktopFolder : public SpecialFolderPath
struct DesktopFolderPath : public SpecialFolderPath
{
DesktopFolder()
DesktopFolderPath()
: SpecialFolderPath(CSIDL_DESKTOP, 0)
{
}
@@ -759,6 +759,10 @@ struct SpecialFolder : public ShellFolder
}
};
struct DesktopFolder : public ShellFolder
{
};
#if _WIN32_IE>=0x400 // is SHGetSpecialFolderPath() available?
@@ -59,7 +59,7 @@ public:
{
TVHITTESTINFO hit;
hit.pt = (POINT&)pt;
ScreenToClient(m_hTargetWnd,&hit.pt);
ScreenToClient(m_hTargetWnd, &hit.pt);
hit.flags = TVHT_ONITEM;
HTREEITEM hItem = TreeView_HitTest(m_hTargetWnd,&hit);
@@ -32,6 +32,14 @@
#include <time.h>
DWORD WINAPI Thread::ThreadProc(void* para)
{
Thread* pThis = (Thread*) para;
return pThis->Run();
}
void display_error(HWND hwnd, DWORD error)
{
PTSTR msg;
@@ -164,6 +164,46 @@ protected:
};
/// Thread base class
struct Thread
{
Thread()
: _alive(true)
{
_hThread = INVALID_HANDLE_VALUE;
}
virtual ~Thread()
{
Stop();
CloseHandle(_hThread);
}
void Start()
{
_hThread = CreateThread(NULL, 0, ThreadProc, this, 0, NULL);
}
void Stop()
{
_alive = false;
// wait for finishing
WaitForSingleObject(_hThread, INFINITE);
}
virtual int Run() = 0;
protected:
static DWORD WINAPI ThreadProc(void* para);
HANDLE _hThread;
bool _alive;
};
// window utilities
struct ClientRect : public RECT
@@ -205,6 +245,13 @@ struct Point : public POINT
};
inline void ClientToScreen(HWND hwnd, RECT* prect)
{::ClientToScreen(hwnd,(LPPOINT)&prect->left); ::ClientToScreen(hwnd,(LPPOINT)&prect->right);}
inline void ScreenToClient(HWND hwnd, RECT* prect)
{::ScreenToClient(hwnd,(LPPOINT)&prect->left); ::ScreenToClient(hwnd,(LPPOINT)&prect->right);}
struct FullScreenParameters
{
FullScreenParameters()
@@ -489,6 +536,7 @@ extern void _splitpath(const CHAR* path, CHAR* drv, CHAR* dir, CHAR* name, CHAR*
#define SetDlgCtrlID(hwnd, id) SetWindowLong(hwnd, GWL_ID, id)
#define SetWindowStyle(hwnd, val) (DWORD)SetWindowLong(hwnd, GWL_STYLE, val)
#define SetWindowExStyle(h, val) (DWORD)SetWindowLong(hwnd, GWL_EXSTYLE, val)
#define Window_SetIcon(hwnd, type, hicon) (HICON)SendMessage(hwnd, WM_SETICON, type, (LPARAM)(hicon))
// display
@@ -92,7 +92,7 @@ Window::~Window()
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)
HWND hwndParent, HMENU hMenu/*, LPVOID lpParam*/)
{
Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info
@@ -107,7 +107,7 @@ HWND Window::Create(CREATORFUNC creator, 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)
HWND hwndParent, HMENU hMenu/*, LPVOID lpParam*/)
{
Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info
@@ -149,8 +149,13 @@ Window* Window::create_mdi_child(HWND hmdiclient, const MDICREATESTRUCT& mcs, CR
LRESULT CALLBACK Window::CBTHookProc(int code, WPARAM wparam, LPARAM lparam)
{
if (code == HCBT_CREATEWND) {
HWND hwnd = (HWND)wparam;
// create Window controller and associate it with the window handle
Window* child = get_window((HWND)wparam);
Window* child = get_window(hwnd);
if (!child)
child = create_controller(hwnd);
if (child)
s_new_child_wnd = child;
@@ -160,8 +165,7 @@ LRESULT CALLBACK Window::CBTHookProc(int code, WPARAM wparam, LPARAM lparam)
}
// get window controller from window handle
// if not already present, create a new controller
/// get window controller from window handle
Window* Window::get_window(HWND hwnd)
{
@@ -174,6 +178,14 @@ Window* Window::get_window(HWND hwnd)
return found->second;
}
return NULL;
}
/// create controller for a new window
Window* Window::create_controller(HWND hwnd)
{
if (s_window_creator) { // protect for recursion
Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info
@@ -203,6 +215,9 @@ LRESULT CALLBACK Window::WindowWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPAR
{
Window* pThis = get_window(hwnd);
if (!pThis)
pThis = create_controller(hwnd);
if (pThis) {
switch(nmsg) {
case WM_COMMAND:
@@ -536,6 +551,18 @@ PreTranslateWindow::~PreTranslateWindow()
}
DialogWindow::DialogWindow(HWND hwnd)
: super(hwnd)
{
register_dialog(hwnd);
}
DialogWindow::~DialogWindow()
{
unregister_dialog(_hwnd);
}
Dialog::Dialog(HWND hwnd)
: super(hwnd)
{
@@ -547,6 +574,149 @@ Dialog::~Dialog()
unregister_dialog(_hwnd);
}
int Dialog::DoModal(UINT nid, CREATORFUNC creator, HWND hwndParent)
{
Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info
s_window_creator = creator;
s_new_info = NULL;
return DialogBoxParam(g_Globals._hInstance, MAKEINTRESOURCE(nid), hwndParent, DialogProc, 0/*lpParam*/);
}
int Dialog::DoModal(UINT nid, CREATORFUNC creator, const void* info, HWND hwndParent)
{
Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info
s_window_creator = creator;
s_new_info = NULL;
return DialogBoxParam(g_Globals._hInstance, MAKEINTRESOURCE(nid), hwndParent, DialogProc, 0/*lpParam*/);
}
INT_PTR CALLBACK Window::DialogProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
{
Window* pThis = get_window(hwnd);
if (pThis) {
switch(nmsg) {
case WM_COMMAND:
pThis->Command(LOWORD(wparam), HIWORD(wparam));
return TRUE; // message has been processed
case WM_NOTIFY:
pThis->Notify(wparam, (NMHDR*)lparam);
return TRUE; // message has been processed
case WM_NCDESTROY:
delete pThis;
return TRUE; // message has been processed
default:
return pThis->WndProc(nmsg, wparam, lparam);
}
} else if (nmsg == WM_INITDIALOG) {
pThis = create_controller(hwnd);
if (pThis)
return pThis->Init(NULL);
}
return FALSE; // message has not been processed
}
LRESULT Dialog::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
{
return FALSE; // message has not been processed
}
int Dialog::Command(int id, int code)
{
if (code == BN_CLICKED) {
EndDialog(_hwnd, id);
return TRUE; // message has been processed
}
return FALSE;
}
ResizeManager::ResizeManager(HWND hwnd)
: _hwnd(hwnd)
{
ClientRect clnt(hwnd);
_last_size.cx = clnt.right;
_last_size.cy = clnt.bottom;
WindowRect rect(hwnd);
_min_wnd_size.cx = rect.right - rect.left;
_min_wnd_size.cy = rect.bottom - rect.top;
}
void ResizeManager::HandleSize(int cx, int cy)
{
ClientRect clnt_rect(_hwnd);
SIZE new_size = {cx, cy};
int dx = new_size.cx - _last_size.cx;
int dy = new_size.cy - _last_size.cy;
if (!dx && !dy)
return;
_last_size = new_size;
HDWP hDWP = BeginDeferWindowPos(size());
for(ResizeManager::const_iterator it=begin(); it!=end(); ++it) {
const ResizeEntry& e = *it;
RECT move = {0};
if (e._flags & MOVE_LEFT) // Die verschiedenen Transformationsmatrizen in move ließen sich eigentlich
move.left += dx; // cachen oder vorausberechnen, da sie nur von _flags und der Größenänderung abhängig sind.
if (e._flags & MOVE_RIGHT)
move.right += dx;
if (e._flags & MOVE_TOP)
move.top += dy;
if (e._flags & MOVE_BOTTOM)
move.bottom += dy;
UINT flags = 0;
if (!move.left && !move.top)
flags = SWP_NOMOVE;
if (move.right==move.left && move.bottom==move.top)
flags |= SWP_NOSIZE;
if (flags != (SWP_NOMOVE|SWP_NOSIZE)) {
HWND hwnd = GetDlgItem(_hwnd, e._id);
WindowRect rect(hwnd);
ScreenToClient(_hwnd, rect);
rect.left += move.left;
rect.right += move.right;
rect.top += move.top;
rect.bottom += move.bottom;
hDWP = DeferWindowPos(hDWP, hwnd, 0, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, flags|SWP_NOACTIVATE|SWP_NOZORDER);
}
}
EndDeferWindowPos(hDWP);
}
void ResizeManager::Resize(int dx, int dy)
{
::SetWindowPos(_hwnd, 0, 0, 0, _min_wnd_size.cx+dx, _min_wnd_size.cy+dy, SWP_NOMOVE|SWP_NOACTIVATE);
ClientRect clnt_rect(_hwnd);
HandleSize(clnt_rect.right, clnt_rect.bottom);
}
Button::Button(HWND parent, LPCTSTR title, int left, int top, int width, int height,
int id, DWORD flags, DWORD exStyle)
+143 -6
View File
@@ -64,16 +64,17 @@ struct Window : public WindowHandle
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);
HWND hwndParent=0, HMENU hMenu=0/*, LPVOID lpParam=0*/);
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);
HWND hwndParent=0, HMENU hMenu=0/*, LPVOID lpParam=0*/);
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 INT_PTR CALLBACK DialogProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
static Window* get_window(HWND hwnd);
#ifndef _MSC_VER
@@ -104,6 +105,8 @@ protected:
virtual int Command(int id, int code); // WM_COMMAND processing
virtual int Notify(int id, NMHDR* pnmh); // WM_NOTIFY processing
static Window* create_controller(HWND hwnd);
static WindowMap s_wnd_map;
@@ -304,9 +307,23 @@ struct PreTranslateWindow : public Window
/**
The class Dialog implements modeless dialogs, which are managed by
The class DialogWindow implements modeless dialogs, which are managed by
Window::dispatch_dialog_msg() in Window::MessageLoop().
A Dialog object should be constructed by calling Window::Create()
A DialogWindow object should be constructed by calling Window::Create()
and specifying the class using the WINDOW_CREATOR() macro.
*/
struct DialogWindow : public Window
{
typedef Window super;
DialogWindow(HWND);
~DialogWindow();
};
/**
The class Dialog implements modal dialogs.
A DialogWindow object should be constructed by calling Dialog::DoModal()
and specifying the class using the WINDOW_CREATOR() macro.
*/
struct Dialog : public Window
@@ -315,6 +332,126 @@ struct Dialog : public Window
Dialog(HWND);
~Dialog();
static int DoModal(UINT nid, CREATORFUNC creator, HWND hwndParent);
static int DoModal(UINT nid, CREATORFUNC creator, const void* info, HWND hwndParent);
protected:
LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
int Command(int id, int code);
};
#define PM_FRM_CALC_CLIENT (WM_APP+0x03)
#define Frame_CalcFrameClient(hwnd, prt) ((BOOL)SNDMSG(hwnd, PM_FRM_CALC_CLIENT, 0, (LPARAM)(PRECT)prt))
// Layouting of resizable windows
enum RESIZE_FLAGS {
MOVE_LEFT = 0x1,
MOVE_RIGHT = 0x2,
MOVE_TOP = 0x4,
MOVE_BOTTOM = 0x8,
MOVE_X = MOVE_LEFT | MOVE_RIGHT,
MOVE_Y = MOVE_TOP | MOVE_BOTTOM,
RESIZE_X= MOVE_RIGHT,
RESIZE_Y= MOVE_BOTTOM,
MOVE = MOVE_X | MOVE_Y,
RESIZE = RESIZE_X | RESIZE_Y
};
struct ResizeEntry
{
ResizeEntry(UINT id, int flags)
: _id(id), _flags(flags) {}
ResizeEntry(HWND hwnd, int flags)
: _id(GetDlgCtrlID(hwnd)), _flags(flags) {}
UINT _id;
int _flags;
};
struct ResizeManager : public std::list<ResizeEntry>
{
typedef std::list<ResizeEntry> super;
ResizeManager(HWND hwnd);
void Add(UINT id, int flags)
{push_back(ResizeEntry(id, flags));}
void Add(HWND hwnd, int flags)
{push_back(ResizeEntry(hwnd, flags));}
void HandleSize(int cx, int cy);
void Resize(int dx, int dy);
void SetMinMaxInfo(LPMINMAXINFO lpmmi)
{
lpmmi->ptMinTrackSize.x = _min_wnd_size.cx;
lpmmi->ptMinTrackSize.y = _min_wnd_size.cy;
}
SIZE _min_wnd_size;
protected:
HWND _hwnd;
SIZE _last_size;
};
template<typename BASE> struct ResizeController : public BASE
{
typedef BASE super;
ResizeController(HWND hwnd)
: super(hwnd),
_resize_mgr(hwnd)
{
}
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam)
{
switch(message) {
case PM_FRM_CALC_CLIENT:
GetClientSpace((PRECT)lparam);
return TRUE;
case WM_SIZE:
if (wparam != SIZE_MINIMIZED)
_resize_mgr.HandleSize(LOWORD(lparam), HIWORD(lparam));
goto def;
case WM_GETMINMAXINFO:
_resize_mgr.SetMinMaxInfo((LPMINMAXINFO)lparam);
goto def;
default: def:
return super::WndProc(message, wparam, lparam);
}
}
virtual void GetClientSpace(PRECT prect)
{
if (!IsIconic(_hwnd)) {
GetClientRect(_hwnd, prect);
} else {
WINDOWPLACEMENT wp;
GetWindowPlacement(_hwnd, &wp);
prect->left = prect->top = 0;
prect->right = wp.rcNormalPosition.right-wp.rcNormalPosition.left-
2*(GetSystemMetrics(SM_CXSIZEFRAME)+GetSystemMetrics(SM_CXEDGE));
prect->bottom = wp.rcNormalPosition.bottom-wp.rcNormalPosition.top-
2*(GetSystemMetrics(SM_CYSIZEFRAME)+GetSystemMetrics(SM_CYEDGE))-
GetSystemMetrics(SM_CYCAPTION)-GetSystemMetrics(SM_CYMENUSIZE);
}
}
protected:
ResizeManager _resize_mgr;
};
@@ -345,7 +482,7 @@ struct Static : public WindowHandle
/*
// control color message routing for ColorStatic and HyperlinkCtrl
#define PM_DISPATCH_CTLCOLOR (WM_APP+0x07)
#define PM_DISPATCH_CTLCOLOR (WM_APP+0x08)
template<typename BASE> struct CtlColorParent : public BASE
{
@@ -376,7 +513,7 @@ template<typename BASE> struct CtlColorParent : public BASE
// owner draw message routing for ColorButton and PictureButton
#define PM_DISPATCH_DRAWITEM (WM_APP+0x08)
#define PM_DISPATCH_DRAWITEM (WM_APP+0x09)
template<typename BASE> struct OwnerDrawParent : public BASE
{