From ddcf08e7d2595be1f6af085f0ea79fc638b7b1f2 Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Fri, 22 Aug 2003 18:25:48 +0000 Subject: [PATCH] double buffering svn path=/trunk/; revision=5763 --- .../subsys/system/explorer/explorer_intres.h | 2 +- .../system/explorer/taskbar/desktopbar.cpp | 10 +-- .../system/explorer/taskbar/taskbar.cpp | 9 +++ .../subsys/system/explorer/taskbar/taskbar.h | 2 + .../system/explorer/taskbar/traynotify.cpp | 45 ++++++++---- .../system/explorer/taskbar/traynotify.h | 6 +- .../subsys/system/explorer/utility/utility.h | 73 +++++++++++++++++++ .../subsys/system/explorer/utility/window.cpp | 32 ++++---- .../subsys/system/explorer/utility/window.h | 2 + 9 files changed, 139 insertions(+), 42 deletions(-) diff --git a/reactos/subsys/system/explorer/explorer_intres.h b/reactos/subsys/system/explorer/explorer_intres.h index 597920652bb..0615c3edc2c 100644 --- a/reactos/subsys/system/explorer/explorer_intres.h +++ b/reactos/subsys/system/explorer/explorer_intres.h @@ -67,7 +67,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 127 +#define _APS_NEXT_RESOURCE_VALUE 128 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 101 diff --git a/reactos/subsys/system/explorer/taskbar/desktopbar.cpp b/reactos/subsys/system/explorer/taskbar/desktopbar.cpp index e223471ff8e..d3a12627b78 100644 --- a/reactos/subsys/system/explorer/taskbar/desktopbar.cpp +++ b/reactos/subsys/system/explorer/taskbar/desktopbar.cpp @@ -81,20 +81,14 @@ LRESULT DesktopBar::Init(LPCREATESTRUCT pcs) new PictureButton(Button(_hwnd, ResString(IDS_START), 2, 2, STARTBUTTON_WIDTH, DESKTOPBARBAR_HEIGHT-8, IDC_START, WS_VISIBLE|WS_CHILD|BS_OWNERDRAW), SmallIcon(IDI_STARTMENU)); - ClientRect clnt(_hwnd); - // create task bar - _hwndTaskBar = Window::Create(WINDOW_CREATOR(TaskBar), 0, - BtnWindowClass(CLASSNAME_TASKBAR), TITLE_TASKBAR, WS_CHILD|WS_VISIBLE, - TASKBAR_LEFT, 0, clnt.right-TASKBAR_LEFT-(NOTIFYAREA_WIDTH+1), DESKTOPBARBAR_HEIGHT, _hwnd); + _hwndTaskBar = TaskBar::Create(_hwnd); TaskBar* taskbar = static_cast(get_window(_hwndTaskBar)); taskbar->_desktop_bar = this; // create tray notification area - _hwndNotify = Window::Create(WINDOW_CREATOR(NotifyArea), WS_EX_STATICEDGE, - BtnWindowClass(CLASSNAME_TRAYNOTIFY,CS_DBLCLKS), TITLE_TRAYNOTIFY, WS_CHILD|WS_VISIBLE, - clnt.right-(NOTIFYAREA_WIDTH+1), 1, NOTIFYAREA_WIDTH, clnt.bottom-2, _hwnd); + _hwndNotify = NotifyArea::Create(_hwnd); // NotifyArea* notify_area = static_cast(get_window(_hwndNotify)); // notify_area->_desktop_bar = this; diff --git a/reactos/subsys/system/explorer/taskbar/taskbar.cpp b/reactos/subsys/system/explorer/taskbar/taskbar.cpp index 554c57446c4..973b4bf9577 100644 --- a/reactos/subsys/system/explorer/taskbar/taskbar.cpp +++ b/reactos/subsys/system/explorer/taskbar/taskbar.cpp @@ -64,6 +64,15 @@ TaskBar::~TaskBar() //DeinstallShellHook(); } +HWND TaskBar::Create(HWND hwndParent) +{ + ClientRect clnt(hwndParent); + + return Window::Create(WINDOW_CREATOR(TaskBar), 0, + BtnWindowClass(CLASSNAME_TASKBAR), TITLE_TASKBAR, WS_CHILD|WS_VISIBLE, + TASKBAR_LEFT, 0, clnt.right-TASKBAR_LEFT/*-(NOTIFYAREA_WIDTH+1)*/, clnt.bottom, hwndParent); +} + LRESULT TaskBar::Init(LPCREATESTRUCT pcs) { if (super::Init(pcs)) diff --git a/reactos/subsys/system/explorer/taskbar/taskbar.h b/reactos/subsys/system/explorer/taskbar/taskbar.h index 6b43216a93e..d8ff416eb8c 100644 --- a/reactos/subsys/system/explorer/taskbar/taskbar.h +++ b/reactos/subsys/system/explorer/taskbar/taskbar.h @@ -76,6 +76,8 @@ struct TaskBar : public Window TaskBar(HWND hwnd); ~TaskBar(); + static HWND Create(HWND hwndParent); + DesktopBar* _desktop_bar; // may be not necessary protected: diff --git a/reactos/subsys/system/explorer/taskbar/traynotify.cpp b/reactos/subsys/system/explorer/taskbar/traynotify.cpp index f95a15781bb..6d1ac23a570 100644 --- a/reactos/subsys/system/explorer/taskbar/traynotify.cpp +++ b/reactos/subsys/system/explorer/taskbar/traynotify.cpp @@ -91,12 +91,8 @@ LRESULT NotifyArea::Init(LPCREATESTRUCT pcs) if (super::Init(pcs)) return 1; - ClientRect clnt(_hwnd); - // create clock window - _hwndClock = Window::Create(WINDOW_CREATOR(ClockWindow), 0, - BtnWindowClass(CLASSNAME_CLOCKWINDOW,CS_DBLCLKS), NULL, WS_CHILD|WS_VISIBLE, - clnt.right-(CLOCKWINDOW_WIDTH+1), 1, CLOCKWINDOW_WIDTH, clnt.bottom-2, _hwnd); + _hwndClock = ClockWindow::Create(_hwnd); SetTimer(_hwnd, 0, 1000, NULL); @@ -108,6 +104,15 @@ NotifyArea::~NotifyArea() KillTimer(_hwnd, 0); } +HWND NotifyArea::Create(HWND hwndParent) +{ + ClientRect clnt(hwndParent); + + return Window::Create(WINDOW_CREATOR(NotifyArea), WS_EX_STATICEDGE, + BtnWindowClass(CLASSNAME_TRAYNOTIFY,CS_DBLCLKS), TITLE_TRAYNOTIFY, WS_CHILD|WS_VISIBLE, + clnt.right-(NOTIFYAREA_WIDTH+1), 1, NOTIFYAREA_WIDTH, clnt.bottom-2, hwndParent); +} + LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) { switch(nmsg) { @@ -133,7 +138,7 @@ LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) || nmsg==WM_XBUTTONDOWN #endif ) - CancelModes(0); + CancelModes(); NotifyIconSet::iterator found = IconHitTest(Point(lparam)); @@ -154,16 +159,12 @@ LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) return 0; } -void NotifyArea::CancelModes(HWND hwnd) +void NotifyArea::CancelModes() { - if (hwnd) - PostMessage(hwnd, WM_CANCELMODE, 0, 0); - else { - PostMessage(HWND_BROADCAST, WM_CANCELMODE, 0, 0); + PostMessage(HWND_BROADCAST, WM_CANCELMODE, 0, 0); - for(NotifyIconSet::const_iterator it=_sorted_icons.begin(); it!=_sorted_icons.end(); ++it) - PostMessage(it->_hWnd, WM_CANCELMODE, 0, 0); - } + for(NotifyIconSet::const_iterator it=_sorted_icons.begin(); it!=_sorted_icons.end(); ++it) + PostMessage(it->_hWnd, WM_CANCELMODE, 0, 0); } LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pnid) @@ -213,13 +214,16 @@ void NotifyArea::Refresh() _sorted_icons.insert(entry); } - InvalidateRect(_hwnd, NULL, TRUE); // refresh icon display + InvalidateRect(_hwnd, NULL, FALSE); // refresh icon display UpdateWindow(_hwnd); } void NotifyArea::Paint() { - PaintCanvas canvas(_hwnd); + BufferedPaintCanvas canvas(_hwnd); + + // first fill with the background color + FillRect(canvas, &canvas.rcPaint, GetSysColorBrush(COLOR_BTNFACE)); // draw icons int x = 2; @@ -279,6 +283,15 @@ ClockWindow::ClockWindow(HWND hwnd) FormatTime(); } +HWND ClockWindow::Create(HWND hwndParent) +{ + ClientRect clnt(hwndParent); + + return Window::Create(WINDOW_CREATOR(ClockWindow), 0, + BtnWindowClass(CLASSNAME_CLOCKWINDOW,CS_DBLCLKS), NULL, WS_CHILD|WS_VISIBLE, + clnt.right-(CLOCKWINDOW_WIDTH+1), 1, CLOCKWINDOW_WIDTH, clnt.bottom-2, hwndParent); +} + LRESULT ClockWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) { switch(nmsg) { diff --git a/reactos/subsys/system/explorer/taskbar/traynotify.h b/reactos/subsys/system/explorer/taskbar/traynotify.h index 338aa0fcae0..a835111f7ed 100644 --- a/reactos/subsys/system/explorer/taskbar/traynotify.h +++ b/reactos/subsys/system/explorer/taskbar/traynotify.h @@ -78,6 +78,8 @@ struct NotifyArea : public Window NotifyArea(HWND hwnd); ~NotifyArea(); + static HWND Create(HWND hwndParent); + // DesktopBar* _desktop_bar; LRESULT ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pnid); @@ -95,7 +97,7 @@ protected: void Refresh(); void Paint(); void TimerTick(); - void CancelModes(HWND hwnd); + void CancelModes(); NotifyIconSet::iterator IconHitTest(const POINT& pos); }; @@ -108,6 +110,8 @@ struct ClockWindow : public Window ClockWindow(HWND hwnd); + static HWND Create(HWND hwndParent); + void TimerTick(); protected: diff --git a/reactos/subsys/system/explorer/utility/utility.h b/reactos/subsys/system/explorer/utility/utility.h index 656c4d0d836..2338fd28a00 100644 --- a/reactos/subsys/system/explorer/utility/utility.h +++ b/reactos/subsys/system/explorer/utility/utility.h @@ -186,6 +186,79 @@ protected: HWND _hwnd; }; + + // double buffering classes + +struct Canvas +{ + Canvas(HDC hdc) : _hdc(hdc) {} + + operator HDC() {return _hdc;} + +protected: + HDC _hdc; +}; + +struct MemCanvas : public Canvas +{ + MemCanvas(HDC hdc=0) + : Canvas(CreateCompatibleDC(hdc)) {assert(_hdc);} + + ~MemCanvas() {DeleteDC(_hdc);} +}; + +struct SelectedBitmap +{ + SelectedBitmap(HDC hdc, HBITMAP hbmp) + : _hdc(hdc), _old_hbmp(SelectBitmap(hdc, hbmp)) {} + + ~SelectedBitmap() {SelectBitmap(_hdc, _old_hbmp);} + +protected: + HDC _hdc; + HBITMAP _old_hbmp; +}; + +struct BufferCanvas : public MemCanvas +{ + BufferCanvas(HDC hdc, int x, int y, int w, int h) + : MemCanvas(hdc), _hdctarg(hdc), + _x(x), _y(y), _w(w), _h(h), + _bmp(_hdc, CreateCompatibleBitmap(hdc, w, h)) {} + + BufferCanvas(HDC hdc, const RECT& rect) + : MemCanvas(hdc), _hdctarg(hdc), + _x(rect.left), _y(rect.top), _w(rect.right-rect.left), _h(rect.bottom-rect.top), + _bmp(_hdc, CreateCompatibleBitmap(hdc, _w, _h)) {} + +protected: + HDC _hdctarg; + int _x, _y, _w, _h; + SelectedBitmap _bmp; +}; + +struct BufferedCanvas : public BufferCanvas +{ + BufferedCanvas(HDC hdc, int x, int y, int w, int h, DWORD mode=SRCCOPY) + : BufferCanvas(hdc, x, y, w, h), _mode(mode) {} + + BufferedCanvas(HDC hdc, const RECT& rect, DWORD mode=SRCCOPY) + : BufferCanvas(hdc, rect), _mode(mode) {} + + ~BufferedCanvas() {BitBlt(_hdctarg, _x, _y, _w, _h, _hdc, 0, 0, _mode);} + + DWORD _mode; +}; + +struct BufferedPaintCanvas : public PaintCanvas, public BufferedCanvas +{ + BufferedPaintCanvas(HWND hwnd) + : PaintCanvas(hwnd), BufferedCanvas(hdc, 0, 0, rcPaint.right, rcPaint.bottom) {} + + operator HDC() {return BufferedCanvas::_hdc;} +}; + + struct TextColor { TextColor(HDC hdc, COLORREF color) diff --git a/reactos/subsys/system/explorer/utility/window.cpp b/reactos/subsys/system/explorer/utility/window.cpp index 70e879a5d1a..8c456c13973 100644 --- a/reactos/subsys/system/explorer/utility/window.cpp +++ b/reactos/subsys/system/explorer/utility/window.cpp @@ -186,14 +186,10 @@ LRESULT CALLBACK Window::WindowWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPAR LRESULT Window::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) { - if (nmsg == WM_SETFOCUS) { - // close startup menu and other popup menus - // This functionality is for tray notification icons missing in MS Windows. - if (wparam) - PostMessage((HWND)wparam, WM_CANCELMODE, 0, 0); - else - PostMessage(HWND_BROADCAST, WM_CANCELMODE, 0, 0); - } + // 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); return DefWindowProc(_hwnd, nmsg, wparam, lparam); } @@ -208,6 +204,14 @@ int Window::Notify(int id, NMHDR* pnmh) return 0; } +void Window::CancelModes(HWND hwnd) +{ + if (hwnd) + PostMessage(hwnd, WM_CANCELMODE, 0, 0); + else + PostMessage(HWND_BROADCAST, WM_CANCELMODE, 0, 0); +} + SubclassedWindow::SubclassedWindow(HWND hwnd) : super(hwnd) @@ -220,14 +224,10 @@ SubclassedWindow::SubclassedWindow(HWND hwnd) LRESULT SubclassedWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) { - if (nmsg == WM_SETFOCUS) { - // close startup menu and other popup menus - // This functionality is for tray notification icons missing in MS Windows. - if (wparam) - PostMessage((HWND)wparam, WM_CANCELMODE, 0, 0); - else - PostMessage(HWND_BROADCAST, WM_CANCELMODE, 0, 0); - } + // 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); return CallWindowProc(_orgWndProc, _hwnd, nmsg, wparam, lparam); } diff --git a/reactos/subsys/system/explorer/utility/window.h b/reactos/subsys/system/explorer/utility/window.h index 2784cebfdf5..b42e421841f 100644 --- a/reactos/subsys/system/explorer/utility/window.h +++ b/reactos/subsys/system/explorer/utility/window.h @@ -111,6 +111,8 @@ struct Window : public WindowHandle LRESULT SendParent(UINT nmsg, WPARAM wparam=0, LPARAM lparam=0); LRESULT PostParent(UINT nmsg, WPARAM wparam=0, LPARAM lparam=0); + static void CancelModes(HWND hwnd=0); + protected: virtual LRESULT Init(LPCREATESTRUCT pcs); // WM_CREATE processing