← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2271: Support taskbar thumbnails and "Aero Peek" live previews on Win 7

 

------------------------------------------------------------
revno: 2271
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Fri 2010-10-29 00:43:23 +0200
message:
  Support taskbar thumbnails and "Aero Peek" live previews on Win 7
added:
  dwt/include/dwt/Taskbar.h
  dwt/include/dwt/dwt_dwmapi.h
  dwt/include/dwt/dwt_shlobj.h
  dwt/src/Taskbar.cpp
modified:
  changelog.txt
  dwt/include/dwt/WindowsHeaders.h
  dwt/include/dwt/util/win32/Version.h
  dwt/include/dwt/widgets/FolderDialog.h
  dwt/include/dwt/widgets/TabView.h
  dwt/src/util/win32/Version.cpp
  dwt/src/widgets/Notification.cpp
  dwt/src/widgets/TabView.cpp
  win32/MainWindow.cpp
  win32/stdafx.h


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'changelog.txt'
--- changelog.txt	2010-10-20 20:49:31 +0000
+++ changelog.txt	2010-10-28 22:43:23 +0000
@@ -21,7 +21,8 @@
 * Customize the font selection dialog, save the charset (poy)
 * Blacklist rogue hub-lists (poy)
 * Fix some wrong menu fonts (poy)
-* Separate IP and Country coloumn in the list of users and connections (thanks iceman50)
+* Separate IP and Country columns in users and connections lists (thanks iceman50)
+* Support taskbar thumbnails and "Aero Peek" live previews on Win 7 (poy)
 
 -- 0.770 2010-07-05 --
 * [L#550300] Catch more potential file corruptions (thanks bigmuscle)

=== added file 'dwt/include/dwt/Taskbar.h'
--- dwt/include/dwt/Taskbar.h	1970-01-01 00:00:00 +0000
+++ dwt/include/dwt/Taskbar.h	2010-10-28 22:43:23 +0000
@@ -0,0 +1,73 @@
+/*
+  DC++ Widget Toolkit
+
+  Copyright (c) 2007-2010, Jacek Sieka
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without modification,
+  are permitted provided that the following conditions are met:
+
+      * Redistributions of source code must retain the above copyright notice,
+        this list of conditions and the following disclaimer.
+      * Redistributions in binary form must reproduce the above copyright notice,
+        this list of conditions and the following disclaimer in the documentation
+        and/or other materials provided with the distribution.
+      * Neither the name of the DWT nor the names of its contributors
+        may be used to endorse or promote products derived from this software
+        without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DWT_TASKBAR_H
+#define DWT_TASKBAR_H
+
+#include "WindowsHeaders.h"
+#include "forward.h"
+#include "resources/Bitmap.h"
+#include "resources/Icon.h"
+#include <unordered_map>
+
+namespace dwt {
+
+/** provides widgets with the ability to play with the taskbar associated with a main window. */
+class Taskbar {
+public:
+	void initTaskbar(WindowPtr window_);
+
+protected:
+	typedef std::function<void (ContainerPtr)> ActivateF;
+	/// @param activateF_ function called when the user activates a tab using the taskbar.
+	explicit Taskbar(const ActivateF& activateF_);
+	virtual ~Taskbar();
+
+	void addToTaskbar(ContainerPtr tab);
+	void removeFromTaskbar(ContainerPtr tab);
+	void moveOnTaskbar(ContainerPtr tab, ContainerPtr rightNeighbor = 0);
+	void setActiveOnTaskbar(ContainerPtr tab);
+	void setTaskbarIcon(ContainerPtr tab, const IconPtr& icon);
+
+	ITaskbarList3* taskbar;
+
+private:
+	BitmapPtr getBitmap(ContainerPtr tab, LPARAM thumbnailSize);
+
+	WindowPtr window;
+	std::unordered_map<ContainerPtr, ContainerPtr> tabs;
+
+	ActivateF activateF;
+};
+
+}
+
+#endif

=== modified file 'dwt/include/dwt/WindowsHeaders.h'
--- dwt/include/dwt/WindowsHeaders.h	2010-07-10 15:49:05 +0000
+++ dwt/include/dwt/WindowsHeaders.h	2010-10-28 22:43:23 +0000
@@ -70,6 +70,7 @@
 #include <windowsx.h>
 #include <shellapi.h>
 #include <shlwapi.h>
+#include "dwt_shlobj.h"
 #include <commctrl.h>
 #include <commdlg.h>
 #include <assert.h>

=== added file 'dwt/include/dwt/dwt_dwmapi.h'
--- dwt/include/dwt/dwt_dwmapi.h	1970-01-01 00:00:00 +0000
+++ dwt/include/dwt/dwt_dwmapi.h	2010-10-28 22:43:23 +0000
@@ -0,0 +1,51 @@
+/*
+  DC++ Widget Toolkit
+
+  Copyright (c) 2007-2010, Jacek Sieka
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without modification,
+  are permitted provided that the following conditions are met:
+
+      * Redistributions of source code must retain the above copyright notice,
+        this list of conditions and the following disclaimer.
+      * Redistributions in binary form must reproduce the above copyright notice,
+        this list of conditions and the following disclaimer in the documentation
+        and/or other materials provided with the distribution.
+      * Neither the name of the DWT nor SmartWin++ nor the names of its contributors
+        may be used to endorse or promote products derived from this software
+        without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DWT_DWMAPI_H
+#define DWT_DWMAPI_H
+
+#ifdef __GNUC__
+// MinGW lacks dwmapi.h, so define what we need here
+
+#define DWMWA_FORCE_ICONIC_REPRESENTATION 7
+#define DWMWA_FORCE_ICONIC_REPRESENTATION 10
+
+#else
+#include <dwmapi.h>
+#endif
+
+// in addition, we also define the following messages that are normally only defined for Win 7
+#if(_WIN32_WINNT < 0x0601)
+#define WM_DWMSENDICONICTHUMBNAIL 0x0323
+#define WM_DWMSENDICONICLIVEPREVIEWBITMAP 0x0326
+#endif
+
+#endif

=== added file 'dwt/include/dwt/dwt_shlobj.h'
--- dwt/include/dwt/dwt_shlobj.h	1970-01-01 00:00:00 +0000
+++ dwt/include/dwt/dwt_shlobj.h	2010-10-28 22:43:23 +0000
@@ -0,0 +1,124 @@
+/*
+  DC++ Widget Toolkit
+
+  Copyright (c) 2007-2010, Jacek Sieka
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without modification,
+  are permitted provided that the following conditions are met:
+
+      * Redistributions of source code must retain the above copyright notice,
+        this list of conditions and the following disclaimer.
+      * Redistributions in binary form must reproduce the above copyright notice,
+        this list of conditions and the following disclaimer in the documentation
+        and/or other materials provided with the distribution.
+      * Neither the name of the DWT nor SmartWin++ nor the names of its contributors
+        may be used to endorse or promote products derived from this software
+        without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DWT_SHLOBJ_H
+#define DWT_SHLOBJ_H
+
+#include <shlobj.h>
+
+#ifdef __GNUC__
+
+// defs for ITaskbarList, ITaskbarList2, ITaskbarList3 (incomplete - just the parts that we need)
+/// @todo MinGW-w64 seems to be implementing these, they have version 1 & 2, but not 3 yet... remove this when they have it.
+
+#ifndef __ITaskbarList_FWD_DEFINED__
+#define __ITaskbarList_FWD_DEFINED__
+typedef struct ITaskbarList ITaskbarList;
+#endif
+
+#ifndef __ITaskbarList2_FWD_DEFINED__
+#define __ITaskbarList2_FWD_DEFINED__
+typedef struct ITaskbarList2 ITaskbarList2;
+#endif
+
+#ifndef __ITaskbarList_INTERFACE_DEFINED__
+#define __ITaskbarList_INTERFACE_DEFINED__
+  EXTERN_C const IID IID_ITaskbarList;
+#if defined(__cplusplus) && !defined(CINTERFACE)
+  struct ITaskbarList : public IUnknown {
+  public:
+    virtual HRESULT WINAPI HrInit(void) = 0;
+    virtual HRESULT WINAPI AddTab(HWND hwnd) = 0;
+    virtual HRESULT WINAPI DeleteTab(HWND hwnd) = 0;
+    virtual HRESULT WINAPI ActivateTab(HWND hwnd) = 0;
+    virtual HRESULT WINAPI SetActiveAlt(HWND hwnd) = 0;
+  };
+#endif
+  HRESULT WINAPI ITaskbarList_HrInit_Proxy(ITaskbarList *This);
+  void __RPC_STUB ITaskbarList_HrInit_Stub(IRpcStubBuffer *This,IRpcChannelBuffer *_pRpcChannelBuffer,PRPC_MESSAGE _pRpcMessage,DWORD *_pdwStubPhase);
+  HRESULT WINAPI ITaskbarList_AddTab_Proxy(ITaskbarList *This,HWND hwnd);
+  void __RPC_STUB ITaskbarList_AddTab_Stub(IRpcStubBuffer *This,IRpcChannelBuffer *_pRpcChannelBuffer,PRPC_MESSAGE _pRpcMessage,DWORD *_pdwStubPhase);
+  HRESULT WINAPI ITaskbarList_DeleteTab_Proxy(ITaskbarList *This,HWND hwnd);
+  void __RPC_STUB ITaskbarList_DeleteTab_Stub(IRpcStubBuffer *This,IRpcChannelBuffer *_pRpcChannelBuffer,PRPC_MESSAGE _pRpcMessage,DWORD *_pdwStubPhase);
+  HRESULT WINAPI ITaskbarList_ActivateTab_Proxy(ITaskbarList *This,HWND hwnd);
+  void __RPC_STUB ITaskbarList_ActivateTab_Stub(IRpcStubBuffer *This,IRpcChannelBuffer *_pRpcChannelBuffer,PRPC_MESSAGE _pRpcMessage,DWORD *_pdwStubPhase);
+  HRESULT WINAPI ITaskbarList_SetActiveAlt_Proxy(ITaskbarList *This,HWND hwnd);
+  void __RPC_STUB ITaskbarList_SetActiveAlt_Stub(IRpcStubBuffer *This,IRpcChannelBuffer *_pRpcChannelBuffer,PRPC_MESSAGE _pRpcMessage,DWORD *_pdwStubPhase);
+#endif
+
+#ifndef __ITaskbarList2_INTERFACE_DEFINED__
+#define __ITaskbarList2_INTERFACE_DEFINED__
+  EXTERN_C const IID IID_ITaskbarList2;
+#if defined(__cplusplus) && !defined(CINTERFACE)
+  struct ITaskbarList2 : public ITaskbarList {
+  public:
+    virtual HRESULT WINAPI MarkFullscreenWindow(HWND hwnd,WINBOOL fFullscreen) = 0;
+  };
+#endif
+  HRESULT WINAPI ITaskbarList2_MarkFullscreenWindow_Proxy(ITaskbarList2 *This,HWND hwnd,WINBOOL fFullscreen);
+  void __RPC_STUB ITaskbarList2_MarkFullscreenWindow_Stub(IRpcStubBuffer *This,IRpcChannelBuffer *_pRpcChannelBuffer,PRPC_MESSAGE _pRpcMessage,DWORD *_pdwStubPhase);
+#endif
+
+#ifndef __ITaskbarList3_INTERFACE_DEFINED__
+#define __ITaskbarList3_INTERFACE_DEFINED__
+  EXTERN_C const IID IID_ITaskbarList3;
+#if defined(__cplusplus) && !defined(CINTERFACE)
+  struct ITaskbarList3 : public ITaskbarList2 {
+  public:
+        virtual HRESULT WINAPI RegisterTab( 
+            /* [in] */ HWND hwndTab,
+            /* [in] */ HWND hwndMDI) = 0;
+        
+        virtual HRESULT WINAPI UnregisterTab( 
+            /* [in] */ HWND hwndTab) = 0;
+        
+        virtual HRESULT WINAPI SetTabOrder( 
+            /* [in] */ HWND hwndTab,
+            /* [in] */ HWND hwndInsertBefore) = 0;
+        
+        virtual HRESULT WINAPI SetTabActive( 
+            /* [in] */ HWND hwndTab,
+            /* [in] */ HWND hwndMDI,
+            /* [in] */ DWORD dwReserved) = 0;
+  };
+#endif
+  HRESULT WINAPI ITaskbarList3_RegisterTab_Proxy(ITaskbarList3 *This,HWND hwnd,HWND hwndMDI);
+  void __RPC_STUB ITaskbarList3_RegisterTab_Stub(IRpcStubBuffer *This,IRpcChannelBuffer *_pRpcChannelBuffer,PRPC_MESSAGE _pRpcMessage,DWORD *_pdwStubPhase);
+  HRESULT WINAPI ITaskbarList3_UnregisterTab_Proxy(ITaskbarList3 *This,HWND hwnd);
+  void __RPC_STUB ITaskbarList3_UnregisterTab_Stub(IRpcStubBuffer *This,IRpcChannelBuffer *_pRpcChannelBuffer,PRPC_MESSAGE _pRpcMessage,DWORD *_pdwStubPhase);
+  HRESULT WINAPI ITaskbarList3_SetTabOrder_Proxy(ITaskbarList3 *This,HWND hwnd,HWND hwndInsertBefore);
+  void __RPC_STUB ITaskbarList3_SetTabOrder_Stub(IRpcStubBuffer *This,IRpcChannelBuffer *_pRpcChannelBuffer,PRPC_MESSAGE _pRpcMessage,DWORD *_pdwStubPhase);
+  HRESULT WINAPI ITaskbarList3_SetTabActive_Proxy(ITaskbarList3 *This,HWND hwnd,HWND hwndMDI,DWORD dwReserved);
+  void __RPC_STUB ITaskbarList3_SetTabActive_Stub(IRpcStubBuffer *This,IRpcChannelBuffer *_pRpcChannelBuffer,PRPC_MESSAGE _pRpcMessage,DWORD *_pdwStubPhase);
+#endif
+
+#endif
+#endif

=== modified file 'dwt/include/dwt/util/win32/Version.h'
--- dwt/include/dwt/util/win32/Version.h	2010-02-11 21:44:13 +0000
+++ dwt/include/dwt/util/win32/Version.h	2010-10-28 22:43:23 +0000
@@ -33,7 +33,8 @@
 
 enum Version {
 	XP,
-	VISTA
+	VISTA,
+	SEVEN
 };
 
 bool ensureVersion(Version version);

=== modified file 'dwt/include/dwt/widgets/FolderDialog.h'
--- dwt/include/dwt/widgets/FolderDialog.h	2010-10-28 20:31:03 +0000
+++ dwt/include/dwt/widgets/FolderDialog.h	2010-10-28 22:43:23 +0000
@@ -38,7 +38,6 @@
 
 #include "../Widget.h"
 #include "../tstring.h"
-#include <shlobj>
 
 namespace dwt {
 

=== modified file 'dwt/include/dwt/widgets/TabView.h'
--- dwt/include/dwt/widgets/TabView.h	2010-10-28 20:31:03 +0000
+++ dwt/include/dwt/widgets/TabView.h	2010-10-28 22:43:23 +0000
@@ -38,6 +38,7 @@
 #include "../aspects/AspectSelection.h"
 #include "../aspects/AspectText.h"
 #include "Control.h"
+#include <dwt/Taskbar.h>
 #include <dwt/Theme.h>
 
 #include <list>
@@ -52,7 +53,8 @@
 	// Aspects
 	private AspectCollection<TabView, int>,
 	public AspectSelection< TabView, int >,
-	public AspectText< TabView >
+	public AspectText< TabView >,
+	public Taskbar
 {
 	typedef CommonControl BaseType;
 	friend class AspectCollection<TabView, int>;

=== added file 'dwt/src/Taskbar.cpp'
--- dwt/src/Taskbar.cpp	1970-01-01 00:00:00 +0000
+++ dwt/src/Taskbar.cpp	2010-10-28 22:43:23 +0000
@@ -0,0 +1,232 @@
+/*
+  DC++ Widget Toolkit
+
+  Copyright (c) 2007-2010, Jacek Sieka
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without modification,
+  are permitted provided that the following conditions are met:
+
+      * Redistributions of source code must retain the above copyright notice,
+        this list of conditions and the following disclaimer.
+      * Redistributions in binary form must reproduce the above copyright notice,
+        this list of conditions and the following disclaimer in the documentation
+        and/or other materials provided with the distribution.
+      * Neither the name of the DWT nor SmartWin++ nor the names of its contributors
+        may be used to endorse or promote products derived from this software
+        without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <dwt/Taskbar.h>
+
+#include <dwt/dwt_dwmapi.h>
+#include <dwt/LibraryLoader.h>
+#include <dwt/util/check.h>
+#include <dwt/util/win32/Version.h>
+#include <dwt/widgets/Container.h>
+#include <dwt/widgets/Window.h>
+
+namespace dwt {
+
+static const UINT taskbarButtonMsg = ::RegisterWindowMessage(_T("TaskbarButtonCreated"));
+
+typedef HRESULT (WINAPI *t_DwmInvalidateIconicBitmaps)(HWND);
+static t_DwmInvalidateIconicBitmaps DwmInvalidateIconicBitmaps;
+
+typedef HRESULT (WINAPI *t_DwmSetIconicLivePreviewBitmap)(HWND, HBITMAP, POINT*, DWORD);
+static t_DwmSetIconicLivePreviewBitmap DwmSetIconicLivePreviewBitmap;
+
+typedef HRESULT (WINAPI *t_DwmSetIconicThumbnail)(HWND, HBITMAP, DWORD);
+static t_DwmSetIconicThumbnail DwmSetIconicThumbnail;
+
+typedef HRESULT (WINAPI *t_DwmSetWindowAttribute)(HWND, DWORD, LPCVOID, DWORD);
+static t_DwmSetWindowAttribute DwmSetWindowAttribute;
+
+Taskbar::Taskbar(const ActivateF& activateF_) :
+taskbar(0),
+window(0),
+activateF(activateF_)
+{
+}
+
+Taskbar::~Taskbar() {
+	if(taskbar)
+		taskbar->Release();
+}
+
+void Taskbar::initTaskbar(WindowPtr window_) {
+	if(!util::win32::ensureVersion(util::win32::SEVEN))
+		return;
+
+	/// @todo call ChangeWindowMessageFilterEx on WM_DWMSENDICONICTHUMBNAIL & WM_DWMSENDICONICLIVEPREVIEWBITMAP
+
+	static LibraryLoader lib(_T("dwmapi"), true);
+	if(lib.loaded()) {
+
+#define get(name) if(!name) { if(!(name = reinterpret_cast<t_##name>(lib.getProcAddress(_T(#name))))) { return; } }
+		get(DwmInvalidateIconicBitmaps);
+		get(DwmSetIconicLivePreviewBitmap);
+		get(DwmSetIconicThumbnail);
+		get(DwmSetWindowAttribute);
+#undef get
+
+		window = window_;
+		dwtassert(window, _T("Taskbar: no widget set"));
+
+		// init the COM pointer on reception of the "TaskbarButtonCreated" message.
+		window->onRaw([this](WPARAM, LPARAM) -> LRESULT {
+			if(!taskbar) {
+				if(::CoCreateInstance(CLSID_TaskbarList, 0, CLSCTX_INPROC_SERVER, IID_ITaskbarList,
+					reinterpret_cast<LPVOID*>(&taskbar)) != S_OK) { taskbar = 0; }
+				if(taskbar && taskbar->HrInit() != S_OK) {
+					taskbar->Release();
+					taskbar = 0;
+				}
+			}
+			return 0;
+		}, Message(taskbarButtonMsg));
+	}
+}
+
+void Taskbar::addToTaskbar(ContainerPtr tab) {
+	/* for Windows to acknowledge that our tab window is worthy of having its own thumbnail in the
+	taskbar, we have to create an invisible popup window that will act as a proxy between the
+	taskbar and the actual tab window.
+	this technique is illustrated in MFC as well as the Windows SDK sample at
+	"Samples\winui\shell\appshellintegration\TabThumbnails". */
+
+	ContainerPtr proxy;
+	{
+		Container::Seed seed;
+		seed.caption = tab->getText();
+		seed.style &= ~WS_VISIBLE;
+		seed.style |= WS_POPUP | WS_CAPTION;
+		seed.exStyle |= WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE;
+		seed.location = Rectangle();
+		proxy = window->addChild(seed);
+	}
+	tabs[tab] = proxy;
+
+	// keep the proxy window in sync with the actual tab window.
+	tab->onTextChanging([proxy](const tstring& text) { proxy->setText(text); });
+	tab->onSized([proxy](const SizedEvent&) { DwmInvalidateIconicBitmaps(proxy->handle()); });
+
+	proxy->onActivate([this, tab](bool activate) {
+		if(activate)
+			activateF(tab);
+	});
+	proxy->onClosing([tab]() -> bool {
+		tab->close(true);
+		return false; // don't close the proxy window just yet; wait for removeFromTaskbar.
+	});
+
+	proxy->onRaw([this, tab, proxy](WPARAM, LPARAM lParam) -> LRESULT {
+		// generate a thumbnail to be displayed in the taskbar.
+		BitmapPtr bitmap = getBitmap(tab, lParam);
+		if(bitmap) {
+			DwmSetIconicThumbnail(proxy->handle(), bitmap->handle(), 0);
+		}
+		return 0;
+	}, Message(WM_DWMSENDICONICTHUMBNAIL));
+
+	proxy->onRaw([this, tab, proxy](WPARAM, LPARAM) -> LRESULT {
+		// generate a preview of the tab to be shown in "Aero Peek" when the user hovers the thumbnail.
+		BitmapPtr bitmap = getBitmap(tab, 0);
+		if(bitmap) {
+			Point offset;
+			::MapWindowPoints(tab->handle(), window->handle(), &offset, 1);
+			MENUBARINFO info = { sizeof(MENUBARINFO) };
+			if(::GetMenuBarInfo(window->handle(), OBJID_MENU, 0, &info))
+				offset.y += Rectangle(info.rcBar).height();
+			DwmSetIconicLivePreviewBitmap(proxy->handle(), bitmap->handle(), &offset, 0);
+		}
+		return 0;
+	}, Message(WM_DWMSENDICONICLIVEPREVIEWBITMAP));
+
+	// indicate to the window manager that it should always use the bitmaps we provide.
+	BOOL attrib = TRUE;
+	DwmSetWindowAttribute(proxy->handle(), DWMWA_FORCE_ICONIC_REPRESENTATION, &attrib, sizeof(attrib));
+	DwmSetWindowAttribute(proxy->handle(), DWMWA_HAS_ICONIC_BITMAP, &attrib, sizeof(attrib));
+
+	taskbar->RegisterTab(proxy->handle(), window->handle());
+	moveOnTaskbar(tab);
+}
+
+void Taskbar::removeFromTaskbar(ContainerPtr tab) {
+	ContainerPtr proxy = tabs[tab];
+	taskbar->UnregisterTab(proxy->handle());
+	::DestroyWindow(proxy->handle());
+	tabs.erase(tab);
+}
+
+void Taskbar::moveOnTaskbar(ContainerPtr tab, ContainerPtr rightNeighbor) {
+	taskbar->SetTabOrder(tabs[tab]->handle(), rightNeighbor ? tabs[rightNeighbor]->handle() : 0);
+}
+
+void Taskbar::setActiveOnTaskbar(ContainerPtr tab) {
+	taskbar->SetTabActive(tabs[tab]->handle(), window->handle(), 0);
+}
+
+void Taskbar::setTaskbarIcon(ContainerPtr tab, const IconPtr& icon) {
+	tabs[tab]->sendMessage(WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(icon->handle()));
+}
+
+BitmapPtr Taskbar::getBitmap(ContainerPtr tab, LPARAM thumbnailSize) {
+	UpdateCanvas canvas(tab);
+
+	// get the actual size of the tab.
+	const Point size_full(tab->getClientSize());
+	if(size_full.x <= 0 || size_full.y <= 0)
+		return 0;
+
+	// this DIB will hold a full capture of the tab.
+	BITMAPINFO info = { { sizeof(BITMAPINFOHEADER), size_full.x, size_full.y, 1, 32, BI_RGB } };
+	BitmapPtr bitmap_full(new Bitmap(::CreateDIBSection(canvas.handle(), &info, DIB_RGB_COLORS, 0, 0, 0)));
+
+	FreeCanvas canvas_full(::CreateCompatibleDC(canvas.handle()));
+	Canvas::Selector select_full(canvas_full, *bitmap_full);
+
+	tab->sendMessage(WM_PRINT, reinterpret_cast<WPARAM>(canvas_full.handle()), PRF_CLIENT | PRF_NONCLIENT | PRF_CHILDREN | PRF_ERASEBKGND);
+
+	// get rid of some transparent bits.
+	::BitBlt(canvas_full.handle(), 0, 0, size_full.x, size_full.y, canvas_full.handle(), 0, 0, MERGECOPY);
+
+	if(!thumbnailSize)
+		return bitmap_full;
+
+	// compute the size of the thumbnail, must not exceed the LPARAM values.
+	double factor = std::min(static_cast<double>(HIWORD(thumbnailSize)) / static_cast<double>(size_full.x),
+		static_cast<double>(LOWORD(thumbnailSize)) / static_cast<double>(size_full.y));
+	const Point size_thumb(size_full.x * factor, size_full.y * factor);
+	if(size_thumb.x <= 0 || size_thumb.y <= 0)
+		return 0;
+
+	// this DIB will hold a resized view of the tab, to be used as a thumbnail.
+	info.bmiHeader.biWidth = size_thumb.x;
+	info.bmiHeader.biHeight = size_thumb.y;
+	BitmapPtr bitmap_thumb(new Bitmap(::CreateDIBSection(canvas.handle(), &info, DIB_RGB_COLORS, 0, 0, 0)));
+
+	FreeCanvas canvas_thumb(::CreateCompatibleDC(canvas.handle()));
+	Canvas::Selector select_thumb(canvas_thumb, *bitmap_thumb);
+
+	::SetStretchBltMode(canvas_thumb.handle(), HALFTONE);
+	::SetBrushOrgEx(canvas_thumb.handle(), 0, 0, 0);
+	::StretchBlt(canvas_thumb.handle(), 0, 0, size_thumb.x, size_thumb.y,
+		canvas_full.handle(), 0, 0, size_full.x, size_full.y, SRCCOPY);
+
+	return bitmap_thumb;
+}
+
+}

=== modified file 'dwt/src/util/win32/Version.cpp'
--- dwt/src/util/win32/Version.cpp	2010-02-11 21:44:13 +0000
+++ dwt/src/util/win32/Version.cpp	2010-10-28 22:43:23 +0000
@@ -53,6 +53,7 @@
 	switch(version) {
 	case XP: return (major == 5 && minor >= 1) || major > 5;
 	case VISTA: return major >= 6;
+	case SEVEN: return (major == 6 && minor >= 1) || major > 6;
 	default: return false;
 	}
 }

=== modified file 'dwt/src/widgets/Notification.cpp'
--- dwt/src/widgets/Notification.cpp	2010-09-02 18:16:12 +0000
+++ dwt/src/widgets/Notification.cpp	2010-10-28 22:43:23 +0000
@@ -36,7 +36,7 @@
 
 const UINT Notification::message = ::RegisterWindowMessage(_T("dwt::Notification"));
 
-static const UINT taskbar = ::RegisterWindowMessage(_T("TaskbarCreated"));
+static const UINT taskbarMsg = ::RegisterWindowMessage(_T("TaskbarCreated"));
 
 Notification::~Notification() {
 	setVisible(false);
@@ -48,7 +48,7 @@
 
 	// TODO Allow more than one icon per window
 	parent->setCallback(Message(message), [this](const MSG& msg, LRESULT&) { return trayHandler(msg); });
-	parent->setCallback(Message(taskbar), [this](const MSG&, LRESULT&) { return redisplay(); });
+	parent->setCallback(Message(taskbarMsg), [this](const MSG&, LRESULT&) { return redisplay(); });
 }
 
 void Notification::setIcon(const IconPtr& icon_) {

=== modified file 'dwt/src/widgets/TabView.cpp'
--- dwt/src/widgets/TabView.cpp	2010-09-02 18:16:12 +0000
+++ dwt/src/widgets/TabView.cpp	2010-10-28 22:43:23 +0000
@@ -60,6 +60,7 @@
 
 TabView::TabView(Widget* w) :
 BaseType(w, ChainingDispatcher::superClass<TabView>()),
+Taskbar([this](ContainerPtr tab) { setActive(tab); }),
 tip(0),
 toggleActive(false),
 font(0),
@@ -168,6 +169,13 @@
 		throw Win32Exception("Error while trying to add page into Tab Sheet");
 	}
 
+	if(taskbar) {
+		addToTaskbar(w);
+		if(image != -1) {
+			setTaskbarIcon(w, icon);
+		}
+	}
+
 	viewOrder.push_front(w);
 
 	if(viewOrder.size() == 1 || w->hasStyle(WS_VISIBLE)) {
@@ -220,6 +228,10 @@
 	}
 
 	layout();
+
+	if(taskbar) {
+		removeFromTaskbar(w);
+	}
 }
 
 IconPtr TabView::getIcon(unsigned index) const {
@@ -238,6 +250,10 @@
 			TCITEM item = { TCIF_IMAGE };
 			item.iImage = image;
 			TabCtrl_SetItem(this->handle(), i, &item);
+
+			if(taskbar) {
+				setTaskbarIcon(w, icon);
+			}
 		}
 	}
 }
@@ -312,6 +328,10 @@
 
 	if(titleChangedFunction)
 		titleChangedFunction(ti->w->getText());
+
+	if(taskbar) {
+		setActiveOnTaskbar(ti->w);
+	}
 }
 
 void TabView::mark(ContainerPtr w) {
@@ -377,11 +397,25 @@
 
 	Rectangle tmp = getUsableArea(true);
 	if(!(tmp == clientSize)) {
-		int i = getSelected();
-		if(i != -1) {
-			getTabInfo(i)->w->layout(tmp);
-		}
 		clientSize = tmp;
+
+		// the client area has changed, update the selected tab synchronously.
+		ContainerPtr sel = 0;
+		TabInfo* ti = getTabInfo(getSelected());
+		if(ti) {
+			sel = ti->w;
+			sel->layout(clientSize);
+		}
+
+		// update background tabs too, but only asynchronously.
+		callAsync([this, sel]() {
+			for(auto i = viewOrder.begin(); i != viewOrder.end(); ++i) {
+				ContainerPtr w = *i;
+				if(w != sel) {
+					w->layout(clientSize);
+				}
+			}
+		});
 	}
 }
 
@@ -522,8 +556,7 @@
 		TCHAR buf[1024] = { 0 };
 		item.pszText = buf;
 		item.cchTextMax = (sizeof(buf) / sizeof(TCHAR)) - 1;
-
-		TabCtrl_GetItem( this->handle(), dragPos, & item );
+		TabCtrl_GetItem(handle(), dragPos, &item);
 
 		erase(dragPos);
 
@@ -532,6 +565,10 @@
 		active = getSelected();
 
 		layout();
+
+		if(taskbar) {
+			moveOnTaskbar(getTabInfo(dropPos)->w, (dropPos < size() - 1) ? getTabInfo(dropPos + 1)->w : 0);
+		}
 	}
 
 	return true;

=== modified file 'win32/MainWindow.cpp'
--- win32/MainWindow.cpp	2010-10-07 17:25:06 +0000
+++ win32/MainWindow.cpp	2010-10-28 22:43:23 +0000
@@ -499,6 +499,7 @@
 	seed.toggleActive = BOOLSETTING(TOGGLE_ACTIVE_WINDOW);
 	seed.ctrlTab = true;
 	tabs = addChild(seed);
+	tabs->initTaskbar(this);
 	tabs->onTitleChanged(std::bind(&MainWindow::handleTabsTitleChanged, this, _1));
 	tabs->onHelp(std::bind(&WinUtil::help, _1, _2));
 	paned->setFirst(tabs);

=== modified file 'win32/stdafx.h'
--- win32/stdafx.h	2010-10-05 21:48:07 +0000
+++ win32/stdafx.h	2010-10-28 22:43:23 +0000
@@ -22,7 +22,6 @@
 #include <dcpp/stdinc.h>
 #include <dcpp/DCPlusPlus.h>
 
-#include <shlobj.h>
 #include <libintl.h>
 
 #include <dwt/Application.h>