mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
multithreading for class Window; usage of window map insted of GWL_USERDATA
svn path=/trunk/; revision=5915
This commit is contained in:
parent
9665ee6bdb
commit
ed65784cec
10 changed files with 187 additions and 52 deletions
|
@ -88,15 +88,17 @@ void explorer_show_frame(HWND hwndDesktop, int cmdshow)
|
|||
g_Globals._prescan_nodes = false;
|
||||
|
||||
// create main window
|
||||
HWND hwndFrame = MainFrame::Create();
|
||||
HWND hMainFrame = MainFrame::Create();
|
||||
|
||||
g_Globals._hMainWnd = hwndFrame;
|
||||
if (hMainFrame) {
|
||||
g_Globals._hMainWnd = hMainFrame;
|
||||
|
||||
ShowWindow(hwndFrame, cmdshow);
|
||||
UpdateWindow(hwndFrame);
|
||||
ShowWindow(hMainFrame, cmdshow);
|
||||
UpdateWindow(hMainFrame);
|
||||
|
||||
// Open the first child window after initializing the whole application
|
||||
PostMessage(hwndFrame, PM_OPEN_WINDOW, TRUE/*mode_explore*/, 0);
|
||||
PostMessage(hMainFrame, PM_OPEN_WINDOW, TRUE/*mode_explore*/, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -167,6 +167,28 @@ HWND MainFrame::Create()
|
|||
0/*hwndDesktop*/, hMenuFrame);
|
||||
}
|
||||
|
||||
HWND MainFrame::Create(LPCTSTR path, BOOL mode_explore)
|
||||
{
|
||||
HWND hMainFrame = Create();
|
||||
if (!hMainFrame)
|
||||
return 0;
|
||||
|
||||
ShowWindow(hMainFrame, SW_SHOW);
|
||||
|
||||
MainFrame* pMainFrame = GET_WINDOW(MainFrame, hMainFrame);
|
||||
|
||||
if (pMainFrame)
|
||||
pMainFrame->CreateChild(path, mode_explore);
|
||||
|
||||
return hMainFrame;
|
||||
}
|
||||
|
||||
|
||||
ChildWindow* MainFrame::CreateChild(LPCTSTR path, BOOL mode_explore)
|
||||
{
|
||||
return reinterpret_cast<ChildWindow*>(SendMessage(_hwnd, PM_OPEN_WINDOW, mode_explore, (LPARAM)path));
|
||||
}
|
||||
|
||||
|
||||
LRESULT MainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
|
@ -237,8 +259,7 @@ LRESULT MainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
|||
create_info._mode_explore = wparam? true: false;
|
||||
|
||||
// FileChildWindow::create(_hmdiclient, create_info);
|
||||
ShellBrowserChild::create(_hmdiclient, create_info);
|
||||
break;}
|
||||
return (LRESULT)ShellBrowserChild::create(_hmdiclient, create_info);}
|
||||
|
||||
case PM_GET_CONTROLWINDOW:
|
||||
if (wparam == FCW_STATUS)
|
||||
|
|
|
@ -34,6 +34,9 @@ struct MainFrame : public PreTranslateWindow
|
|||
~MainFrame();
|
||||
|
||||
static HWND Create();
|
||||
static HWND Create(LPCTSTR path, BOOL mode_explore=TRUE);
|
||||
|
||||
ChildWindow* CreateChild(LPCTSTR path=NULL, BOOL mode_explore=TRUE);
|
||||
|
||||
protected:
|
||||
FullScreenParameters _fullscreen;
|
||||
|
|
|
@ -252,7 +252,7 @@ LRESULT DesktopBar::ProcessCopyData(COPYDATASTRUCT* pcd)
|
|||
|
||||
//TODO: process the differnt versions of the NOTIFYICONDATA structure (look at cbSize to decide which one)
|
||||
|
||||
NotifyArea* notify_area = static_cast<NotifyArea*>(get_window(_hwndNotify));
|
||||
NotifyArea* notify_area = GET_WINDOW(NotifyArea, _hwndNotify);
|
||||
|
||||
if (notify_area)
|
||||
return notify_area->ProcessTrayNotification(ptr->notify_code, &ptr->nicon_data);
|
||||
|
|
|
@ -562,6 +562,36 @@ HWND StartMenuRoot::Create(HWND hwndDesktopBar)
|
|||
}
|
||||
|
||||
|
||||
void StartMenuRoot::TrackStartmenu()
|
||||
{
|
||||
//TODO
|
||||
|
||||
MSG msg;
|
||||
|
||||
while(GetMessage(&msg, 0, 0, 0)) {
|
||||
try {
|
||||
if (pretranslate_msg(&msg))
|
||||
continue;
|
||||
|
||||
if (dispatch_dialog_msg(&msg))
|
||||
continue;
|
||||
|
||||
TranslateMessage(&msg);
|
||||
|
||||
try {
|
||||
DispatchMessage(&msg);
|
||||
} catch(COMException& e) {
|
||||
HandleException(e, g_Globals._hMainWnd);
|
||||
}
|
||||
} catch(COMException& e) {
|
||||
HandleException(e, g_Globals._hMainWnd);
|
||||
}
|
||||
}
|
||||
|
||||
//@@return msg.wParam;
|
||||
}
|
||||
|
||||
|
||||
LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs)
|
||||
{
|
||||
// add buttons for entries in _entries
|
||||
|
@ -656,12 +686,10 @@ int StartMenuRoot::Command(int id, int code)
|
|||
CreateSubmenu(id, CSIDL_CONTROLS);
|
||||
break;
|
||||
|
||||
case IDC_SETTINGS_WND: { //TODO: make more object oriented, e.g introduce a class CabinetWindow
|
||||
case IDC_SETTINGS_WND:
|
||||
CloseStartMenu(id);
|
||||
HWND hwndFrame = MainFrame::Create();
|
||||
ShowWindow(hwndFrame, SW_SHOW);
|
||||
SendMessage(hwndFrame, PM_OPEN_WINDOW, FALSE/*mode_explore*/, (LPARAM)_T("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"));
|
||||
break;}
|
||||
MainFrame::Create(_T("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"), FALSE);
|
||||
break;
|
||||
|
||||
case IDC_FAVORITES:
|
||||
CreateSubmenu(id, CSIDL_FAVORITES);
|
||||
|
|
|
@ -206,6 +206,7 @@ struct StartMenuRoot : public StartMenu
|
|||
StartMenuRoot(HWND hwnd);
|
||||
|
||||
static HWND Create(HWND hwndDesktopBar);
|
||||
void TrackStartmenu();
|
||||
|
||||
protected:
|
||||
LRESULT Init(LPCREATESTRUCT pcs);
|
||||
|
|
|
@ -124,7 +124,7 @@ LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
|||
case WM_TIMER: {
|
||||
TimerTick();
|
||||
|
||||
ClockWindow* clock_window = static_cast<ClockWindow*>(get_window(_hwndClock));
|
||||
ClockWindow* clock_window = GET_WINDOW(ClockWindow, _hwndClock);
|
||||
|
||||
if (clock_window)
|
||||
clock_window->TimerTick();
|
||||
|
|
|
@ -124,6 +124,55 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
struct WindowHandle
|
||||
{
|
||||
WindowHandle(HWND hwnd=0)
|
||||
: _hwnd(hwnd) {}
|
||||
|
||||
operator HWND() const {return _hwnd;}
|
||||
HWND* operator&() {return &_hwnd;}
|
||||
|
||||
protected:
|
||||
HWND _hwnd;
|
||||
};
|
||||
|
||||
|
||||
/// critical section wrapper
|
||||
|
||||
struct CritSect : public CRITICAL_SECTION
|
||||
{
|
||||
CritSect()
|
||||
{
|
||||
InitializeCriticalSection(this);
|
||||
}
|
||||
|
||||
~CritSect()
|
||||
{
|
||||
DeleteCriticalSection(this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Lock protects a code section utilizing a critical section
|
||||
|
||||
struct Lock
|
||||
{
|
||||
Lock(CritSect& crit_sect)
|
||||
: _crit_sect(crit_sect)
|
||||
{
|
||||
EnterCriticalSection(&crit_sect);
|
||||
}
|
||||
|
||||
~Lock()
|
||||
{
|
||||
LeaveCriticalSection(&_crit_sect);
|
||||
}
|
||||
|
||||
protected:
|
||||
CritSect& _crit_sect;
|
||||
};
|
||||
|
||||
|
||||
// window utilities
|
||||
|
||||
struct ClientRect : public RECT
|
||||
|
|
|
@ -58,8 +58,29 @@ IconWindowClass::IconWindowClass(LPCTSTR classname, UINT nid, UINT style, WNDPRO
|
|||
|
||||
|
||||
HHOOK Window::s_hcbtHook = 0;
|
||||
|
||||
Window::CREATORFUNC Window::s_window_creator = NULL;
|
||||
const void* Window::s_new_info = NULL;
|
||||
CritSect Window::s_create_crit_sect;
|
||||
|
||||
Window::WindowMap Window::s_wnd_map;
|
||||
CritSect Window::s_map_crit_sect;
|
||||
|
||||
|
||||
Window::Window(HWND hwnd)
|
||||
: WindowHandle(hwnd)
|
||||
{
|
||||
Lock lock(s_map_crit_sect); // protect access to s_wnd_map
|
||||
|
||||
s_wnd_map[_hwnd] = this;
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
Lock lock(s_map_crit_sect); // protect access to s_wnd_map
|
||||
|
||||
s_wnd_map.erase(_hwnd);
|
||||
}
|
||||
|
||||
|
||||
HWND Window::Create(CREATORFUNC creator, DWORD dwExStyle,
|
||||
|
@ -67,6 +88,8 @@ HWND Window::Create(CREATORFUNC creator, DWORD dwExStyle,
|
|||
DWORD dwStyle, int x, int y, int w, int h,
|
||||
HWND hwndParent, HMENU hMenu, LPVOID lpParam)
|
||||
{
|
||||
Lock lock(s_create_crit_sect); // protect access to s_window_creator and s_new_info
|
||||
|
||||
s_window_creator = creator;
|
||||
s_new_info = NULL;
|
||||
|
||||
|
@ -80,6 +103,8 @@ HWND Window::Create(CREATORFUNC creator, const void* info, DWORD dwExStyle,
|
|||
DWORD dwStyle, int x, int y, int w, int h,
|
||||
HWND hwndParent, HMENU hMenu, LPVOID lpParam)
|
||||
{
|
||||
Lock lock(s_create_crit_sect); // protect access to s_window_creator and s_new_info
|
||||
|
||||
s_window_creator = creator;
|
||||
s_new_info = info;
|
||||
|
||||
|
@ -93,6 +118,8 @@ static Window* s_new_child_wnd = NULL;
|
|||
|
||||
Window* Window::create_mdi_child(HWND hmdiclient, const MDICREATESTRUCT& mcs, CREATORFUNC creator, const void* info)
|
||||
{
|
||||
Lock lock(s_create_crit_sect); // protect access to s_window_creator and s_new_info
|
||||
|
||||
s_window_creator = creator;
|
||||
s_new_info = info;
|
||||
s_new_child_wnd = NULL;
|
||||
|
@ -132,12 +159,18 @@ LRESULT CALLBACK Window::CBTHookProc(int code, WPARAM wparam, LPARAM lparam)
|
|||
|
||||
Window* Window::get_window(HWND hwnd)
|
||||
{
|
||||
Window* wnd = (Window*) GetWindowLong(hwnd, GWL_USERDATA);
|
||||
{
|
||||
Lock lock(s_map_crit_sect); // protect access to s_wnd_map
|
||||
|
||||
if (wnd)
|
||||
return wnd;
|
||||
WindowMap::const_iterator found = s_wnd_map.find(hwnd);
|
||||
|
||||
if (found!=s_wnd_map.end())
|
||||
return found->second;
|
||||
}
|
||||
|
||||
if (s_window_creator) { // protect for recursion
|
||||
Lock lock(s_create_crit_sect); // protect access to s_window_creator and s_new_info
|
||||
|
||||
const void* info = s_new_info;
|
||||
s_new_info = NULL;
|
||||
|
||||
|
@ -145,12 +178,12 @@ Window* Window::get_window(HWND hwnd)
|
|||
s_window_creator = NULL;
|
||||
|
||||
if (info)
|
||||
wnd = window_creator(hwnd, info);
|
||||
return window_creator(hwnd, info);
|
||||
else
|
||||
wnd = CREATORFUNC_NO_INFO(window_creator)(hwnd);
|
||||
return CREATORFUNC_NO_INFO(window_creator)(hwnd);
|
||||
}
|
||||
|
||||
return wnd;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -191,11 +224,12 @@ LRESULT Window::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
|||
{
|
||||
HWND hwnd = _hwnd;
|
||||
|
||||
/*@@TODO: replace by StartMenu::TrackStartmenu()
|
||||
// close startup menu and other popup menus
|
||||
// This functionality is for tray notification icons missing in MS Windows.
|
||||
if (nmsg == WM_SETFOCUS)
|
||||
CancelModes((HWND)wparam); //@@ erronesly cancels desktop bar resize when switching from another process
|
||||
|
||||
*/
|
||||
return DefWindowProc(hwnd, nmsg, wparam, lparam);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,19 +45,6 @@ typedef set<HWND> WindowSet;
|
|||
*/
|
||||
|
||||
|
||||
struct WindowHandle
|
||||
{
|
||||
WindowHandle(HWND hwnd=0)
|
||||
: _hwnd(hwnd) {}
|
||||
|
||||
operator HWND() const {return _hwnd;}
|
||||
HWND* operator&() {return &_hwnd;}
|
||||
|
||||
protected:
|
||||
HWND _hwnd;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Class Window is the base class for several C++ window wrapper classes.
|
||||
Window objects are allocated from the heap. They are automatically freed
|
||||
|
@ -65,19 +52,11 @@ protected:
|
|||
*/
|
||||
struct Window : public WindowHandle
|
||||
{
|
||||
Window(HWND hwnd)
|
||||
: WindowHandle(hwnd)
|
||||
{
|
||||
// store "this" pointer as user data
|
||||
SetWindowLong(hwnd, GWL_USERDATA, (LONG)this);
|
||||
}
|
||||
Window(HWND hwnd);
|
||||
virtual ~Window();
|
||||
|
||||
virtual ~Window()
|
||||
{
|
||||
// empty user data field
|
||||
SetWindowLong(_hwnd, GWL_USERDATA, 0);
|
||||
}
|
||||
|
||||
typedef map<HWND,Window*> WindowMap;
|
||||
|
||||
typedef Window* (*CREATORFUNC)(HWND, const void*);
|
||||
typedef Window* (*CREATORFUNC_NO_INFO)(HWND);
|
||||
|
@ -95,8 +74,12 @@ struct Window : public WindowHandle
|
|||
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);
|
||||
|
||||
static Window* get_window(HWND hwnd);
|
||||
#ifndef _MSC_VER
|
||||
template<typename WNDCLASS> static WNDCLASS* get_window(HWND hwnd) {return static_cast<WNDCLASS*>(get_window(hwnd));}
|
||||
#define GET_WINDOW(WNDCLASS, hwnd) Window::get_window<WNDCLASS>(hwnd)
|
||||
#endif
|
||||
|
||||
static void register_pretranslate(HWND hwnd);
|
||||
static void unregister_pretranslate(HWND hwnd);
|
||||
|
@ -122,8 +105,12 @@ protected:
|
|||
virtual int Notify(int id, NMHDR* pnmh); // WM_NOTIFY processing
|
||||
|
||||
|
||||
static const void* s_new_info; //TODO: protect for multithreaded access
|
||||
static CREATORFUNC s_window_creator; //TODO: protect for multithreaded access
|
||||
static WindowMap s_wnd_map;
|
||||
static CritSect s_map_crit_sect;
|
||||
|
||||
static const void* s_new_info;
|
||||
static CREATORFUNC s_window_creator;
|
||||
static CritSect s_create_crit_sect;
|
||||
|
||||
// MDI child creation
|
||||
static HHOOK s_hcbtHook;
|
||||
|
@ -134,6 +121,16 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
template<typename WNDCLASS> struct GetWindowHelper {
|
||||
static WNDCLASS* get_window(HWND hwnd) {
|
||||
return static_cast<WNDCLASS*>(Window::get_window(hwnd));
|
||||
}
|
||||
};
|
||||
#define GET_WINDOW(WNDCLASS, hwnd) GetWindowHelper<WNDCLASS>::get_window(hwnd)
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
SubclassedWindow is used to wrap already existing window handles
|
||||
into C++ Window objects. To construct a object, use the "new" operator
|
||||
|
|
Loading…
Reference in a new issue