Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXhmikosR <xhmikosr@users.sourceforge.net>2010-09-16 14:24:14 +0400
committerXhmikosR <xhmikosr@users.sourceforge.net>2010-09-16 14:24:14 +0400
commit1cba01c08b61ee81033bfdfdc3cf6d65dd91d9f7 (patch)
tree545648e6867a7bb88a5fbced2e361613b38d57c7 /src/thirdparty/ui
parent41735446a0e29866794583674dcd2973efead7f1 (diff)
moved thirdparty UI code in the thirdparty/ui dir and CmdUI in the src dir
git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@2569 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src/thirdparty/ui')
-rw-r--r--src/thirdparty/ui/LCDUI/LCDAnimatedBitmap.cpp163
-rw-r--r--src/thirdparty/ui/LCDUI/LCDAnimatedBitmap.h49
-rw-r--r--src/thirdparty/ui/LCDUI/LCDBase.cpp324
-rw-r--r--src/thirdparty/ui/LCDUI/LCDBase.h84
-rw-r--r--src/thirdparty/ui/LCDUI/LCDBitmap.cpp87
-rw-r--r--src/thirdparty/ui/LCDUI/LCDBitmap.h37
-rw-r--r--src/thirdparty/ui/LCDUI/LCDCollection.cpp196
-rw-r--r--src/thirdparty/ui/LCDUI/LCDCollection.h48
-rw-r--r--src/thirdparty/ui/LCDUI/LCDGfx.cpp344
-rw-r--r--src/thirdparty/ui/LCDUI/LCDGfx.h84
-rw-r--r--src/thirdparty/ui/LCDUI/LCDManager.cpp204
-rw-r--r--src/thirdparty/ui/LCDUI/LCDManager.h49
-rw-r--r--src/thirdparty/ui/LCDUI/LCDOutput.cpp896
-rw-r--r--src/thirdparty/ui/LCDUI/LCDOutput.h107
-rw-r--r--src/thirdparty/ui/LCDUI/LCDProgressBar.cpp270
-rw-r--r--src/thirdparty/ui/LCDUI/LCDProgressBar.h66
-rw-r--r--src/thirdparty/ui/LCDUI/LCDScrollingText.cpp294
-rw-r--r--src/thirdparty/ui/LCDUI/LCDScrollingText.h65
-rw-r--r--src/thirdparty/ui/LCDUI/LCDText.cpp398
-rw-r--r--src/thirdparty/ui/LCDUI/LCDText.h71
-rw-r--r--src/thirdparty/ui/LCDUI/LCDUI.vcproj351
-rw-r--r--src/thirdparty/ui/LCDUI/LCDUI.vcxproj151
-rw-r--r--src/thirdparty/ui/LCDUI/LCDUI.vcxproj.filters77
-rw-r--r--src/thirdparty/ui/ResizableLib/Artistic-License.txt99
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableDialog.cpp155
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableDialog.h101
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableGrip.cpp304
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableGrip.h81
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableLayout.cpp516
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableLayout.h196
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableLib.vcproj370
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableLib.vcxproj152
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableLib.vcxproj.filters73
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableMinMax.cpp89
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableMinMax.h53
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableMsgSupport.h61
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableMsgSupport.inl56
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizablePage.cpp72
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizablePage.h78
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableSheet.cpp349
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableSheet.h114
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableState.cpp105
-rw-r--r--src/thirdparty/ui/ResizableLib/ResizableState.h38
-rw-r--r--src/thirdparty/ui/ResizableLib/stdafx.cpp1
-rw-r--r--src/thirdparty/ui/ResizableLib/stdafx.h13
-rw-r--r--src/thirdparty/ui/TreePropSheet/PropPageFrame.cpp187
-rw-r--r--src/thirdparty/ui/TreePropSheet/PropPageFrame.h306
-rw-r--r--src/thirdparty/ui/TreePropSheet/PropPageFrameDefault.cpp393
-rw-r--r--src/thirdparty/ui/TreePropSheet/PropPageFrameDefault.h119
-rw-r--r--src/thirdparty/ui/TreePropSheet/TreePropSheet.cpp982
-rw-r--r--src/thirdparty/ui/TreePropSheet/TreePropSheet.h483
-rw-r--r--src/thirdparty/ui/TreePropSheet/TreePropSheet.vcproj330
-rw-r--r--src/thirdparty/ui/TreePropSheet/TreePropSheet.vcxproj143
-rw-r--r--src/thirdparty/ui/TreePropSheet/TreePropSheet.vcxproj.filters41
-rw-r--r--src/thirdparty/ui/TreePropSheet/stdafx.cpp1
-rw-r--r--src/thirdparty/ui/TreePropSheet/stdafx.h13
-rw-r--r--src/thirdparty/ui/sizecbar/scbarcf.cpp234
-rw-r--r--src/thirdparty/ui/sizecbar/scbarcf.h78
-rw-r--r--src/thirdparty/ui/sizecbar/scbarg.cpp239
-rw-r--r--src/thirdparty/ui/sizecbar/scbarg.h110
-rw-r--r--src/thirdparty/ui/sizecbar/sizecbar.cpp1417
-rw-r--r--src/thirdparty/ui/sizecbar/sizecbar.h249
-rw-r--r--src/thirdparty/ui/sizecbar/sizecbar.vcproj328
-rw-r--r--src/thirdparty/ui/sizecbar/sizecbar.vcxproj140
-rw-r--r--src/thirdparty/ui/sizecbar/sizecbar.vcxproj.filters41
-rw-r--r--src/thirdparty/ui/sizecbar/stdafx.cpp1
-rw-r--r--src/thirdparty/ui/sizecbar/stdafx.h11
67 files changed, 13337 insertions, 0 deletions
diff --git a/src/thirdparty/ui/LCDUI/LCDAnimatedBitmap.cpp b/src/thirdparty/ui/LCDUI/LCDAnimatedBitmap.cpp
new file mode 100644
index 000000000..497fa40dd
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDAnimatedBitmap.cpp
@@ -0,0 +1,163 @@
+//************************************************************************
+//
+// LCDAnimatedBitmap.cpp
+//
+// The CLCDAnimatedBitmap class draws animated bitmaps onto the LCD.
+// An animated bitmap consists of a tiled bitmap representing the
+// animation. The tile size is set with the SetSubpicWidth.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#include "LCDAnimatedBitmap.h"
+
+
+//************************************************************************
+//
+// CLCDAnimatedBitmap::CLCDAnimatedBitmap
+//
+//************************************************************************
+
+CLCDAnimatedBitmap::CLCDAnimatedBitmap()
+{
+ m_dwCurrSubpic = m_dwTotalSubpics = 0;
+}
+
+
+//************************************************************************
+//
+// CLCDAnimatedBitmap::CLCDAnimatedBitmap
+//
+//************************************************************************
+
+CLCDAnimatedBitmap::~CLCDAnimatedBitmap()
+{
+
+}
+
+
+//************************************************************************
+//
+// CLCDAnimatedBitmap::Initialize
+//
+//************************************************************************
+
+HRESULT CLCDAnimatedBitmap::Initialize(void)
+{
+ m_dwRate = 250;
+ m_dwElapsedTime = 0;
+ m_dwLastUpdate = GetTickCount();
+
+ return CLCDBitmap::Initialize();
+}
+
+
+//************************************************************************
+//
+// CLCDAnimatedBitmap::ResetUpdate
+//
+//************************************************************************
+
+void CLCDAnimatedBitmap::ResetUpdate(void)
+{
+ m_dwCurrSubpic = 0;
+ m_dwLastUpdate = GetTickCount();
+}
+
+
+//************************************************************************
+//
+// CLCDAnimatedBitmap::SetSubpicWidth
+//
+//************************************************************************
+
+void CLCDAnimatedBitmap::SetSubpicWidth(DWORD dwWidth)
+{
+ m_dwSubpicWidth = dwWidth;
+ LCDUIASSERT(NULL != m_hBitmap);
+ LCDUIASSERT(0 != dwWidth);
+ if((NULL != m_hBitmap) && (0 != dwWidth))
+ {
+ // figure out how many tiles we have
+ BITMAP bitmap;
+ if(GetObject(m_hBitmap, sizeof(bitmap), &bitmap))
+ {
+ m_dwTotalSubpics = bitmap.bmWidth / dwWidth;
+ SetLogicalSize(bitmap.bmWidth, bitmap.bmHeight);
+ }
+ else
+ {
+ m_dwTotalSubpics = 0;
+ }
+ }
+ else
+ {
+ m_dwTotalSubpics = 0;
+ }
+}
+
+//************************************************************************
+//
+// CLCDAnimatedBitmap::SetAnimationRate
+//
+//************************************************************************
+
+void CLCDAnimatedBitmap::SetAnimationRate(DWORD dwRate)
+{
+ m_dwRate = dwRate;
+}
+
+
+//************************************************************************
+//
+// CLCDAnimatedBitmap::OnUpdate
+//
+//************************************************************************
+
+void CLCDAnimatedBitmap::OnUpdate(DWORD dwTimestamp)
+{
+ m_dwElapsedTime = (dwTimestamp - m_dwLastUpdate);
+}
+
+
+//************************************************************************
+//
+// CLCDAnimatedBitmap::OnDraw
+//
+//************************************************************************
+
+void CLCDAnimatedBitmap::OnDraw(CLCDGfx &rGfx)
+{
+ if(m_dwTotalSubpics > 0)
+ {
+ int xoffs = m_dwCurrSubpic * m_dwSubpicWidth;
+
+ DWORD increment = m_dwElapsedTime / m_dwRate;
+ if(increment > 0)
+ {
+ m_dwCurrSubpic += increment;
+ m_dwCurrSubpic %= m_dwTotalSubpics;
+ m_dwElapsedTime %= m_dwRate;
+ m_dwLastUpdate = GetTickCount();
+ }
+
+ // stolen from: CLCDBitmap::OnDraw(rGfx);
+ if(m_hBitmap)
+ {
+ HDC hCompatibleDC = CreateCompatibleDC(rGfx.GetHDC());
+ HBITMAP hOldBitmap = (HBITMAP)SelectObject(hCompatibleDC, m_hBitmap);
+
+ // get
+ BitBlt(rGfx.GetHDC(), 0, 0, m_Size.cx, m_Size.cy, hCompatibleDC, xoffs, 0, m_dwROP);
+
+ // restores
+ SelectObject(hCompatibleDC, hOldBitmap);
+ DeleteDC(hCompatibleDC);
+ }
+ }
+}
+
+
+//** end of LCDAnimatedBitmap.cpp ****************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDAnimatedBitmap.h b/src/thirdparty/ui/LCDUI/LCDAnimatedBitmap.h
new file mode 100644
index 000000000..492959cd1
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDAnimatedBitmap.h
@@ -0,0 +1,49 @@
+//************************************************************************
+//
+// LCDAnimatedBitmap.h
+//
+// The CLCDAnimatedBitmap class draws animated bitmaps onto the LCD.
+// An animated bitmap consists of a tiled bitmap representing the
+// animation. The tile size is set with the SetSubpicWidth.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#ifndef _LCDANIMATEDBITMAP_H_INCLUDED_
+#define _LCDANIMATEDBITMAP_H_INCLUDED_
+
+#include "LCDBase.h"
+#include "LCDBitmap.h"
+
+class CLCDAnimatedBitmap : public CLCDBitmap
+{
+public:
+ CLCDAnimatedBitmap();
+ virtual ~CLCDAnimatedBitmap();
+
+ virtual HRESULT Initialize(void);
+ virtual void ResetUpdate(void);
+
+ void SetSubpicWidth(DWORD dwWidth);
+ void SetAnimationRate(DWORD dwRate); // milliseconds/subpicture
+
+protected:
+ virtual void OnUpdate(DWORD dwTimestamp);
+ virtual void OnDraw(CLCDGfx &rGfx);
+
+private:
+ DWORD m_dwElapsedTime; // elapsed time in state
+ DWORD m_dwRate; // milliseconds per subpicture
+ DWORD m_dwLastUpdate; // milliseconds
+
+ DWORD m_dwSubpicWidth;
+ DWORD m_dwCurrSubpic;
+ DWORD m_dwTotalSubpics;
+};
+
+
+#endif // !_LCDANIMATEDBITMAP_H_INCLUDED_
+
+//** end of LCDBitmap.h **************************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDBase.cpp b/src/thirdparty/ui/LCDUI/LCDBase.cpp
new file mode 100644
index 000000000..4b4c585d9
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDBase.cpp
@@ -0,0 +1,324 @@
+//************************************************************************
+//
+// LCDBase.cpp
+//
+// The CLCDBase class is the generic base class for all lcd ui objects
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#include "LCDBase.h"
+
+
+//************************************************************************
+//
+// CLCDBase::CLCDBase
+//
+//************************************************************************
+
+CLCDBase::CLCDBase(void)
+{
+ m_Size.cx = 0;
+ m_Size.cy = 0;
+ m_Origin.x = 0;
+ m_Origin.y = 0;
+ m_bVisible = TRUE;
+ m_bInverted = FALSE;
+ ZeroMemory(&m_ptLogical, sizeof(m_ptLogical));
+ ZeroMemory(&m_sizeLogical, sizeof(m_sizeLogical));
+ m_nBkMode = TRANSPARENT;
+ m_objectType = LG_UNKNOWN;
+}
+
+
+//************************************************************************
+//
+// CLCDBase::~CLCDBase
+//
+//************************************************************************
+
+CLCDBase::~CLCDBase(void)
+{
+}
+
+
+//************************************************************************
+//
+// CLCDBase::Initialize
+//
+//************************************************************************
+
+HRESULT CLCDBase::Initialize(void)
+{
+ return S_OK;
+}
+
+
+//************************************************************************
+//
+// CLCDBase::Shutdown
+//
+//************************************************************************
+
+void CLCDBase::Shutdown(void)
+{
+}
+
+
+//************************************************************************
+//
+// CLCDBase::SetOrigin
+//
+//************************************************************************
+
+void CLCDBase::SetOrigin(POINT pt)
+{
+ m_Origin = pt;
+}
+
+
+//************************************************************************
+//
+// CLCDBase::SetOrigin
+//
+//************************************************************************
+
+void CLCDBase::SetOrigin(int nX, int nY)
+{
+ POINT pt = { nX, nY };
+ SetOrigin(pt);
+}
+
+
+//************************************************************************
+//
+// CLCDBase::GetOrigin
+//
+//************************************************************************
+
+POINT& CLCDBase::GetOrigin(void)
+{
+ return m_Origin;
+}
+
+
+//************************************************************************
+//
+// CLCDBase::SetSize
+//
+//************************************************************************
+
+void CLCDBase::SetSize(SIZE& size)
+{
+ m_Size = size;
+ SetLogicalSize(m_Size);
+}
+
+
+//************************************************************************
+//
+// CLCDBase::SetSize
+//
+//************************************************************************
+
+void CLCDBase::SetSize(int nCX, int nCY)
+{
+ SIZE size = { nCX, nCY };
+ SetSize(size);
+}
+
+
+//************************************************************************
+//
+// CLCDBase::GetSize
+//
+//************************************************************************
+
+SIZE& CLCDBase::GetSize(void)
+{
+ return m_Size;
+}
+
+
+//************************************************************************
+//
+// CLCDBase::SetLogicalOrigin
+//
+//************************************************************************
+
+void CLCDBase::SetLogicalOrigin(POINT& pt)
+{
+ m_ptLogical = pt;
+}
+
+
+//************************************************************************
+//
+// CLCDBase::SetLogicalOrigin
+//
+//************************************************************************
+
+void CLCDBase::SetLogicalOrigin(int nX, int nY)
+{
+ m_ptLogical.x = nX;
+ m_ptLogical.y = nY;
+}
+
+
+//************************************************************************
+//
+// CLCDBase::GetLogicalOrigin
+//
+//************************************************************************
+
+POINT& CLCDBase::GetLogicalOrigin(void)
+{
+ return m_ptLogical;
+}
+
+
+//************************************************************************
+//
+// CLCDBase::SetLogicalSize
+//
+//************************************************************************
+
+void CLCDBase::SetLogicalSize(SIZE& size)
+{
+ m_sizeLogical = size;
+}
+
+
+//************************************************************************
+//
+// CLCDBase::SetLogicalSize
+//
+//************************************************************************
+
+void CLCDBase::SetLogicalSize(int nCX, int nCY)
+{
+ m_sizeLogical.cx = nCX;
+ m_sizeLogical.cy = nCY;
+}
+
+
+//************************************************************************
+//
+// CLCDBase::GetLogicalSize
+//
+//************************************************************************
+
+SIZE& CLCDBase::GetLogicalSize(void)
+{
+ return m_sizeLogical;
+}
+
+
+//************************************************************************
+//
+// CLCDBase::Show
+//
+//************************************************************************
+
+void CLCDBase::Show(BOOL bShow)
+{
+ m_bVisible = bShow;
+}
+
+
+//************************************************************************
+//
+// BOOL CLCDBase::
+//
+//************************************************************************
+
+BOOL CLCDBase::IsVisible(void)
+{
+ return m_bVisible;
+}
+
+
+//************************************************************************
+//
+// CLCDBase::Invert
+//
+//************************************************************************
+
+void CLCDBase::Invert(BOOL bEnable)
+{
+ m_bInverted = bEnable;
+}
+
+
+//************************************************************************
+//
+// CLCDBase::ResetUpdate
+//
+//************************************************************************
+
+void CLCDBase::ResetUpdate(void)
+{
+ // do nothing
+}
+
+
+//************************************************************************
+//
+// CLCDBase::OnUpdate
+//
+//************************************************************************
+
+void CLCDBase::OnUpdate(DWORD dwTimestamp)
+{
+ UNREFERENCED_PARAMETER(dwTimestamp);
+}
+
+
+//************************************************************************
+//
+// CLCDBase::SetBackgroundMode
+//
+//************************************************************************
+
+void CLCDBase::SetBackgroundMode(int nMode)
+{
+ m_nBkMode = nMode;
+}
+
+
+//************************************************************************
+//
+// CLCDBase::GetBackgroundMode
+//
+//************************************************************************
+
+int CLCDBase::GetBackgroundMode()
+{
+ return m_nBkMode;
+}
+
+//************************************************************************
+//
+// CLCDBase::GetObjectType
+//
+//************************************************************************
+
+const LGObjectType CLCDBase::GetObjectType()
+{
+ return m_objectType;
+}
+
+//************************************************************************
+//
+// CLCDBase::SetObjectType
+//
+//************************************************************************
+
+void CLCDBase::SetObjectType(const LGObjectType type)
+{
+ m_objectType = type;
+}
+
+//** end of LCDBase.cpp **************************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDBase.h b/src/thirdparty/ui/LCDUI/LCDBase.h
new file mode 100644
index 000000000..dbf677cc7
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDBase.h
@@ -0,0 +1,84 @@
+//************************************************************************
+//
+// LCDBase.h
+//
+// The CLCDBase class is the generic base class for all lcd ui objects
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#ifndef _LCDBASE_H_INCLUDED_
+#define _LCDBASE_H_INCLUDED_
+
+#include "LCDGfx.h"
+
+
+typedef enum
+{
+ LG_SCROLLING_TEXT, LG_STATIC_TEXT, LG_ICON, LG_PROGRESS_BAR, LG_UNKNOWN
+} LGObjectType;
+
+class CLCDBase
+{
+public:
+ CLCDBase(void);
+ virtual ~CLCDBase(void);
+
+public:
+ virtual HRESULT Initialize(void);
+ virtual void Shutdown(void);
+
+ virtual void SetOrigin(POINT pt);
+ virtual void SetOrigin(int nX, int nY);
+ virtual POINT& GetOrigin(void);
+
+ virtual void SetSize(SIZE& size);
+ virtual void SetSize(int nCX, int nCY);
+ virtual SIZE& GetSize(void);
+
+ virtual int GetWidth(void) { return GetSize().cx; }
+ virtual int GetHeight(void) { return GetSize().cy; };
+
+ virtual void Show(BOOL bShow);
+ virtual BOOL IsVisible();
+
+ virtual void Invert(BOOL bEnable);
+ virtual void ResetUpdate(void);
+
+ // local coordinates
+ virtual void SetLogicalOrigin(POINT& rLogical);
+ virtual void SetLogicalOrigin(int nX, int nY);
+ virtual POINT& GetLogicalOrigin(void);
+ virtual void SetLogicalSize(SIZE& size);
+ virtual void SetLogicalSize(int nCX, int nCY);
+ virtual SIZE& GetLogicalSize(void);
+
+ virtual void SetBackgroundMode(int nMode);
+ virtual int GetBackgroundMode();
+
+ virtual const LGObjectType GetObjectType();
+ virtual void SetObjectType(const LGObjectType type);
+
+public:
+ virtual void OnDraw(CLCDGfx &rGfx) = 0;
+ virtual void OnUpdate(DWORD dwTimestamp);
+
+protected:
+ SIZE m_Size;
+ POINT m_Origin;
+ BOOL m_bVisible;
+ BOOL m_bInverted;
+
+ POINT m_ptLogical;
+ SIZE m_sizeLogical;
+ int m_nBkMode;
+
+ LGObjectType m_objectType;
+};
+
+
+#endif // !_LCDBASE_H_INCLUDED_
+
+//** end of LCDBase.h ****************************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDBitmap.cpp b/src/thirdparty/ui/LCDUI/LCDBitmap.cpp
new file mode 100644
index 000000000..559a88a5b
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDBitmap.cpp
@@ -0,0 +1,87 @@
+//************************************************************************
+//
+// LCDBitmap.cpp
+//
+// The CLCDBitmap class draws bitmaps onto the LCD.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#include "LCDBitmap.h"
+
+
+//************************************************************************
+//
+// CLCDBitmap::CLCDBitmap
+//
+//************************************************************************
+
+CLCDBitmap::CLCDBitmap()
+{
+ m_hBitmap = NULL;
+ m_dwROP = SRCCOPY;
+}
+
+
+//************************************************************************
+//
+// CLCDBitmap::CLCDBitmap
+//
+//************************************************************************
+
+CLCDBitmap::~CLCDBitmap()
+{
+
+}
+
+
+//************************************************************************
+//
+// CLCDBitmap::SetBitmap
+//
+//************************************************************************
+
+void CLCDBitmap::SetBitmap(HBITMAP hBitmap)
+{
+ LCDUIASSERT(NULL != hBitmap);
+ m_hBitmap = hBitmap;
+}
+
+
+//************************************************************************
+//
+// CLCDBitmap::SetBitmap
+//
+//************************************************************************
+
+void CLCDBitmap::SetROP(DWORD dwROP)
+{
+ m_dwROP = dwROP;
+}
+
+
+//************************************************************************
+//
+// CLCDBitmap::OnDraw
+//
+//************************************************************************
+
+void CLCDBitmap::OnDraw(CLCDGfx &rGfx)
+{
+ if(m_hBitmap)
+ {
+ HDC hCompatibleDC = CreateCompatibleDC(rGfx.GetHDC());
+ HBITMAP hOldBitmap = (HBITMAP)SelectObject(hCompatibleDC, m_hBitmap);
+
+ BitBlt(rGfx.GetHDC(), 0, 0, m_Size.cx, m_Size.cy, hCompatibleDC, m_ptLogical.x, m_ptLogical.y, m_dwROP);
+
+ // restores
+ SelectObject(hCompatibleDC, hOldBitmap);
+ DeleteDC(hCompatibleDC);
+ }
+}
+
+
+//** end of LCDBitmap.cpp ************************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDBitmap.h b/src/thirdparty/ui/LCDUI/LCDBitmap.h
new file mode 100644
index 000000000..1ac1a6103
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDBitmap.h
@@ -0,0 +1,37 @@
+//************************************************************************
+//
+// LCDBitmap.h
+//
+// The CLCDBitmap class draws bitmaps onto the LCD.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#ifndef _LCDBITMAP_H_INCLUDED_
+#define _LCDBITMAP_H_INCLUDED_
+
+#include "LCDBase.h"
+
+class CLCDBitmap : public CLCDBase
+{
+public:
+ CLCDBitmap();
+ virtual ~CLCDBitmap();
+
+ void SetBitmap(HBITMAP hBitmap);
+ void SetROP(DWORD dwROP);
+
+protected:
+ virtual void OnDraw(CLCDGfx &rGfx);
+ HBITMAP m_hBitmap;
+ DWORD m_dwROP;
+
+private:
+};
+
+
+#endif // !_LCDBITMAP_H_INCLUDED_
+
+//** end of LCDBitmap.h **************************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDCollection.cpp b/src/thirdparty/ui/LCDUI/LCDCollection.cpp
new file mode 100644
index 000000000..edba28599
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDCollection.cpp
@@ -0,0 +1,196 @@
+//************************************************************************
+//
+// LCDCollection.cpp
+//
+// The CLCDCollection class is a generic collection of CLCDBase objects.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#include "LCDCollection.h"
+
+
+//************************************************************************
+//
+// CLCDCollection::CLCDCollection
+//
+//************************************************************************
+
+CLCDCollection::CLCDCollection(void)
+{
+}
+
+
+//************************************************************************
+//
+// CLCDCollection::~CLCDCollection
+//
+//************************************************************************
+
+CLCDCollection::~CLCDCollection(void)
+{
+}
+
+
+//************************************************************************
+//
+// CLCDCollection::AddObject
+//
+//************************************************************************
+
+BOOL CLCDCollection::AddObject(CLCDBase* pObject)
+{
+ //TODO: handle addition of same object twice...
+ m_Objects.push_back(pObject);
+ return TRUE;
+}
+
+
+//************************************************************************
+//
+// CLCDCollection::RemoveObject
+//
+//************************************************************************
+
+BOOL CLCDCollection::RemoveObject(CLCDBase* pObject)
+{
+ LCD_OBJECT_LIST::iterator it = m_Objects.begin();
+ while(it != m_Objects.end())
+ {
+ if (*it == pObject)
+ {
+ m_Objects.erase(it);
+ break;
+ }
+ ++it;
+ }
+ return FALSE;
+}
+
+
+//************************************************************************
+//
+// CLCDCollection::OnDraw
+//
+//************************************************************************
+
+void CLCDCollection::OnDraw(CLCDGfx &rGfx)
+{
+ LCD_OBJECT_LIST::iterator it = m_Objects.begin();
+ while(it != m_Objects.end())
+ {
+ CLCDBase *pObject = *it;
+ LCDUIASSERT(NULL != pObject);
+
+ if (!pObject->IsVisible())
+ {
+ ++it;
+ continue;
+ }
+
+ // create the clip region
+ HRGN hRgn = CreateRectRgn(pObject->GetOrigin().x, pObject->GetOrigin().y,
+ pObject->GetOrigin().x + pObject->GetWidth(),
+ pObject->GetOrigin().y + pObject->GetHeight());
+
+ // ensure that controls only draw within their specified region
+ SelectClipRgn(rGfx.GetHDC(), hRgn);
+
+ // free the region (a copy is used in the call above)
+ DeleteObject(hRgn);
+
+ // offset the control at its origin so controls use (0,0)
+ POINT ptPrevViewportOrg = { 0, 0 };
+ SetViewportOrgEx(rGfx.GetHDC(),
+ pObject->GetOrigin().x,
+ pObject->GetOrigin().y,
+ &ptPrevViewportOrg);
+
+ // allow controls to supply additional translation
+ // this allows controls to move freely within the confined viewport
+ OffsetViewportOrgEx(rGfx.GetHDC(),
+ pObject->GetLogicalOrigin().x,
+ pObject->GetLogicalOrigin().y,
+ NULL);
+
+ pObject->OnDraw(rGfx);
+
+ // set the clipping region to nothing
+ SelectClipRgn(rGfx.GetHDC(), NULL);
+
+ // restore the viewport origin
+ SetViewportOrgEx(rGfx.GetHDC(),
+ ptPrevViewportOrg.x,
+ ptPrevViewportOrg.y,
+ NULL);
+
+ // restore the viewport origin offset
+ OffsetViewportOrgEx(rGfx.GetHDC(), 0, 0, NULL);
+
+ ++it;
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDCollection::OnUpdate
+//
+//************************************************************************
+
+void CLCDCollection::OnUpdate(DWORD dwTimestamp)
+{
+ LCD_OBJECT_LIST::iterator it = m_Objects.begin();
+ while(it != m_Objects.end())
+ {
+ CLCDBase *pObject = *it;
+ LCDUIASSERT(NULL != pObject);
+ pObject->OnUpdate(dwTimestamp);
+ ++it;
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDCollection::ResetUpdate
+//
+//************************************************************************
+
+void CLCDCollection::ResetUpdate(void)
+{
+ LCD_OBJECT_LIST::iterator it = m_Objects.begin();
+ while(it != m_Objects.end())
+ {
+ CLCDBase *pObject = *it;
+ LCDUIASSERT(NULL != pObject);
+ pObject->ResetUpdate();
+ ++it;
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDCollection::Show
+//
+//************************************************************************
+
+void CLCDCollection::Show(BOOL bShow)
+{
+ LCD_OBJECT_LIST::iterator it = m_Objects.begin();
+ while(it != m_Objects.end())
+ {
+ CLCDBase *pObject = *it;
+ LCDUIASSERT(NULL != pObject);
+ pObject->Show(bShow);
+ ++it;
+ }
+
+ CLCDBase::Show(bShow);
+}
+
+
+//** end of LCDCollection.cpp ********************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDCollection.h b/src/thirdparty/ui/LCDUI/LCDCollection.h
new file mode 100644
index 000000000..0f4547222
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDCollection.h
@@ -0,0 +1,48 @@
+//************************************************************************
+//
+// LCDCollection.h
+//
+// The CLCDCollection class is a generic collection of CLCDBase objects.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#ifndef _LCDCOLLECTION_H_INCLUDED_
+#define _LCDCOLLECTION_H_INCLUDED_
+
+#include "LCDBase.h"
+
+
+#include <list>
+using namespace std;
+typedef list <CLCDBase*> LCD_OBJECT_LIST;
+typedef LCD_OBJECT_LIST::iterator LCD_OBJECT_LIST_ITER;
+
+
+class CLCDCollection : public CLCDBase
+{
+public:
+ CLCDCollection();
+ virtual ~CLCDCollection();
+
+ // collection objects use relative origin
+ BOOL AddObject(CLCDBase* pObject);
+ BOOL RemoveObject(CLCDBase* pObject);
+
+ virtual void ResetUpdate(void);
+ virtual void Show(BOOL bShow);
+
+public:
+ virtual void OnDraw(CLCDGfx &rGfx);
+ virtual void OnUpdate(DWORD dwTimestamp);
+
+protected:
+ LCD_OBJECT_LIST m_Objects;
+};
+
+
+#endif // !_LCDCOLLECTION_H_INCLUDED_
+
+//** end of LCDCollection.h **********************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDGfx.cpp b/src/thirdparty/ui/LCDUI/LCDGfx.cpp
new file mode 100644
index 000000000..15732074b
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDGfx.cpp
@@ -0,0 +1,344 @@
+//************************************************************************
+//
+// LCDGfx.cpp
+//
+// The CLCDGfx class abstracts GDI/bitmap details. It is used in the
+// OnDraw event.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#include "../../../DSUtil/SharedInclude.h"
+#include <Afx.h>
+#include "LCDGfx.h"
+
+
+//************************************************************************
+//
+// CLCDGfx::CLCDGfx
+//
+//************************************************************************
+
+CLCDGfx::CLCDGfx(void)
+: m_nWidth(0),
+ m_nHeight(0),
+ m_pLCDScreen(NULL),
+ m_pBitmapInfo(NULL),
+ m_hDC(NULL),
+ m_hBitmap(NULL),
+ m_hPrevBitmap(NULL),
+ m_pBitmapBits(NULL)
+{
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::~CLCDGfx
+//
+//************************************************************************
+
+CLCDGfx::~CLCDGfx(void)
+{
+ Shutdown();
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::Initialize
+//
+//************************************************************************
+
+HRESULT CLCDGfx::Initialize(int nWidth, int nHeight)
+{
+ m_nWidth = nWidth;
+ m_nHeight = nHeight;
+
+ m_hDC = CreateCompatibleDC(NULL);
+ if(NULL == m_hDC)
+ {
+ LCDUITRACE(_T("CLCDGfx::Initialize(): failed to create compatible DC.\n"));
+ Shutdown();
+ return E_FAIL;
+ }
+
+ int nBMISize = sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD);
+ m_pBitmapInfo = (BITMAPINFO *) DNew BYTE [nBMISize];
+ if(NULL == m_pBitmapInfo)
+ {
+ LCDUITRACE(_T("CLCDGfx::Initialize(): failed to allocate bitmap info.\n"));
+ Shutdown();
+ return E_OUTOFMEMORY;
+ }
+
+ ZeroMemory(m_pBitmapInfo, nBMISize);
+ m_pBitmapInfo->bmiHeader.biSize = sizeof(m_pBitmapInfo->bmiHeader);
+ m_pBitmapInfo->bmiHeader.biWidth = m_nWidth;
+ m_pBitmapInfo->bmiHeader.biHeight = -m_nHeight;
+ m_pBitmapInfo->bmiHeader.biPlanes = 1;
+ m_pBitmapInfo->bmiHeader.biBitCount = 8;
+ m_pBitmapInfo->bmiHeader.biCompression = BI_RGB;
+ m_pBitmapInfo->bmiHeader.biSizeImage =
+ (m_nWidth *
+ m_nHeight *
+ m_pBitmapInfo->bmiHeader.biBitCount) / 8;
+ m_pBitmapInfo->bmiHeader.biXPelsPerMeter = 3200;
+ m_pBitmapInfo->bmiHeader.biYPelsPerMeter = 3200;
+ m_pBitmapInfo->bmiHeader.biClrUsed = 256;
+ m_pBitmapInfo->bmiHeader.biClrImportant = 256;
+
+ for(int nColor = 0; nColor < 256; ++nColor)
+ {
+ m_pBitmapInfo->bmiColors[nColor].rgbRed = (BYTE)((nColor > 128) ? 255 : 0);
+ m_pBitmapInfo->bmiColors[nColor].rgbGreen = (BYTE)((nColor > 128) ? 255 : 0);
+ m_pBitmapInfo->bmiColors[nColor].rgbBlue = (BYTE)((nColor > 128) ? 255 : 0);
+ m_pBitmapInfo->bmiColors[nColor].rgbReserved = 0;
+ }
+
+ m_hBitmap = CreateDIBSection(m_hDC, m_pBitmapInfo, DIB_RGB_COLORS, (PVOID *) &m_pBitmapBits, NULL, 0);
+ if(NULL == m_hBitmap)
+ {
+ LCDUITRACE(_T("CLCDGfx::Initialize(): failed to create bitmap.\n"));
+ Shutdown();
+ return E_FAIL;
+ }
+
+ m_pLCDScreen = DNew lgLcdBitmap160x43x1;
+ if(NULL == m_pLCDScreen)
+ {
+ LCDUITRACE(_T("CLCDGfx::Initialize(): failed to allocate the lcd screen structure.\n"));
+ Shutdown();
+ return E_OUTOFMEMORY;
+ }
+
+ return S_OK;
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::Shutdown
+//
+//************************************************************************
+
+void CLCDGfx::Shutdown(void)
+{
+ if(NULL != m_pLCDScreen)
+ {
+ delete m_pLCDScreen;
+ m_pLCDScreen = NULL;
+ }
+
+ if(NULL != m_hBitmap)
+ {
+ DeleteObject(m_hBitmap);
+ m_hBitmap = NULL;
+ m_pBitmapBits = NULL;
+ }
+
+ LCDUIASSERT(NULL == m_hPrevBitmap);
+ m_hPrevBitmap = NULL;
+
+ if(NULL != m_pBitmapInfo)
+ {
+ delete [] m_pBitmapInfo;
+ m_pBitmapInfo = NULL;
+ }
+
+ if(NULL != m_hDC)
+ {
+ DeleteDC(m_hDC);
+ m_hDC = NULL;
+ }
+
+ m_nWidth = 0;
+ m_nHeight = 0;
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::BeginDraw
+//
+//************************************************************************
+
+void CLCDGfx::BeginDraw(void)
+{
+ LCDUIASSERT(NULL != m_hBitmap);
+ LCDUIASSERT(NULL == m_hPrevBitmap);
+ if(NULL == m_hPrevBitmap)
+ {
+ m_hPrevBitmap = (HBITMAP) SelectObject(m_hDC, m_hBitmap);
+ SetTextColor(m_hDC, RGB(255, 255, 255));
+ SetBkColor(m_hDC, RGB(0, 0, 0));
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::ClearScreen
+//
+//************************************************************************
+
+void CLCDGfx::ClearScreen(void)
+{
+ // this means, we're inside BeginDraw()/EndDraw()
+ LCDUIASSERT(NULL != m_hPrevBitmap);
+ RECT rc = { 0, 0, m_nWidth, m_nHeight };
+ FillRect(m_hDC, &rc, (HBRUSH) GetStockObject(BLACK_BRUSH));
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::SetPixel
+//
+//************************************************************************
+
+void CLCDGfx::SetPixel(int nX, int nY, BYTE bValue)
+{
+ // this means, we're inside BeginDraw()/EndDraw()
+ LCDUIASSERT(NULL != m_hPrevBitmap);
+ ::SetPixel(m_hDC, nX, nY, bValue ? RGB(255, 255, 255) : RGB(0, 0, 0));
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::DrawLine
+//
+//************************************************************************
+
+void CLCDGfx::DrawLine(int nX1, int nY1, int nX2, int nY2)
+{
+ // this means, we're inside BeginDraw()/EndDraw()
+ LCDUIASSERT(NULL != m_hPrevBitmap);
+
+ HPEN hPrevPen = (HPEN) SelectObject(m_hDC, GetStockObject(WHITE_PEN));
+ ::MoveToEx(m_hDC, nX1, nY1, NULL);
+ ::LineTo(m_hDC, nX2, nY2);
+ SelectObject(m_hDC, hPrevPen);
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::DrawFilledRect
+//
+//************************************************************************
+
+void CLCDGfx::DrawFilledRect(int nX, int nY, int nWidth, int nHeight)
+{
+ // this means, we're inside BeginDraw()/EndDraw()
+ LCDUIASSERT(NULL != m_hPrevBitmap);
+
+ HBRUSH hPrevBrush = (HBRUSH) SelectObject(m_hDC, GetStockObject(WHITE_BRUSH));
+ RECT r = { nX, nY, nX + nWidth, nY + nHeight };
+ ::FillRect(m_hDC, &r, hPrevBrush);
+ SelectObject(m_hDC, hPrevBrush);
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::DrawText
+//
+//************************************************************************
+
+void CLCDGfx::DrawText(int nX, int nY, LPCTSTR sText)
+{
+ // map mode text, with transparency
+ int nOldMapMode = SetMapMode(m_hDC, MM_TEXT);
+ int nOldBkMode = SetBkMode(m_hDC, TRANSPARENT);
+
+ ::TextOut(m_hDC, nX, nY, sText, (int)_tcslen(sText));
+
+ // restores
+ SetMapMode(m_hDC, nOldMapMode);
+ SetBkMode(m_hDC, nOldBkMode);
+
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::EndDraw
+//
+//************************************************************************
+
+void CLCDGfx::EndDraw(void)
+{
+ LCDUIASSERT(NULL != m_hPrevBitmap);
+ if(NULL != m_hPrevBitmap)
+ {
+ GdiFlush();
+ m_hPrevBitmap = (HBITMAP) SelectObject(m_hDC, m_hPrevBitmap);
+ LCDUIASSERT(m_hPrevBitmap == m_hBitmap);
+ m_hPrevBitmap = NULL;
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::GetHDC
+//
+//************************************************************************
+
+HDC CLCDGfx::GetHDC(void)
+{
+ LCDUIASSERT(NULL != m_hDC);
+ return m_hDC;
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::GetLCDScreen
+//
+//************************************************************************
+
+lgLcdBitmap160x43x1 *CLCDGfx::GetLCDScreen(void)
+{
+ LCDUIASSERT(NULL != m_pLCDScreen);
+ if(NULL != m_pLCDScreen)
+ {
+ m_pLCDScreen->hdr.Format = LGLCD_BMP_FORMAT_160x43x1;
+ memcpy(m_pLCDScreen->pixels, m_pBitmapBits, m_nWidth * m_nHeight);
+ }
+
+ return m_pLCDScreen;
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::GetBitmapInfo
+//
+//************************************************************************
+
+BITMAPINFO *CLCDGfx::GetBitmapInfo(void)
+{
+ LCDUIASSERT(NULL != m_pBitmapInfo);
+ return m_pBitmapInfo;
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::GetHBITMAP
+//
+//************************************************************************
+
+HBITMAP CLCDGfx::GetHBITMAP(void)
+{
+ LCDUIASSERT(NULL != m_hBitmap);
+ return m_hBitmap;
+}
+
+
+//** end of LCDGfx.cpp ***************************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDGfx.h b/src/thirdparty/ui/LCDUI/LCDGfx.h
new file mode 100644
index 000000000..880e825d6
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDGfx.h
@@ -0,0 +1,84 @@
+//************************************************************************
+//
+// LCDGfx.h
+//
+// The CLCDGfx class abstracts GDI/bitmap details. It is used in the
+// OnDraw event.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#ifndef _LCDGFX_H_INCLUDED_
+#define _LCDGFX_H_INCLUDED_
+
+#include <windows.h>
+#include <tchar.h>
+#include <lglcd/lglcd.h>
+
+#if _MSC_VER >= 1400
+#define LCDUI_tcsncpy(x, y, z) _tcsncpy_s(x, _countof(x), y, z)
+#define LCDUI_tcscpy(x, y) _tcscpy_s(x, _countof(x), y)
+#else
+#define LCDUI_tcsncpy(x, y, z) _tcsncpy(x, y, z)
+#define LCDUI_tcscpy(x, y) _tcscpy(x, y)
+#endif
+
+#ifndef LCDUITRACE
+ // .NET compiler uses __noop intrinsic
+ #if _MSC_VER > 1300
+ #define LCDUITRACE __noop
+ #else
+ #define LCDUITRACE (void)0
+ #endif
+#endif
+
+#ifndef LCDUIASSERT
+ // .NET compiler uses __noop intrinsic
+ #if _MSC_VER > 1300
+ #define LCDUIASSERT __noop
+ #else
+ #define LCDUIASSERT (void)0
+ #endif
+#endif
+
+
+
+class CLCDGfx
+{
+public:
+ CLCDGfx(void);
+ virtual ~CLCDGfx(void);
+
+ HRESULT Initialize(int nWidth, int nHeight);
+ void Shutdown(void);
+
+ void BeginDraw(void);
+ void ClearScreen(void);
+ void SetPixel(int nX, int nY, BYTE bValue);
+ void DrawLine(int nX1, int nY1, int nX2, int nY2);
+ void DrawFilledRect(int nX, int nY, int nWidth, int nHeight);
+ void DrawText(int nX, int nY, LPCTSTR sText);
+ void EndDraw(void);
+
+ HDC GetHDC(void);
+ lgLcdBitmap160x43x1 *GetLCDScreen(void);
+ BITMAPINFO *GetBitmapInfo(void);
+ HBITMAP GetHBITMAP(void);
+
+protected:
+ int m_nWidth;
+ int m_nHeight;
+ lgLcdBitmap160x43x1 *m_pLCDScreen;
+ BITMAPINFO *m_pBitmapInfo;
+ HDC m_hDC;
+ HBITMAP m_hBitmap;
+ HBITMAP m_hPrevBitmap;
+ PBYTE m_pBitmapBits;
+};
+
+
+#endif // !_LCDGFX_H_INCLUDED_
+
+//** end of LCDGfx.h *****************************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDManager.cpp b/src/thirdparty/ui/LCDUI/LCDManager.cpp
new file mode 100644
index 000000000..3d83b9165
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDManager.cpp
@@ -0,0 +1,204 @@
+//************************************************************************
+//
+// LCDManager.cpp
+//
+// The CLCDManager class is the representation of a "Screen". LCD UI class
+// objects are added here.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#include "LCDManager.h"
+
+
+//************************************************************************
+//
+// CLCDManager::CLCDManager
+//
+//************************************************************************
+
+CLCDManager::CLCDManager(void)
+{
+ m_dwElapsedTime = 0;
+ m_dwExpirationTime = 0;
+ m_dwStartTime = 0;
+}
+
+
+//************************************************************************
+//
+// CLCDManager::~CLCDManager
+//
+//************************************************************************
+
+CLCDManager::~CLCDManager(void)
+{
+ Shutdown();
+}
+
+
+//************************************************************************
+//
+// CLCDManager::Initialize
+//
+//************************************************************************
+
+HRESULT CLCDManager::Initialize(void)
+{
+ HRESULT hRes = CLCDCollection::Initialize();
+ if(FAILED(hRes))
+ {
+ LCDUITRACE(_T("CLCDManager::Initialize(): failed to initialize base class.\n"));
+ Shutdown();
+ return hRes;
+ }
+
+ SetOrigin(0, 0);
+ SetSize(LGLCD_BMP_WIDTH, LGLCD_BMP_HEIGHT);
+
+ hRes = m_Gfx.Initialize(GetWidth(), GetHeight());
+ if(FAILED(hRes))
+ {
+ LCDUITRACE(_T("CLCDManager::Initialize(): failed to initialize graphics component.\n"));
+ Shutdown();
+ return hRes;
+ }
+
+ return S_OK;
+}
+
+
+//************************************************************************
+//
+// CLCDManager::Shutdown
+//
+//************************************************************************
+
+void CLCDManager::Shutdown(void)
+{
+ m_Gfx.Shutdown();
+}
+
+
+//************************************************************************
+//
+// CLCDManager::GetLCDScreen
+//
+//************************************************************************
+
+lgLcdBitmap160x43x1 *CLCDManager::GetLCDScreen(void)
+{
+ return m_Gfx.GetLCDScreen();
+}
+
+
+//************************************************************************
+//
+// CLCDManager::GetBitmapInfo
+//
+//************************************************************************
+
+BITMAPINFO *CLCDManager::GetBitmapInfo(void)
+{
+ return m_Gfx.GetBitmapInfo();
+}
+
+
+//************************************************************************
+//
+// CLCDManager::Draw
+//
+//************************************************************************
+
+HRESULT CLCDManager::Draw(void)
+{
+ LCDUIASSERT(NULL != m_Gfx.GetHDC());
+ LCDUIASSERT(NULL != m_Gfx.GetHBITMAP());
+ if((NULL == m_Gfx.GetHDC()) || (NULL == m_Gfx.GetHBITMAP()))
+ {
+ LCDUITRACE(_T("CLCDManager::Draw(): trying to draw without successful Initialize() first.!\n"));
+ return E_FAIL;
+ }
+
+ // select our bitmap into the Gfx DC
+ m_Gfx.BeginDraw();
+
+ m_Gfx.ClearScreen();
+
+ // invoke LCD UI Elements
+ OnDraw(m_Gfx);
+
+ // select it back out of it
+ m_Gfx.EndDraw();
+
+ return S_OK;
+}
+
+
+//************************************************************************
+//
+// CLCDManager::Update
+//
+//************************************************************************
+
+void CLCDManager::Update(DWORD dwTimestamp)
+{
+ LCDUIASSERT(m_dwStartTime != 0);
+ m_dwElapsedTime = (dwTimestamp - m_dwStartTime);
+ CLCDCollection::OnUpdate(dwTimestamp);
+}
+
+
+//************************************************************************
+//
+// CLCDManager::SetExpiration
+//
+//************************************************************************
+
+void CLCDManager::SetExpiration(DWORD dwMilliseconds)
+{
+ m_dwStartTime = GetTickCount();
+ m_dwElapsedTime = 0;
+ m_dwExpirationTime = dwMilliseconds;
+}
+
+
+//************************************************************************
+//
+// CLCDManager::HasExpired
+//
+//************************************************************************
+
+BOOL CLCDManager::HasExpired(void)
+{
+ return (!m_dwStartTime || (m_dwElapsedTime > m_dwExpirationTime));
+}
+
+
+//************************************************************************
+//
+// CLCDManager::OnLCDButtonDown
+//
+//************************************************************************
+
+void CLCDManager::OnLCDButtonDown(int nButton)
+{
+ UNREFERENCED_PARAMETER(nButton);
+}
+
+
+//************************************************************************
+//
+// CLCDManager::OnLCDButtonUp
+//
+//************************************************************************
+
+void CLCDManager::OnLCDButtonUp(int nButton)
+{
+ UNREFERENCED_PARAMETER(nButton);
+}
+
+
+//** end of LCDManager.cpp ***********************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDManager.h b/src/thirdparty/ui/LCDUI/LCDManager.h
new file mode 100644
index 000000000..c564b74da
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDManager.h
@@ -0,0 +1,49 @@
+//************************************************************************
+//
+// LCDManager.h
+//
+// The CLCDManager class is the representation of a "Screen". LCD UI class
+// objects are added here.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#ifndef _LCDMANAGER_H_INCLUDED_
+#define _LCDMANAGER_H_INCLUDED_
+
+#include "LCDCollection.h"
+
+
+class CLCDManager : public CLCDCollection
+{
+public:
+ CLCDManager();
+ virtual ~CLCDManager();
+
+ virtual HRESULT Initialize(void);
+ virtual void Shutdown(void);
+
+ lgLcdBitmap160x43x1 *GetLCDScreen(void);
+ BITMAPINFO *GetBitmapInfo(void);
+
+ virtual HRESULT Draw(void);
+ virtual void Update(DWORD dwTimestamp);
+
+ virtual void OnLCDButtonDown(int nButton);
+ virtual void OnLCDButtonUp(int nButton);
+
+ void SetExpiration(DWORD dwMilliseconds);
+ virtual BOOL HasExpired(void);
+
+private:
+ CLCDGfx m_Gfx;
+
+ DWORD m_dwStartTime, m_dwElapsedTime, m_dwExpirationTime;
+};
+
+
+#endif // !_LCDMANAGER_H_INCLUDED_
+
+//** end of LCDManager.h *************************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDOutput.cpp b/src/thirdparty/ui/LCDUI/LCDOutput.cpp
new file mode 100644
index 000000000..6022dddbe
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDOutput.cpp
@@ -0,0 +1,896 @@
+//************************************************************************
+//
+// LCDOutput.cpp
+//
+// The CLCDOutput class manages LCD hardware enumeration and screen
+// management.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#include "../../../DSUtil/SharedInclude.h"
+#include <Afx.h>
+#include "LCDOutput.h"
+
+// to keep track of clients that use multiple CLCDOutput instances
+// within the same app
+static LONG lInitCount = 0;
+
+//************************************************************************
+//
+// CLCDOutput::CLCDOutput
+//
+//************************************************************************
+
+CLCDOutput::CLCDOutput()
+{
+ m_pActiveScreen = NULL;
+ m_bLocked = FALSE;
+ m_hDevice = LGLCD_INVALID_DEVICE;
+ m_hConnection = LGLCD_INVALID_CONNECTION;
+ m_nPriority = LGLCD_PRIORITY_NORMAL;
+ ZeroMemory(&m_lcdConnectCtxEx, sizeof(m_lcdConnectCtxEx));
+ m_bDisplayLocked = FALSE;
+ m_bSetAsForeground = FALSE;
+
+ // Setup default device families
+ m_dwDeviceFamiliesSupported = LGLCD_DEVICE_FAMILY_KEYBOARD_G15 |
+ LGLCD_DEVICE_FAMILY_JACKBOX |
+ LGLCD_DEVICE_FAMILY_SPEAKERS_Z10;
+ m_dwDeviceFamiliesSupportedReserved1 = 0;
+
+ m_pLastBitmap = DNew lgLcdBitmap160x43x1;
+ ClearBitmap(m_pLastBitmap);
+ // Allow the first update to go through
+ m_bPriorityHasChanged = TRUE;
+}
+
+//************************************************************************
+//
+// CLCDOutput::~CLCDOutput
+//
+//************************************************************************
+
+CLCDOutput::~CLCDOutput()
+{
+ delete m_pLastBitmap;
+ m_pLastBitmap = NULL;
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::Initialize
+//
+//************************************************************************
+
+HRESULT CLCDOutput::Initialize()
+{
+ return Initialize((lgLcdConnectContext *)NULL, FALSE);
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::Initialize
+//
+// NOTE: Initialize should always return S_OK
+//************************************************************************
+
+HRESULT CLCDOutput::Initialize(lgLcdConnectContext* pContext, BOOL bUseWindow)
+{
+
+ UNREFERENCED_PARAMETER(bUseWindow);
+
+ DWORD res = ERROR_SUCCESS;
+
+ CLCDManager::Initialize();
+
+ // initialize our screens
+ LCD_MGR_LIST::iterator it = m_LCDMgrList.begin();
+ while(it != m_LCDMgrList.end())
+ {
+ CLCDManager *pMgr = *it;
+ LCDUIASSERT(NULL != pMgr);
+
+ pMgr->Initialize();
+ ++it;
+ }
+
+ // LCD Stuff
+ LCDUIASSERT(lInitCount >= 0);
+ if(1 == InterlockedIncrement(&lInitCount))
+ {
+ // need to call lgLcdInit once
+ res = lgLcdInit();
+ if (ERROR_SUCCESS != res)
+ {
+ InterlockedDecrement(&lInitCount);
+ LCDUITRACE(_T("WARNING: lgLcdInit failed\n"));
+ return E_FAIL;
+ }
+ }
+
+ m_lcdConnectCtxEx.appFriendlyName = _T("My App");
+ m_lcdConnectCtxEx.isPersistent = FALSE;
+ m_lcdConnectCtxEx.isAutostartable = FALSE;
+ m_lcdConnectCtxEx.connection = LGLCD_INVALID_CONNECTION;
+
+ // Initialize the added version 3.0 API fields
+ m_lcdConnectCtxEx.dwAppletCapabilitiesSupported = LGLCD_APPLET_CAP_BASIC;
+ m_lcdConnectCtxEx.dwReserved1 = 0;
+ m_lcdConnectCtxEx.onNotify.notificationCallback = NULL;
+ m_lcdConnectCtxEx.onNotify.notifyContext = NULL;
+
+ // if user passed in the context, fill it up
+ if (NULL != pContext)
+ {
+ memcpy(&m_lcdConnectCtxEx, pContext, sizeof(lgLcdConnectContext));
+ }
+
+ return S_OK;
+}
+
+//************************************************************************
+//
+// CLCDOutput::Initialize
+//
+// NOTE: Initialize should always return S_OK
+//************************************************************************
+
+HRESULT CLCDOutput::Initialize(lgLcdConnectContextEx* pContextEx, BOOL bUseWindow)
+{
+
+ UNREFERENCED_PARAMETER(bUseWindow);
+
+ DWORD res = ERROR_SUCCESS;
+
+ CLCDManager::Initialize();
+
+ // initialize our screens
+ LCD_MGR_LIST::iterator it = m_LCDMgrList.begin();
+ while(it != m_LCDMgrList.end())
+ {
+ CLCDManager *pMgr = *it;
+ LCDUIASSERT(NULL != pMgr);
+
+ pMgr->Initialize();
+ ++it;
+ }
+
+ // LCD Stuff
+ LCDUIASSERT(lInitCount >= 0);
+ if(1 == InterlockedIncrement(&lInitCount))
+ {
+ // need to call lgLcdInit once
+ res = lgLcdInit();
+ if (ERROR_SUCCESS != res)
+ {
+ InterlockedDecrement(&lInitCount);
+ LCDUITRACE(_T("WARNING: lgLcdInit failed\n"));
+ return E_FAIL;
+ }
+ }
+
+
+ m_lcdConnectCtxEx.appFriendlyName = _T("My App");
+ m_lcdConnectCtxEx.isPersistent = FALSE;
+ m_lcdConnectCtxEx.isAutostartable = FALSE;
+ m_lcdConnectCtxEx.connection = LGLCD_INVALID_CONNECTION;
+
+ // if user passed in the context, fill it up
+ if (NULL != pContextEx)
+ {
+ memcpy(&m_lcdConnectCtxEx, pContextEx, sizeof(lgLcdConnectContextEx));
+ }
+
+ return S_OK;
+}
+
+//************************************************************************
+//
+// CLCDOutput::Shutdown
+//
+//************************************************************************
+
+void CLCDOutput::Shutdown(void)
+{
+ CloseAndDisconnect();
+ if(0 == InterlockedDecrement(&lInitCount))
+ {
+ lgLcdDeInit();
+ }
+ LCDUIASSERT(lInitCount >= 0);
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::Draw
+//
+//************************************************************************
+
+HRESULT CLCDOutput::Draw()
+{
+ DWORD dwPriorityToUse = LGLCD_ASYNC_UPDATE(m_nPriority);
+
+ if ( (NULL == m_pActiveScreen) ||
+ (LGLCD_INVALID_DEVICE == m_hDevice) ||
+ (LGLCD_PRIORITY_IDLE_NO_SHOW == dwPriorityToUse) )
+ {
+ // don't submit the bitmap
+ return S_OK;
+ }
+
+ // Render the active screen
+ m_pActiveScreen->Draw();
+
+ // Get the active bitmap
+ lgLcdBitmap160x43x1* pScreen = m_pActiveScreen->GetLCDScreen();
+
+ // Only submit if the bitmap needs to be updated
+ // (If the priority or bitmap have changed)
+ DWORD res = ERROR_SUCCESS;
+ if (DoesBitmapNeedUpdate(pScreen))
+ {
+ res = lgLcdUpdateBitmap(m_hDevice, &pScreen->hdr, dwPriorityToUse);
+ HandleErrorFromAPI(res);
+ }
+
+ // read the soft buttons
+ ReadButtons();
+
+ return S_OK;
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::Update
+//
+//************************************************************************
+
+void CLCDOutput::Update(DWORD dwTimestamp)
+{
+ if (m_pActiveScreen)
+ {
+ m_pActiveScreen->Update(dwTimestamp);
+ }
+
+ // check for expiration
+ if (m_pActiveScreen && m_pActiveScreen->HasExpired())
+ {
+ m_pActiveScreen = NULL;
+ //m_nPriority = LGLCD_PRIORITY_FYI; -> needs to go so that if a
+ // program sets priority to LGLCD_PRIORITY_BACKGROUND, that
+ // priority sticks.
+
+ OnScreenExpired(m_pActiveScreen);
+
+ // Clear the bitmap
+ ClearBitmap(m_pLastBitmap);
+
+ // find the next active screen
+ LCD_MGR_LIST::iterator it = m_LCDMgrList.begin();
+ while(it != m_LCDMgrList.end())
+ {
+ CLCDManager *pMgr = *it;
+ LCDUIASSERT(NULL != pMgr);
+
+ if (!pMgr->HasExpired())
+ {
+ ActivateScreen(pMgr);
+ //m_nPriority = LGLCD_PRIORITY_FYI; -> needs to go so that if a
+ // program sets priority to LGLCD_PRIORITY_BACKGROUND, that
+ // priority sticks.
+ break;
+ }
+
+ ++it;
+ }
+
+ // if no screen found, empty the screen at idle priority
+ if (NULL == m_pActiveScreen)
+ {
+ if (LGLCD_INVALID_DEVICE != m_hDevice)
+ {
+ lgLcdUpdateBitmap(m_hDevice, &CLCDManager::GetLCDScreen()->hdr,
+ LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW));
+ }
+ }
+ }
+
+ // check for lcd devices
+ if (LGLCD_INVALID_DEVICE == m_hDevice)
+ {
+ EnumerateDevices();
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::HasHardwareChanged
+//
+//************************************************************************
+
+BOOL CLCDOutput::HasHardwareChanged(void)
+{
+ if(LGLCD_INVALID_DEVICE != m_hDevice)
+ {
+ // ping to see whether we're still alive
+ DWORD dwButtonState = 0;
+
+ DWORD res = lgLcdReadSoftButtons(m_hDevice, &dwButtonState);
+
+ HandleErrorFromAPI(res);
+ }
+
+ // check for lcd devices
+ if (LGLCD_INVALID_DEVICE == m_hDevice)
+ {
+ EnumerateDevices();
+ }
+ else
+ {
+ // we still have our device;
+ return FALSE;
+ }
+
+ // we got a new device
+ return LGLCD_INVALID_DEVICE != m_hDevice;
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::GetLCDScreen
+//
+//************************************************************************
+
+lgLcdBitmap160x43x1 *CLCDOutput::GetLCDScreen(void)
+{
+ return m_pActiveScreen ? m_pActiveScreen->GetLCDScreen() : CLCDManager::GetLCDScreen();
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::GetBitmapInfo
+//
+//************************************************************************
+
+BITMAPINFO *CLCDOutput::GetBitmapInfo(void)
+{
+ return m_pActiveScreen ? m_pActiveScreen->GetBitmapInfo() : CLCDManager::GetBitmapInfo();
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::ReadButtons
+//
+//************************************************************************
+
+void CLCDOutput::ReadButtons()
+{
+ if(IsOpened())
+ {
+ DWORD dwButtonState = 0;
+
+ DWORD res = lgLcdReadSoftButtons(m_hDevice, &dwButtonState);
+ if (ERROR_SUCCESS != res)
+ {
+ LCDUITRACE(_T("lgLcdReadSoftButtons failed: unplug?\n"));
+ HandleErrorFromAPI(res);
+ }
+
+ if (m_dwButtonState == dwButtonState)
+ return;
+
+ // handle the buttons
+ HandleButtonState(dwButtonState, LGLCDBUTTON_BUTTON0);
+ HandleButtonState(dwButtonState, LGLCDBUTTON_BUTTON1);
+ HandleButtonState(dwButtonState, LGLCDBUTTON_BUTTON2);
+ HandleButtonState(dwButtonState, LGLCDBUTTON_BUTTON3);
+
+ m_dwButtonState = dwButtonState;
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::HandleButtonState
+//
+//************************************************************************
+
+void CLCDOutput::HandleButtonState(DWORD dwButtonState, DWORD dwButton)
+{
+ if ( (m_dwButtonState & dwButton) && !(dwButtonState & dwButton) )
+ {
+ LCDUITRACE(_T("Button 0x%x released\n"), dwButton);
+ OnLCDButtonUp(dwButton);
+ }
+ if ( !(m_dwButtonState & dwButton) && (dwButtonState & dwButton) )
+ {
+ LCDUITRACE(_T("Button 0x%x pressed\n"), dwButton);
+ OnLCDButtonDown(dwButton);
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::OnLCDButtonDown
+//
+//************************************************************************
+
+void CLCDOutput::OnLCDButtonDown(int nButton)
+{
+ if (m_pActiveScreen)
+ {
+ m_pActiveScreen->OnLCDButtonDown(nButton);
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::OnLCDButtonUp
+//
+//************************************************************************
+
+void CLCDOutput::OnLCDButtonUp(int nButton)
+{
+ if (m_pActiveScreen)
+ {
+ m_pActiveScreen->OnLCDButtonUp(nButton);
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::ActivateScreen
+//
+//************************************************************************
+
+void CLCDOutput::ActivateScreen(CLCDManager* pScreen)
+{
+ if (m_bLocked)
+ return;
+ m_pActiveScreen = pScreen;
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::LockScreen
+//
+//************************************************************************
+
+void CLCDOutput::LockScreen(CLCDManager* pScreen)
+{
+ if (m_bLocked)
+ return;
+
+ m_pActiveScreen = pScreen;
+ m_bLocked = TRUE;
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::UnlockScreen
+//
+//************************************************************************
+
+void CLCDOutput::UnlockScreen()
+{
+ m_bLocked = FALSE;
+ m_pActiveScreen = NULL;
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::IsLocked
+//
+//************************************************************************
+
+BOOL CLCDOutput::IsLocked()
+{
+ return m_bLocked;
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::AddScreen
+//
+//************************************************************************
+
+void CLCDOutput::AddScreen(CLCDManager* pScreen)
+{
+ m_LCDMgrList.push_back(pScreen);
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::AnyDeviceOfThisFamilyPresent
+//
+//************************************************************************
+
+BOOL CLCDOutput::AnyDeviceOfThisFamilyPresent(DWORD dwDeviceFamilyWanted, DWORD dwReserved1)
+{
+ lgLcdDeviceDescEx descEx;
+
+ if (LGLCD_INVALID_CONNECTION == m_hConnection)
+ {
+ if (ERROR_SUCCESS == lgLcdConnectEx(&m_lcdConnectCtxEx))
+ {
+ // make sure we don't work with a stale device handle
+ m_hConnection = m_lcdConnectCtxEx.connection;
+ m_hDevice = LGLCD_INVALID_CONNECTION;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+
+ // Setup the device family to use next time
+ lgLcdSetDeviceFamiliesToUse(m_hConnection, dwDeviceFamilyWanted, dwReserved1);
+
+ ZeroMemory(&descEx, sizeof(lgLcdDeviceDescEx));
+ DWORD res = ERROR_SUCCESS;
+
+ res = lgLcdEnumerateEx(m_hConnection, 0, &descEx);
+
+ if (ERROR_SUCCESS != res)
+ {
+ if(ERROR_NO_MORE_ITEMS != res)
+ {
+ // something happened. Let's close this.
+ CloseAndDisconnect();
+ return FALSE;
+ }
+
+ // Go back to the previous device family we were using
+ lgLcdSetDeviceFamiliesToUse(m_hConnection, m_dwDeviceFamiliesSupported,
+ m_dwDeviceFamiliesSupportedReserved1);
+
+ return FALSE;
+ }
+
+ // Go back to what was being used
+ lgLcdSetDeviceFamiliesToUse(m_hConnection, m_dwDeviceFamiliesSupported,
+ m_dwDeviceFamiliesSupportedReserved1);
+
+ return TRUE;
+}
+
+//************************************************************************
+//
+// CLCDOutput::SetDeviceFamiliesSupported
+//
+//************************************************************************
+
+void CLCDOutput::SetDeviceFamiliesSupported(DWORD dwDeviceFamiliesSupported, DWORD dwReserved1)
+{
+ m_dwDeviceFamiliesSupported = dwDeviceFamiliesSupported;
+ m_dwDeviceFamiliesSupportedReserved1 = dwReserved1;
+
+ if (LGLCD_INVALID_CONNECTION == m_hConnection)
+ {
+ if (ERROR_SUCCESS == lgLcdConnectEx(&m_lcdConnectCtxEx))
+ {
+ // make sure we don't work with a stale device handle
+ m_hConnection = m_lcdConnectCtxEx.connection;
+ m_hDevice = LGLCD_INVALID_CONNECTION;
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ // close the lcd device before we open up another
+ if (LGLCD_INVALID_DEVICE != m_hDevice)
+ {
+ lgLcdClose(m_hDevice);
+ m_hDevice = LGLCD_INVALID_DEVICE;
+
+ }
+
+ // Setup the device family to use next time
+ lgLcdSetDeviceFamiliesToUse(m_hConnection, m_dwDeviceFamiliesSupported, m_dwDeviceFamiliesSupportedReserved1);
+}
+
+//************************************************************************
+//
+// CLCDOutput::EnumerateDevices
+//
+//************************************************************************
+
+void CLCDOutput::EnumerateDevices()
+{
+ lgLcdDeviceDescEx descEx;
+
+ if (LGLCD_INVALID_CONNECTION == m_hConnection)
+ {
+ if (ERROR_SUCCESS == lgLcdConnectEx(&m_lcdConnectCtxEx))
+ {
+ // make sure we don't work with a stale device handle
+ m_hConnection = m_lcdConnectCtxEx.connection;
+ m_hDevice = LGLCD_INVALID_CONNECTION;
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ // close the lcd device before we open up another
+ if (LGLCD_INVALID_DEVICE != m_hDevice)
+ {
+ lgLcdClose(m_hDevice);
+ m_hDevice = LGLCD_INVALID_DEVICE;
+
+ }
+
+ // Setup the device family to use next time
+ lgLcdSetDeviceFamiliesToUse(m_hConnection, m_dwDeviceFamiliesSupported, m_dwDeviceFamiliesSupportedReserved1);
+
+ ZeroMemory(&descEx, sizeof(lgLcdDeviceDescEx));
+ DWORD res = ERROR_SUCCESS;
+
+ res = lgLcdEnumerateEx(m_hConnection, 0, &descEx);
+ if (ERROR_SUCCESS != res)
+ {
+ if(ERROR_NO_MORE_ITEMS != res)
+ {
+ // something happened. Let's close this.
+ CloseAndDisconnect();
+ }
+ return;
+ }
+// ERROR_NO_MORE_ITEMS
+ lgLcdOpenContext open_ctx;
+ ZeroMemory(&open_ctx, sizeof(open_ctx));
+
+ open_ctx.connection = m_hConnection;
+ open_ctx.index = 0;
+ res = lgLcdOpen(&open_ctx);
+ if (ERROR_SUCCESS != res)
+ return;
+ m_hDevice = open_ctx.device;
+ m_dwButtonState = 0;
+
+ // restores
+ SetAsForeground(m_bSetAsForeground);
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::HandleErrorFromAPI
+//
+//************************************************************************
+void CLCDOutput::HandleErrorFromAPI(DWORD dwRes)
+{
+ switch(dwRes)
+ {
+ // all is well
+ case ERROR_SUCCESS:
+ break;
+ // we lost our device
+ case ERROR_DEVICE_NOT_CONNECTED:
+ LCDUITRACE(_T("lgLcdAPI returned with ERROR_DEVICE_NOT_CONNECTED, closing device\n"));
+ OnClosingDevice(m_hDevice);
+ break;
+ default:
+ LCDUITRACE(_T("lgLcdAPI returned with other error (0x%08x) closing device and connection\n"));
+ OnClosingDevice(m_hDevice);
+ OnDisconnecting(m_hConnection);
+ // something else happened, such as LCDMon that was terminated
+ break;
+ }
+}
+
+//************************************************************************
+//
+// CLCDOutput::SetScreenPriority
+//
+//************************************************************************
+void CLCDOutput::SetScreenPriority(DWORD priority)
+{
+ if (priority == m_nPriority)
+ {
+ // Nothing to do
+ return;
+ }
+
+ // Clear the bitmap
+ ClearBitmap(m_pLastBitmap);
+
+ m_nPriority = priority;
+ m_bPriorityHasChanged = TRUE;
+
+ if (LGLCD_PRIORITY_IDLE_NO_SHOW == m_nPriority)
+ {
+ // send an empty bitmap at idle priority
+ if (LGLCD_INVALID_DEVICE != m_hDevice)
+ {
+ lgLcdUpdateBitmap(m_hDevice, &m_pLastBitmap->hdr,
+ LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW));
+ }
+ }
+}
+
+//************************************************************************
+//
+// CLCDOutput::GetScreenPriority
+//
+//************************************************************************
+DWORD CLCDOutput::GetScreenPriority()
+{
+ return m_nPriority;
+}
+
+//************************************************************************
+//
+// CLCDOutput::GetDeviceHandle
+//
+//************************************************************************
+INT CLCDOutput::GetDeviceHandle()
+{
+ return m_hDevice;
+}
+
+//************************************************************************
+//
+// CLCDOutput::CloseAndDisconnect
+//
+//************************************************************************
+
+void CLCDOutput::CloseAndDisconnect()
+{
+ OnClosingDevice(m_hDevice);
+ OnDisconnecting(m_hConnection);
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::OnScreenExpired
+//
+//************************************************************************
+
+void CLCDOutput::OnScreenExpired(CLCDManager* pScreen)
+{
+ UNREFERENCED_PARAMETER(pScreen);
+ UnlockScreen();
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::OnClosingDevice
+//
+//************************************************************************
+
+void CLCDOutput::OnClosingDevice(int hDevice)
+{
+ UNREFERENCED_PARAMETER(hDevice);
+ LCDUITRACE(_T("CLCDOutput::OnClosingDevice\n"));
+ if (IsOpened())
+ {
+ lgLcdClose(m_hDevice);
+ m_hDevice = LGLCD_INVALID_DEVICE;
+ }
+ ClearBitmap(m_pLastBitmap);
+}
+
+//************************************************************************
+//
+// CLCDOutput::OnDisconnecting
+//
+//************************************************************************
+
+void CLCDOutput::OnDisconnecting(int hConnection)
+{
+ UNREFERENCED_PARAMETER(hConnection);
+ LCDUITRACE(_T("CLCDOutput::OnDisconnecting\n"));
+ // let's hope our device is already gone
+ LCDUIASSERT(!IsOpened());
+
+ if (LGLCD_INVALID_CONNECTION != m_hConnection)
+ {
+ lgLcdDisconnect(m_hConnection);
+ m_hConnection = LGLCD_INVALID_CONNECTION;
+ ZeroMemory(m_pLastBitmap, sizeof(lgLcdBitmap160x43x1));
+ }
+}
+
+//************************************************************************
+//
+// CLCDOutput::IsOpened
+//
+//************************************************************************
+
+BOOL CLCDOutput::IsOpened()
+{
+ return (LGLCD_INVALID_DEVICE != m_hDevice);
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::SetAsForeground
+//
+//************************************************************************
+
+void CLCDOutput::SetAsForeground(BOOL bSetAsForeground)
+{
+ /*DWORD dwSet = */bSetAsForeground ? LGLCD_LCD_FOREGROUND_APP_YES : LGLCD_LCD_FOREGROUND_APP_NO;
+ m_bSetAsForeground = bSetAsForeground;
+ if (LGLCD_INVALID_DEVICE != m_hDevice)
+ {
+ lgLcdSetAsLCDForegroundApp(m_hDevice, bSetAsForeground);
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::DoesBitmapNeedUpdate
+//
+//************************************************************************
+
+BOOL CLCDOutput::DoesBitmapNeedUpdate(lgLcdBitmap160x43x1* pCurrentBitmap)
+{
+ // The bitmap is different from the last one sent
+ // send the bitmap
+ BOOL bBitmapChanged = 0 != memcmp(pCurrentBitmap, m_pLastBitmap, sizeof(lgLcdBitmap160x43x1));
+ BOOL bPriorityChanged = m_bPriorityHasChanged;
+
+ if (bBitmapChanged)
+ {
+ LCDUITRACE(_T("Resubmitting bitmap (bitmap changed)\n"));
+ }
+ else if (bPriorityChanged)
+ {
+ LCDUITRACE(_T("Resubmitting bitmap (priority changed)\n"));
+ }
+
+ // Save the current bitmap
+ memcpy(m_pLastBitmap, pCurrentBitmap, sizeof(lgLcdBitmap160x43x1));
+ // Reset the priority change
+ m_bPriorityHasChanged = FALSE;
+
+ return (bBitmapChanged || bPriorityChanged);
+}
+
+
+//************************************************************************
+//
+// CLCDOutput::ClearBitmap
+//
+//************************************************************************
+
+void CLCDOutput::ClearBitmap(lgLcdBitmap160x43x1* pCurrentBitmap)
+{
+ LCDUIASSERT(NULL != pCurrentBitmap);
+ if (pCurrentBitmap)
+ {
+ pCurrentBitmap->hdr.Format = LGLCD_BMP_FORMAT_160x43x1;
+ ZeroMemory(pCurrentBitmap->pixels, sizeof(pCurrentBitmap->pixels));
+ }
+}
+
+//** end of LCDOutput.cpp ************************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDOutput.h b/src/thirdparty/ui/LCDUI/LCDOutput.h
new file mode 100644
index 000000000..7a379aea0
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDOutput.h
@@ -0,0 +1,107 @@
+//************************************************************************
+//
+// LCDOutput.h
+//
+// The CLCDOutput class manages LCD hardware enumeration and screen
+// management.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#ifndef _CLCDOUTPUT_H_INCLUDED_
+#define _CLCDOUTPUT_H_INCLUDED_
+
+#include "LCDManager.h"
+#include <lglcd/lglcd.h>
+#include <vector>
+
+using namespace std;
+
+typedef vector <CLCDManager*> LCD_MGR_LIST;
+typedef LCD_MGR_LIST::iterator LCD_MGR_LIST_ITER;
+
+class CLCDOutput : public CLCDManager
+{
+
+public:
+ CLCDOutput();
+ virtual ~CLCDOutput();
+
+ void AddScreen(CLCDManager* pScreen);
+
+ void LockScreen(CLCDManager* pScreen);
+ void UnlockScreen();
+ BOOL IsLocked();
+
+ BOOL IsOpened();
+ void SetAsForeground(BOOL bSetAsForeground);
+ BOOL AnyDeviceOfThisFamilyPresent(DWORD dwDeviceFamilyWanted, DWORD dwReserved1);
+ void SetDeviceFamiliesSupported(DWORD dwDeviceFamiliesSupported, DWORD dwReserved1);
+
+ void SetScreenPriority(DWORD priority);
+ DWORD GetScreenPriority();
+
+ INT GetDeviceHandle();
+
+ HRESULT Initialize(lgLcdConnectContext* pContext, BOOL bUseWindow = FALSE);
+ HRESULT Initialize(lgLcdConnectContextEx* pContextEx, BOOL bUseWindow = FALSE);
+
+ // returns TRUE if a new display was enumerated
+ BOOL HasHardwareChanged(void);
+
+ // CLCDBase
+ virtual HRESULT Initialize();
+ virtual HRESULT Draw();
+ virtual void Update(DWORD dwTimestamp);
+ virtual void Shutdown(void);
+
+ // CLCDManager
+ lgLcdBitmap160x43x1 *GetLCDScreen(void);
+ BITMAPINFO *GetBitmapInfo(void);
+
+protected:
+ void ActivateScreen(CLCDManager* pScreen);
+ void ReadButtons();
+ void HandleButtonState(DWORD dwButtonState, DWORD dwButton);
+ void HandleErrorFromAPI(DWORD dwRes);
+ void CloseAndDisconnect();
+
+ virtual void OnLCDButtonDown(int nButton);
+ virtual void OnLCDButtonUp(int nButton);
+
+protected:
+ virtual void OnScreenExpired(CLCDManager* pScreen);
+ virtual void OnClosingDevice(int hDevice);
+ virtual void OnDisconnecting(int hConnection);
+
+protected:
+ BOOL DoesBitmapNeedUpdate(lgLcdBitmap160x43x1* pCurrentBitmap);
+ void ClearBitmap(lgLcdBitmap160x43x1* pCurrentBitmap);
+ lgLcdBitmap160x43x1* m_pLastBitmap;
+ BOOL m_bPriorityHasChanged;
+
+protected:
+ CLCDManager* m_pActiveScreen;
+
+ // list
+ LCD_MGR_LIST m_LCDMgrList;
+
+ void EnumerateDevices();
+ int m_hConnection;
+ int m_hDevice;
+ DWORD m_nPriority;
+ BOOL m_bLocked, m_bDisplayLocked;
+ DWORD m_dwButtonState;
+ BOOL m_bSetAsForeground;
+
+// lgLcdConnectContext m_lcdConnectCtx;
+ lgLcdConnectContextEx m_lcdConnectCtxEx;
+ DWORD m_dwDeviceFamiliesSupported;
+ DWORD m_dwDeviceFamiliesSupportedReserved1;
+};
+
+#endif // !_CLCDOUTPUT_H_INCLUDED_
+
+//** end of CLCDOutput.h *************************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDProgressBar.cpp b/src/thirdparty/ui/LCDUI/LCDProgressBar.cpp
new file mode 100644
index 000000000..978cb2558
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDProgressBar.cpp
@@ -0,0 +1,270 @@
+//************************************************************************
+//
+// LCDProgressBar.cpp
+//
+// The CLCDProgressBar class draws a progress bar onto the LCD.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#include "LCDProgressBar.h"
+
+//************************************************************************
+//
+// CLCDProgressBar::CLCDProgressBar
+//
+//************************************************************************
+
+CLCDProgressBar::CLCDProgressBar()
+{
+ m_Pos = 0;
+ m_eStyle = STYLE_CURSOR;
+ m_Range.nMin = 0;
+ m_Range.nMax = 100;
+ m_nCursorWidth = 5;
+ m_hPen = NULL;
+}
+
+
+//************************************************************************
+//
+// CLCDProgressBar::~CLCDProgressBar
+//
+//************************************************************************
+
+CLCDProgressBar::~CLCDProgressBar()
+{
+ if (m_hPen != NULL)
+ {
+ ::DeleteObject(m_hPen);
+ m_hPen = NULL;
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDProgressBar:Initialize
+//
+//************************************************************************
+
+HRESULT CLCDProgressBar::Initialize()
+{
+
+ m_hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
+ m_hPen = ::CreatePen(PS_DOT, 1, RGB(255, 255, 255));
+
+ return CLCDBase::Initialize();
+}
+
+
+//************************************************************************
+//
+// CLCDProgressBar::OnDraw
+//
+//************************************************************************
+
+void CLCDProgressBar::OnDraw(CLCDGfx &rGfx)
+{
+ HPEN hOldPen;
+
+ rGfx.ClearScreen();
+
+ // draw the border
+ RECT r = { 0, 0, GetWidth(), GetHeight() };
+
+ FrameRect(rGfx.GetHDC(), &r, m_hBrush);
+
+ // draw the progress
+ switch(m_eStyle)
+ {
+ case STYLE_CURSOR:
+ {
+ int nCursorPos = (int)Scalef((float)m_Range.nMin, (float)m_Range.nMax,
+ (float)1, (float)(GetWidth() - m_nCursorWidth-1),
+ m_Pos);
+ r.left = nCursorPos;
+ r.right = r.left + m_nCursorWidth;
+ FillRect(rGfx.GetHDC(), &r, m_hBrush);
+ }
+ break;
+ case STYLE_FILLED_V:
+ case STYLE_FILLED_H:
+ {
+ int nBar = (int)Scalef((float)m_Range.nMin, (float)m_Range.nMax,
+ 0.0f, (m_eStyle == STYLE_FILLED_H ? (float)GetWidth() : (float)GetHeight())-4,
+ m_Pos);
+ r.left = r.left+2;
+ r.bottom = r.bottom-2;
+ if (m_eStyle == STYLE_FILLED_H)
+ {
+ r.right = nBar+2;
+ r.top = r.top+2;
+ }
+ else
+ {
+ r.right = r.right-2;
+ r.top = r.bottom-nBar;
+ }
+
+ FillRect(rGfx.GetHDC(), &r, m_hBrush);
+ }
+ break;
+ case STYLE_DASHED_CURSOR:
+ {
+ int nCursorPos = (int)Scalef((float)m_Range.nMin, (float)m_Range.nMax,
+ (float)1, (float)(GetWidth() - m_nCursorWidth-1),
+ m_Pos);
+ r.left = nCursorPos;
+ r.right = r.left + m_nCursorWidth;
+ FillRect(rGfx.GetHDC(), &r, m_hBrush);
+ hOldPen = (HPEN)::SelectObject(rGfx.GetHDC(), m_hPen);
+
+ ::MoveToEx(rGfx.GetHDC(), 0, (r.bottom - r.top)/2, NULL);
+ ::LineTo(rGfx.GetHDC(), nCursorPos, (r.bottom - r.top)/2);
+ ::SelectObject(rGfx.GetHDC(), hOldPen);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDProgressBar::ResetUpdate
+//
+//************************************************************************
+
+void CLCDProgressBar::ResetUpdate()
+{
+
+}
+
+
+//************************************************************************
+//
+// CLCDProgressBar::SetRange
+//
+//************************************************************************
+
+void CLCDProgressBar::SetRange(__int64 nMin, __int64 nMax)
+{
+ m_Range.nMin = nMin;
+ m_Range.nMax = nMax;
+}
+
+
+//************************************************************************
+//
+// CLCDProgressBar::SetRange
+//
+//************************************************************************
+
+void CLCDProgressBar::SetRange(RANGE& Range)
+{
+ m_Range = Range;
+}
+
+
+//************************************************************************
+//
+// CLCDProgressBar::GetRange
+//
+//************************************************************************
+
+RANGE& CLCDProgressBar::GetRange()
+{
+ return m_Range;
+}
+
+
+//************************************************************************
+//
+// CLCDProgressBar::SetPos
+//
+//************************************************************************
+
+__int64 CLCDProgressBar::SetPos(__int64 Pos)
+{
+ return ( m_Pos = max(m_Range.nMin, min(Pos, m_Range.nMax)) );
+}
+
+
+//************************************************************************
+//
+// CLCDProgressBar::GetPos
+//
+//************************************************************************
+
+__int64 CLCDProgressBar::GetPos()
+{
+ return m_Pos;
+}
+
+
+//************************************************************************
+//
+// CLCDProgressBar::EnableCursor
+//
+//************************************************************************
+
+void CLCDProgressBar::EnableCursor(BOOL bEnable)
+{
+ m_eStyle = bEnable ? STYLE_CURSOR : STYLE_FILLED_H;
+}
+
+//************************************************************************
+//
+// CLCDProgressBar::SetProgressStyle
+//
+//************************************************************************
+
+void CLCDProgressBar::SetProgressStyle(ePROGRESS_STYLE eStyle)
+{
+ m_eStyle = eStyle;
+}
+
+//************************************************************************
+//
+// CLCDProgressBar::Scalef
+//
+//************************************************************************
+
+float CLCDProgressBar::Scalef(float fFromMin, float fFromMax,
+ float fToMin, float fToMax, __int64 fFromValue)
+{
+
+ // normalize the input
+ float fFromValueN = (fFromValue - fFromMin) / (fFromMax - fFromMin);
+
+ // now scale to the output
+ float fToRange = fToMax - fToMin;
+
+ return ( fToMin + (fFromValueN * fToRange) );
+}
+
+
+//************************************************************************
+//
+// CLCDProgressBar::Scale
+//
+//************************************************************************
+
+int CLCDProgressBar::Scale(int nFromMin, int nFromMax,
+ int nToMin, int nToMax, __int64 nFromValue)
+{
+ return (int)Scalef(
+ (float)nFromMin,
+ (float)nFromMax,
+ (float)nToMin,
+ (float)nToMax,
+ nFromValue
+ );
+}
+
+
+//** end of LCDProgressBar.cpp *******************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDProgressBar.h b/src/thirdparty/ui/LCDUI/LCDProgressBar.h
new file mode 100644
index 000000000..346bf6c2b
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDProgressBar.h
@@ -0,0 +1,66 @@
+//************************************************************************
+//
+// LCDProgressBar.h
+//
+// The CLCDProgressBar class draws a progress bar onto the LCD.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#ifndef _LCDPROGRESSBAR_H_INCLUDED_
+#define _LCDPROGRESSBAR_H_INCLUDED_
+
+#include "LCDBase.h"
+
+typedef struct RANGE
+{
+ __int64 nMin;
+ __int64 nMax;
+
+}RANGE, *LPRANGE;
+
+enum ePROGRESS_STYLE { STYLE_FILLED_H, STYLE_FILLED_V, STYLE_CURSOR, STYLE_DASHED_CURSOR };
+
+class CLCDProgressBar : public CLCDBase
+{
+public:
+ enum ePROGRESS_STYLE { STYLE_FILLED_H, STYLE_FILLED_V, STYLE_CURSOR, STYLE_DASHED_CURSOR };
+
+ CLCDProgressBar();
+ virtual ~CLCDProgressBar();
+
+ // CLCDBase
+ virtual HRESULT Initialize(void);
+ virtual void OnDraw(CLCDGfx &rGfx);
+ virtual void ResetUpdate(void);
+
+ // CLCDProgressBar
+ virtual void SetRange(__int64 nMin, __int64 nMax);
+ virtual void SetRange(RANGE& Range);
+ virtual RANGE& GetRange(void);
+ virtual __int64 SetPos(__int64 fPos);
+ virtual __int64 GetPos(void);
+ virtual void EnableCursor(BOOL bEnable);
+ virtual void SetProgressStyle(ePROGRESS_STYLE eStyle);
+
+protected:
+ float Scalef(float fFromMin, float fFromMax,
+ float fToMin, float fToMax, __int64 fFromValue);
+ int Scale(int nFromMin, int nFromMax,
+ int nToMin, int nToMax, __int64 nFromValue);
+
+private:
+ RANGE m_Range;
+ __int64 m_Pos;
+ ePROGRESS_STYLE m_eStyle;
+ HBRUSH m_hBrush;
+ HPEN m_hPen;
+ int m_nCursorWidth;
+};
+
+
+#endif // !_LCDPROGRESSBAR_H_INCLUDED_
+
+//** end of LCDProgressBar.h *********************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDScrollingText.cpp b/src/thirdparty/ui/LCDUI/LCDScrollingText.cpp
new file mode 100644
index 000000000..880fc505a
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDScrollingText.cpp
@@ -0,0 +1,294 @@
+//************************************************************************
+//
+// LCDScrollingText.cpp
+//
+// The CLCDScrollingText class draws scrolling text onto the LCD.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#include "LCDScrollingText.h"
+
+
+//************************************************************************
+//
+// CLCDScrollingText::CLCDScrollingText
+//
+//************************************************************************
+
+CLCDScrollingText::CLCDScrollingText()
+{
+ m_eState = STATE_START_DELAY;
+ m_eScrollDir = SCROLL_HORZ;
+ m_bRepeat = TRUE;
+}
+
+
+//************************************************************************
+//
+// CLCDScrollingText::~CLCDScrollingText
+//
+//************************************************************************
+
+CLCDScrollingText::~CLCDScrollingText()
+{
+
+}
+
+
+//************************************************************************
+//
+// CLCDScrollingText::Initialize
+//
+//************************************************************************
+
+HRESULT CLCDScrollingText::Initialize(void)
+{
+ m_dwStartDelay = 1000;
+ m_dwSpeed = 20;
+ m_nScrollingDistance = -1;
+ m_dwLastUpdate = 0;
+ m_dwEllapsedTime = 0;
+ m_dwLastUpdate = GetTickCount();
+ m_fTotalDistance = 0;
+ m_eScrollDir = SCROLL_HORZ;
+ m_dwEndDelay = 1000;
+ m_bRepeat = TRUE;
+
+ return CLCDText::Initialize();
+}
+
+
+//************************************************************************
+//
+// CLCDScrollingText::ResetUpdate
+//
+//************************************************************************
+
+void CLCDScrollingText::ResetUpdate(void)
+{
+ m_eState = STATE_START_DELAY;
+ m_dwEllapsedTime = 0;
+ m_dwLastUpdate = GetTickCount();
+ m_nScrollingDistance = -1;
+ m_fTotalDistance = 0;
+ SetLeftMargin(0);
+ SetLogicalOrigin(0, 0);
+
+ CLCDText::ResetUpdate();
+}
+
+
+//************************************************************************
+//
+// CLCDScrollingText::SetStartDelay
+//
+//************************************************************************
+
+void CLCDScrollingText::SetStartDelay(DWORD dwMilliseconds)
+{
+ m_dwStartDelay = dwMilliseconds;
+}
+
+
+//************************************************************************
+//
+// CLCDScrollingText::SetEndDelay
+//
+//************************************************************************
+
+void CLCDScrollingText::SetEndDelay(DWORD dwMilliseconds)
+{
+ m_dwEndDelay = dwMilliseconds;
+}
+
+
+//************************************************************************
+//
+// CLCDScrollingText::SetSpeed
+//
+//************************************************************************
+
+void CLCDScrollingText::SetSpeed(DWORD dwSpeed)
+{
+ m_dwSpeed = dwSpeed;
+}
+
+
+//************************************************************************
+//
+// CLCDScrollingText::SetScrollDirection
+//
+//************************************************************************
+
+void CLCDScrollingText::SetScrollDirection(eSCROLL_DIR eScrollDir)
+{
+ m_eScrollDir = eScrollDir;
+ SetWordWrap(eScrollDir == SCROLL_VERT);
+ ResetUpdate();
+}
+
+
+//************************************************************************
+//
+// CLCDScrollingText::GetScrollDirection
+//
+//************************************************************************
+
+CLCDScrollingText::eSCROLL_DIR CLCDScrollingText::GetScrollDirection()
+{
+ return m_eScrollDir;
+}
+
+
+//************************************************************************
+//
+// CLCDScrollingText::SetText
+//
+//************************************************************************
+
+void CLCDScrollingText::SetText(LPCTSTR szText)
+{
+ if (_tcscmp(szText, m_sText.c_str()))
+ {
+ ResetUpdate();
+ }
+
+ CLCDText::SetText(szText);
+}
+
+
+//************************************************************************
+//
+// CLCDScrollingText::IsScrollingDone
+//
+//************************************************************************
+
+BOOL CLCDScrollingText::IsScrollingDone()
+{
+ return (STATE_DONE == m_eState);
+}
+
+
+//************************************************************************
+//
+// CLCDScrollingText::EnableRepeat
+//
+//************************************************************************
+
+void CLCDScrollingText::EnableRepeat(BOOL bEnable)
+{
+ m_bRepeat = bEnable;
+}
+
+
+//************************************************************************
+//
+// CLCDScrollingText::OnUpdate
+//
+//************************************************************************
+
+void CLCDScrollingText::OnUpdate(DWORD dwTimestamp)
+{
+ m_dwEllapsedTime = (dwTimestamp - m_dwLastUpdate);
+}
+
+
+//************************************************************************
+//
+// CLCDScrollingText::OnDraw
+//
+//************************************************************************
+
+void CLCDScrollingText::OnDraw(CLCDGfx &rGfx)
+{
+ if (!m_nTextLength)
+ return;
+
+ // calculate the scrolling distance
+ if (-1 == m_nScrollingDistance)
+ {
+ CLCDText::OnDraw(rGfx);
+
+ if (SCROLL_VERT == m_eScrollDir)
+ {
+ // determine how far we have to travel until scrolling stops
+ m_nScrollingDistance = ((GetHeight()) >= GetVExtent().cy) ?
+ 0 : (GetVExtent().cy - GetHeight());
+ SetLogicalSize(GetVExtent().cx, GetVExtent().cy);
+ }
+ else
+ {
+ // determine how far we have to travel until scrolling stops
+ m_nScrollingDistance = ((GetWidth()) >= GetHExtent().cx) ?
+ 0 : (GetHExtent().cx - GetWidth());
+ SetLogicalSize(max(GetSize().cx, GetHExtent().cx), GetHExtent().cy);
+ }
+ }
+
+ switch(m_eState)
+ {
+ case STATE_START_DELAY:
+ if (m_dwEllapsedTime > m_dwStartDelay)
+ {
+ m_eState = STATE_SCROLL;
+ m_dwEllapsedTime = 0;
+ m_dwLastUpdate = GetTickCount();
+ }
+ break;
+ case STATE_END_DELAY:
+ if (m_dwEllapsedTime > m_dwEndDelay)
+ {
+ if (m_bRepeat)
+ {
+ ResetUpdate();
+ break;
+ }
+ m_dwEllapsedTime = 0;
+ m_dwLastUpdate = GetTickCount();
+ m_eState = STATE_DONE;
+ }
+ break;
+ case STATE_SCROLL:
+ {
+ // TODO: add some anti-aliasing on the movement
+
+ // how much time has ellapsed?
+ // given the speed, what is the total displacement?
+ float fDistance = (float)(m_dwSpeed * m_dwEllapsedTime) / 1000.0f;
+ m_fTotalDistance += fDistance;
+
+ // we dont want the total distnace exceed our scrolling distance
+ int nTotalOffset = min((int)m_fTotalDistance, m_nScrollingDistance);
+
+ if (SCROLL_VERT == m_eScrollDir)
+ {
+ SetLogicalOrigin(GetLogicalOrigin().x, -1 * nTotalOffset);
+ }
+ else
+ {
+ SetLogicalOrigin(-1 * nTotalOffset, GetLogicalOrigin().y);
+ }
+
+ m_dwLastUpdate = GetTickCount();
+
+ if (nTotalOffset == m_nScrollingDistance)
+ {
+ m_eState = STATE_END_DELAY;
+ }
+ }
+ break;
+ case STATE_DONE:
+ break;
+
+ default:
+ break;
+ }
+
+ CLCDText::OnDraw(rGfx);
+}
+
+
+//** end of LCDScrollingText.cpp *****************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDScrollingText.h b/src/thirdparty/ui/LCDUI/LCDScrollingText.h
new file mode 100644
index 000000000..8438c3952
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDScrollingText.h
@@ -0,0 +1,65 @@
+//************************************************************************
+//
+// LCDScrollingText.h
+//
+// The CLCDScrollingText class draws scrolling text onto the LCD.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#ifndef _LCDSCROLLINGTEXT_H_INCLUDED_
+#define _LCDSCROLLINGTEXT_H_INCLUDED_
+
+#include "LCDBase.h"
+#include "LCDText.h"
+
+class CLCDScrollingText : public CLCDText
+{
+public:
+ CLCDScrollingText();
+ virtual ~CLCDScrollingText();
+
+ // CLCDBase
+ virtual HRESULT Initialize(void);
+ virtual void ResetUpdate(void);
+
+ // CLCDText
+ virtual void SetText(LPCTSTR szText);
+
+ void SetStartDelay(DWORD dwMilliseconds);
+ void SetEndDelay(DWORD dwMilliseconds);
+ void EnableRepeat(BOOL bEnable);
+ void SetSpeed(DWORD dwSpeed);
+
+ enum eSCROLL_DIR { SCROLL_HORZ, SCROLL_VERT};
+ void SetScrollDirection(eSCROLL_DIR eScrollDir);
+ eSCROLL_DIR GetScrollDirection();
+ BOOL IsScrollingDone();
+
+protected:
+ virtual void OnUpdate(DWORD dwTimestamp);
+ virtual void OnDraw(CLCDGfx &rGfx);
+
+private:
+ enum eSCROLL_STATES { STATE_START_DELAY, STATE_SCROLL, STATE_END_DELAY, STATE_DONE};
+
+ DWORD m_dwEllapsedTime; // ellapsed time in state
+ DWORD m_dwStartDelay; // milliseconds
+ DWORD m_dwEndDelay; // milliseconds
+ DWORD m_dwSpeed; // pixels/second
+ DWORD m_dwLastUpdate; // milliseconds
+ BOOL m_bRepeat; // repeat
+
+ int m_nScrollingDistance;
+ float m_fTotalDistance;
+
+ eSCROLL_DIR m_eScrollDir;
+ eSCROLL_STATES m_eState;
+};
+
+
+#endif // !_LCDSCROLLINGTEXT_H_INCLUDED_
+
+//** end of LCDScrollingText.h *******************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDText.cpp b/src/thirdparty/ui/LCDUI/LCDText.cpp
new file mode 100644
index 000000000..e77282db2
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDText.cpp
@@ -0,0 +1,398 @@
+//************************************************************************
+//
+// LCDText.cpp
+//
+// The CLCDText class draws simple text onto the LCD.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#include "LCDText.h"
+
+
+//************************************************************************
+//
+// CLCDText::CLCDText
+//
+//************************************************************************
+
+CLCDText::CLCDText()
+{
+ m_nTextLength = 0;
+ m_hFont = NULL;
+ m_sText.erase(m_sText.begin(), m_sText.end());
+ m_crColor = RGB(255, 255, 255); // white
+ m_bRecalcExtent = TRUE;
+ ZeroMemory(&m_dtp, sizeof(DRAWTEXTPARAMS));
+ m_dtp.cbSize = sizeof(DRAWTEXTPARAMS);
+ m_nTextFormat = m_nTextAlignment = (DT_LEFT | DT_NOPREFIX);
+ m_nTextAlignment = DT_LEFT;
+ ZeroMemory(&m_sizeVExtent, sizeof(m_sizeVExtent));
+ ZeroMemory(&m_sizeHExtent, sizeof(m_sizeHExtent));
+}
+
+
+//************************************************************************
+//
+// CLCDText::~CLCDText
+//
+//************************************************************************
+
+CLCDText::~CLCDText()
+{
+
+ if (m_hFont)
+ {
+ DeleteObject(m_hFont);
+ m_hFont = NULL;
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDText::Initialize
+//
+//************************************************************************
+
+HRESULT CLCDText::Initialize()
+{
+
+ m_hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
+ if(NULL != m_hFont)
+ {
+ SetFontPointSize(DEFAULT_POINTSIZE);
+ }
+
+ return (NULL != m_hFont) ? S_OK : E_OUTOFMEMORY;
+}
+
+
+//************************************************************************
+//
+// CLCDText::SetFont
+//
+//************************************************************************
+
+void CLCDText::SetFont(LOGFONT& lf)
+{
+ if (m_hFont)
+ {
+ DeleteObject(m_hFont);
+ m_hFont = NULL;
+ }
+
+ m_hFont = CreateFontIndirect(&lf);
+ m_bRecalcExtent = TRUE;
+}
+
+
+//************************************************************************
+//
+// CLCDText::GetFont
+//
+//************************************************************************
+
+HFONT CLCDText::GetFont()
+{
+ return m_hFont;
+}
+
+
+//************************************************************************
+//
+// CLCDText::SetFontFaceName
+//
+//************************************************************************
+
+void CLCDText::SetFontFaceName(LPCTSTR szFontName)
+{
+ // if NULL, uses the default gui font
+ if (NULL == szFontName)
+ return;
+
+ LOGFONT lf;
+ ZeroMemory(&lf, sizeof(lf));
+ GetObject(m_hFont, sizeof(LOGFONT), &lf);
+
+ //_tcsncpy(lf.lfFaceName, szFontName, LF_FACESIZE);
+ //_tcsncpy_s(lf.lfFaceName, LF_FACESIZE, szFontName, LF_FACESIZE);
+ LCDUI_tcsncpy(lf.lfFaceName, szFontName, LF_FACESIZE);
+
+ SetFont(lf);
+}
+
+
+//************************************************************************
+//
+// CLCDText::SetFontPointSize
+//
+//************************************************************************
+
+void CLCDText::SetFontPointSize(int nPointSize)
+{
+ LOGFONT lf;
+ ZeroMemory(&lf, sizeof(lf));
+ GetObject(m_hFont, sizeof(LOGFONT), &lf);
+
+ lf.lfHeight = -MulDiv(nPointSize, DEFAULT_DPI, 72);
+
+ SetFont(lf);
+}
+
+
+//************************************************************************
+//
+// CLCDText::SetFontWeight
+//
+//************************************************************************
+
+void CLCDText::SetFontWeight(int nWeight)
+{
+ LOGFONT lf;
+ ZeroMemory(&lf, sizeof(lf));
+ GetObject(m_hFont, sizeof(LOGFONT), &lf);
+
+ lf.lfWeight = nWeight;
+
+ SetFont(lf);
+}
+
+
+//************************************************************************
+//
+// CLCDText::SetText
+//
+//************************************************************************
+
+void CLCDText::SetText(LPCTSTR szText)
+{
+ LCDUIASSERT(NULL != szText);
+ if(szText && _tcscmp(m_sText.c_str(), szText))
+ {
+ m_sText.assign(szText);
+ m_nTextLength = m_sText.size();
+ m_dtp.iLeftMargin = 0;
+ m_dtp.iRightMargin = 0;
+ m_bRecalcExtent = TRUE;
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDText::GetText
+//
+//************************************************************************
+
+LPCTSTR CLCDText::GetText()
+{
+ return m_sText.c_str();
+}
+
+
+//************************************************************************
+//
+// CLCDText::SetWordWrap
+//
+//************************************************************************
+
+void CLCDText::SetWordWrap(BOOL bEnable)
+{
+ if (bEnable)
+ {
+ m_nTextFormat |= DT_WORDBREAK;
+ }
+ else
+ {
+ m_nTextFormat &= ~DT_WORDBREAK;
+ }
+ m_bRecalcExtent = TRUE;
+}
+
+
+//************************************************************************
+//
+// CLCDText::SetLeftMargin
+//
+//************************************************************************
+
+void CLCDText::SetLeftMargin(int nLeftMargin)
+{
+ m_dtp.iLeftMargin = nLeftMargin;
+}
+
+
+//************************************************************************
+//
+// CLCDText::SetRightMargin
+//
+//************************************************************************
+
+void CLCDText::SetRightMargin(int nRightMargin)
+{
+ m_dtp.iRightMargin = nRightMargin;
+}
+
+
+//************************************************************************
+//
+// CLCDText::GetLeftMargin
+//
+//************************************************************************
+
+int CLCDText::GetLeftMargin(void)
+{
+ return m_dtp.iLeftMargin;
+}
+
+
+//************************************************************************
+//
+// CLCDText::GetRightMargin
+//
+//************************************************************************
+
+int CLCDText::GetRightMargin(void)
+{
+ return m_dtp.iRightMargin;
+}
+
+
+//************************************************************************
+//
+// CLCDText::GetVExtent
+//
+//************************************************************************
+
+SIZE& CLCDText::GetVExtent()
+{
+ return m_sizeVExtent;
+}
+
+
+//************************************************************************
+//
+// CLCDText::GetHExtent
+//
+//************************************************************************
+
+SIZE& CLCDText::GetHExtent()
+{
+ return m_sizeHExtent;
+}
+
+
+//************************************************************************
+//
+// CLCDText::SetAlignment
+//
+//************************************************************************
+
+void CLCDText::SetAlignment(int nAlignment)
+{
+ m_nTextFormat &= ~m_nTextAlignment;
+ m_nTextFormat |= nAlignment;
+ m_nTextAlignment = nAlignment;
+}
+
+
+//************************************************************************
+//
+// CLCDText::DrawText
+//
+//************************************************************************
+
+void CLCDText::DrawText(CLCDGfx &rGfx)
+{
+ // draw the text
+ RECT rBoundary = { 0, 0,0 + GetLogicalSize().cx, 0 + GetLogicalSize().cy };
+ DrawTextEx(rGfx.GetHDC(), (LPTSTR)m_sText.c_str(), static_cast<int>(m_nTextLength), &rBoundary, m_nTextFormat, &m_dtp);
+
+// LCDUITRACE(_T("Drawing %s at (%d,%d)-(%d-%d) lmargin=%d, rmargin=%d\n"),
+// m_sText.c_str(), m_Origin.x, m_Origin.y, GetWidth(), GetHeight(),
+// m_dtp.iLeftMargin, m_dtp.iRightMargin);
+
+ if (m_bInverted)
+ {
+ InvertRect(rGfx.GetHDC(), &rBoundary);
+ }
+}
+
+
+//************************************************************************
+//
+// CLCDText::OnDraw
+//
+//************************************************************************
+
+void CLCDText::OnDraw(CLCDGfx &rGfx)
+{
+
+ if (GetBackgroundMode() == OPAQUE)
+ {
+ // clear the clipped area
+ RECT rcClp = { 0, 0, m_Size.cx, m_Size.cy };
+ FillRect(rGfx.GetHDC(), &rcClp, (HBRUSH) GetStockObject(BLACK_BRUSH));
+
+ // clear the logical area
+ RECT rcLog = { 0, 0, m_sizeLogical.cx, m_sizeLogical.cy };
+ FillRect(rGfx.GetHDC(), &rcLog, (HBRUSH) GetStockObject(BLACK_BRUSH));
+ }
+
+ if (m_nTextLength)
+ {
+
+ // map mode text, with transparency
+ int nOldMapMode = SetMapMode(rGfx.GetHDC(), MM_TEXT);
+ int nOldBkMode = SetBkMode(rGfx.GetHDC(), GetBackgroundMode());
+
+ // select current font
+ HFONT hOldFont = (HFONT)SelectObject(rGfx.GetHDC(), m_hFont);
+
+ // select color
+ COLORREF crOldTextColor = SetTextColor(rGfx.GetHDC(), m_crColor);
+
+ if (m_bRecalcExtent)
+ {
+ int nTextFormat;
+
+ RECT rExtent;
+ // calculate vertical extent with word wrap
+ nTextFormat = (m_nTextFormat | DT_WORDBREAK | DT_CALCRECT);
+ rExtent.left = rExtent.top = 0;
+ rExtent.right = GetWidth();
+ rExtent.bottom = GetHeight();
+ DrawTextEx(rGfx.GetHDC(), (LPTSTR)m_sText.c_str(), static_cast<int>(m_nTextLength), &rExtent, nTextFormat, &m_dtp);
+ m_sizeVExtent.cx = rExtent.right;
+ m_sizeVExtent.cy = rExtent.bottom;
+
+ // calculate horizontal extent w/o word wrap
+ nTextFormat = (m_nTextFormat | DT_CALCRECT);
+ rExtent.left = rExtent.top = 0;
+ rExtent.right = GetWidth();
+ rExtent.bottom = GetHeight();
+ DrawTextEx(rGfx.GetHDC(), (LPTSTR)m_sText.c_str(), static_cast<int>(m_nTextLength), &rExtent, nTextFormat, &m_dtp);
+ m_sizeHExtent.cx = rExtent.right;
+ m_sizeHExtent.cy = rExtent.bottom;
+
+ m_bRecalcExtent = FALSE;
+ }
+
+ if (IsVisible())
+ {
+ DrawText(rGfx);
+ }
+
+ // restores
+ SetMapMode(rGfx.GetHDC(), nOldMapMode);
+ SetTextColor(rGfx.GetHDC(), crOldTextColor);
+ SetBkMode(rGfx.GetHDC(), nOldBkMode);
+ SelectObject(rGfx.GetHDC(), hOldFont);
+ }
+}
+
+//** end of LCDText.cpp **************************************************
+
diff --git a/src/thirdparty/ui/LCDUI/LCDText.h b/src/thirdparty/ui/LCDUI/LCDText.h
new file mode 100644
index 000000000..3a74f746f
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDText.h
@@ -0,0 +1,71 @@
+//************************************************************************
+//
+// LCDText.h
+//
+// The CLCDText class draws simple text onto the LCD.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#ifndef _LCDTEXT_H_INCLUDED_
+#define _LCDTEXT_H_INCLUDED_
+
+#include "LCDBase.h"
+
+#include <string>
+using namespace std;
+
+class CLCDText : public CLCDBase
+{
+
+public:
+ CLCDText();
+ virtual ~CLCDText();
+
+ virtual HRESULT Initialize(void);
+
+ virtual void SetFont(LOGFONT& lf);
+ virtual void SetFontFaceName(LPCTSTR szFontName);
+ virtual void SetFontPointSize(int nPointSize);
+ virtual void SetFontWeight(int nWeight);
+
+ virtual HFONT GetFont();
+ virtual void SetText(LPCTSTR szText);
+ virtual LPCTSTR GetText();
+ virtual void SetWordWrap(BOOL bEnable);
+ virtual SIZE& GetVExtent();
+ virtual SIZE& GetHExtent();
+ virtual void SetLeftMargin(int nLeftMargin);
+ virtual int GetLeftMargin(void);
+ virtual void SetRightMargin(int nRightMargin);
+ virtual int GetRightMargin(void);
+ virtual void SetAlignment(int nAlignment = DT_LEFT);
+
+ virtual void OnDraw(CLCDGfx &rGfx);
+
+ enum { DEFAULT_DPI = 96, DEFAULT_POINTSIZE = 8 };
+
+protected:
+ void DrawText(CLCDGfx &rGfx);
+
+#ifdef UNICODE
+ std::wstring m_sText;
+#else
+ std::string m_sText;
+#endif
+ HFONT m_hFont;
+ COLORREF m_crColor;
+ basic_string <TCHAR>::size_type m_nTextLength;
+ UINT m_nTextFormat;
+ BOOL m_bRecalcExtent;
+ DRAWTEXTPARAMS m_dtp;
+ int m_nTextAlignment;
+ SIZE m_sizeVExtent, m_sizeHExtent;
+};
+
+
+#endif // !_LCDTEXT_H_INCLUDED_
+
+//** end of LCDText.h ****************************************************
diff --git a/src/thirdparty/ui/LCDUI/LCDUI.vcproj b/src/thirdparty/ui/LCDUI/LCDUI.vcproj
new file mode 100644
index 000000000..568a4a72d
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDUI.vcproj
@@ -0,0 +1,351 @@
+<?xml version="1.0" encoding="Windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="LCDUI"
+ ProjectGUID="{476B97B4-F079-4A44-AF89-52CA30C35E28}"
+ RootNamespace="LCDUI"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\debug.vsprops"
+ UseOfMFC="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\..\..\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalDependencies="lgLcd.lib"
+ AdditionalLibraryDirectories="$(SolutionDir)lib\lglcd"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\debug.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\..\..\include"
+ PreprocessorDefinitions="_WIN64;_DEBUG;_LIB"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalDependencies="lgLcd.lib"
+ AdditionalLibraryDirectories="$(SolutionDir)lib64\lglcd"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\release.vsprops"
+ UseOfMFC="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\..\..\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalDependencies="lgLcd.lib"
+ AdditionalLibraryDirectories="$(SolutionDir)lib\lglcd"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\release.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\..\..\include"
+ PreprocessorDefinitions="_WIN64;NDEBUG;_LIB"
+ EnableEnhancedInstructionSet="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalDependencies="lgLcd.lib"
+ AdditionalLibraryDirectories="$(SolutionDir)lib64\lglcd"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\LCDAnimatedBitmap.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDBase.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDBitmap.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDCollection.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDGfx.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDManager.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDOutput.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDProgressBar.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDScrollingText.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDText.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\LCDAnimatedBitmap.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDBase.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDBitmap.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDCollection.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDGfx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDManager.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDOutput.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDProgressBar.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDScrollingText.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDText.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/thirdparty/ui/LCDUI/LCDUI.vcxproj b/src/thirdparty/ui/LCDUI/LCDUI.vcxproj
new file mode 100644
index 000000000..7f341aa93
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDUI.vcxproj
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{476B97B4-F079-4A44-AF89-52CA30C35E28}</ProjectGuid>
+ <RootNamespace>LCDUI</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>Static</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>Static</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\debug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\debug.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Lib>
+ <TargetMachine>MachineX86</TargetMachine>
+ <AdditionalDependencies>lgLcd.lib</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(SolutionDir)lib\lglcd</AdditionalLibraryDirectories>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Lib>
+ <TargetMachine>MachineX64</TargetMachine>
+ <AdditionalDependencies>lgLcd.lib</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(SolutionDir)lib64\lglcd</AdditionalLibraryDirectories>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Lib>
+ <TargetMachine>MachineX86</TargetMachine>
+ <AdditionalDependencies>lgLcd.lib</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(SolutionDir)lib\lglcd</AdditionalLibraryDirectories>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ </ClCompile>
+ <Lib>
+ <TargetMachine>MachineX64</TargetMachine>
+ <AdditionalDependencies>lgLcd.lib</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(SolutionDir)lib64\lglcd</AdditionalLibraryDirectories>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="LCDAnimatedBitmap.cpp" />
+ <ClCompile Include="LCDBase.cpp" />
+ <ClCompile Include="LCDBitmap.cpp" />
+ <ClCompile Include="LCDCollection.cpp" />
+ <ClCompile Include="LCDGfx.cpp" />
+ <ClCompile Include="LCDManager.cpp" />
+ <ClCompile Include="LCDOutput.cpp" />
+ <ClCompile Include="LCDProgressBar.cpp" />
+ <ClCompile Include="LCDScrollingText.cpp" />
+ <ClCompile Include="LCDText.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="LCDAnimatedBitmap.h" />
+ <ClInclude Include="LCDBase.h" />
+ <ClInclude Include="LCDBitmap.h" />
+ <ClInclude Include="LCDCollection.h" />
+ <ClInclude Include="LCDGfx.h" />
+ <ClInclude Include="LCDManager.h" />
+ <ClInclude Include="LCDOutput.h" />
+ <ClInclude Include="LCDProgressBar.h" />
+ <ClInclude Include="LCDScrollingText.h" />
+ <ClInclude Include="LCDText.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/src/thirdparty/ui/LCDUI/LCDUI.vcxproj.filters b/src/thirdparty/ui/LCDUI/LCDUI.vcxproj.filters
new file mode 100644
index 000000000..74777ef58
--- /dev/null
+++ b/src/thirdparty/ui/LCDUI/LCDUI.vcxproj.filters
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="LCDAnimatedBitmap.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="LCDBase.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="LCDBitmap.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="LCDCollection.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="LCDGfx.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="LCDManager.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="LCDOutput.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="LCDProgressBar.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="LCDScrollingText.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="LCDText.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="LCDAnimatedBitmap.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="LCDBase.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="LCDBitmap.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="LCDCollection.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="LCDGfx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="LCDManager.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="LCDOutput.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="LCDProgressBar.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="LCDScrollingText.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="LCDText.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project>
diff --git a/src/thirdparty/ui/ResizableLib/Artistic-License.txt b/src/thirdparty/ui/ResizableLib/Artistic-License.txt
new file mode 100644
index 000000000..803d2293e
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/Artistic-License.txt
@@ -0,0 +1,99 @@
+The Artistic License
+
+Preamble
+
+The intent of this document is to state the conditions under which a Package
+may be copied, such that the Copyright Holder maintains some semblance of
+artistic control over the development of the package, while giving the users of
+the package the right to use and distribute the Package in a more-or-less
+customary fashion, plus the right to make reasonable modifications.
+
+Definitions:
+
+ * "Package" refers to the collection of files distributed by the Copyright
+ Holder, and derivatives of that collection of files created through textual
+ modification.
+ * "Standard Version" refers to such a Package if it has not been modified,
+ or has been modified in accordance with the wishes of the Copyright Holder.
+ * "Copyright Holder" is whoever is named in the copyright or copyrights for
+ the package.
+ * "You" is you, if you're thinking about copying or distributing this
+ Package.
+ * "Reasonable copying fee" is whatever you can justify on the basis of media
+ cost, duplication charges, time of people involved, and so on. (You will not
+ be required to justify it to the Copyright Holder, but only to the computing
+ community at large as a market that must bear the fee.)
+ * "Freely Available" means that no fee is charged for the item itself,
+ though there may be fees involved in handling the item. It also means that
+ recipients of the item may redistribute it under the same conditions they
+ received it.
+
+1. You may make and give away verbatim copies of the source form of the
+ Standard Version of this Package without restriction, provided that you
+ duplicate all of the original copyright notices and associated disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications derived
+ from the Public Domain or from the Copyright Holder. A Package modified in such
+ a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way, provided
+ that you insert a prominent notice in each changed file stating how and when you
+ changed that file, and provided that you do at least ONE of the following:
+
+ a) place your modifications in the Public Domain or otherwise make them
+ Freely Available, such as by posting said modifications to Usenet or an
+ equivalent medium, or placing the modifications on a major archive site such
+ as ftp.uu.net, or by allowing the Copyright Holder to include your
+ modifications in the Standard Version of the Package.
+
+ b) use the modified Package only within your corporation or
+ organization.
+
+ c) rename any non-standard executables so the names do not conflict with
+ standard executables, which must also be provided, and provide a separate
+ manual page for each non-standard executable that clearly documents how it
+ differs from the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or
+ executable form, provided that you do at least ONE of the following:
+
+ a) distribute a Standard Version of the executables and library files,
+ together with instructions (in the manual page or equivalent) on where to get
+ the Standard Version.
+
+ b) accompany the distribution with the machine-readable source of the
+ Package with your modifications.
+
+ c) accompany any non-standard executables with their corresponding Standard
+ Version executables, giving the non-standard executables non-standard names,
+ and clearly documenting the differences in manual pages (or equivalent),
+ together with instructions on where to get the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+ Package. You may charge any fee you choose for support of this Package. You may
+ not charge a fee for this Package itself. However, you may distribute this
+ Package in aggregate with other (possibly commercial) programs as part of a
+ larger (possibly commercial) software distribution provided that you do not
+ advertise this Package as a product of your own.
+
+6. The scripts and library files supplied as input to or produced as output
+ from the programs of this Package do not automatically fall under the copyright
+ of this Package, but belong to whomever generated them, and may be sold
+ commercially, and may be aggregated with this Package.
+
+7. C or perl subroutines supplied by you and linked into this Package shall
+ not be considered part of this Package.
+
+8. The name of the Copyright Holder may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+The End
diff --git a/src/thirdparty/ui/ResizableLib/ResizableDialog.cpp b/src/thirdparty/ui/ResizableLib/ResizableDialog.cpp
new file mode 100644
index 000000000..af9d16b97
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableDialog.cpp
@@ -0,0 +1,155 @@
+// ResizableDialog.cpp : implementation file
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "ResizableDialog.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// CResizableDialog
+
+inline void CResizableDialog::PrivateConstruct()
+{
+ m_bEnableSaveRestore = FALSE;
+ m_dwGripTempState = 1;
+}
+
+CResizableDialog::CResizableDialog()
+{
+ PrivateConstruct();
+}
+
+CResizableDialog::CResizableDialog(UINT nIDTemplate, CWnd* pParentWnd)
+ : CCmdUIDialog(nIDTemplate, pParentWnd)
+{
+ PrivateConstruct();
+}
+
+CResizableDialog::CResizableDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd)
+ : CCmdUIDialog(lpszTemplateName, pParentWnd)
+{
+ PrivateConstruct();
+}
+
+CResizableDialog::~CResizableDialog()
+{
+}
+
+
+BEGIN_MESSAGE_MAP(CResizableDialog, CCmdUIDialog)
+ //{{AFX_MSG_MAP(CResizableDialog)
+ ON_WM_GETMINMAXINFO()
+ ON_WM_SIZE()
+ ON_WM_DESTROY()
+ ON_WM_CREATE()
+ ON_WM_ERASEBKGND()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CResizableDialog message handlers
+
+int CResizableDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (__super::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ // child dialogs don't want resizable border or size grip,
+ // nor they can handle the min/max size constraints
+ BOOL bChild = GetStyle() & WS_CHILD;
+
+ if (!bChild)
+ {
+ // keep client area
+ CRect rect;
+ GetClientRect(&rect);
+ // set resizable style
+ ModifyStyle(DS_MODALFRAME, WS_POPUP | WS_THICKFRAME);
+ // adjust size to reflect new style
+ ::AdjustWindowRectEx(&rect, GetStyle(),
+ ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());
+ SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(), SWP_FRAMECHANGED|
+ SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREPOSITION);
+
+ // set the initial size as the min track size
+ SetMinTrackSize(rect.Size());
+ }
+
+ // create and init the size-grip
+ if (!CreateSizeGrip(!bChild))
+ return -1;
+
+ return 0;
+}
+
+void CResizableDialog::OnDestroy()
+{
+ if (m_bEnableSaveRestore)
+ SaveWindowRect(m_sSection, m_bRectOnly);
+
+ // remove child windows
+ RemoveAllAnchors();
+
+ __super::OnDestroy();
+}
+
+void CResizableDialog::OnSize(UINT nType, int cx, int cy)
+{
+ CWnd::OnSize(nType, cx, cy);
+
+ if (nType == SIZE_MAXHIDE || nType == SIZE_MAXSHOW)
+ return; // arrangement not needed
+
+ if (nType == SIZE_MAXIMIZED)
+ HideSizeGrip(&m_dwGripTempState);
+ else
+ ShowSizeGrip(&m_dwGripTempState);
+
+ // update grip and layout
+ UpdateSizeGrip();
+ ArrangeLayout();
+}
+
+void CResizableDialog::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
+{
+ MinMaxInfo(lpMMI);
+}
+
+// NOTE: this must be called after setting the layout
+// to have the dialog and its controls displayed properly
+void CResizableDialog::EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly)
+{
+ m_sSection = pszSection;
+
+ m_bEnableSaveRestore = TRUE;
+ m_bRectOnly = bRectOnly;
+
+ // restore immediately
+ LoadWindowRect(pszSection, bRectOnly);
+}
+
+
+BOOL CResizableDialog::OnEraseBkgnd(CDC* pDC)
+{
+ // Windows XP doesn't like clipping regions ...try this!
+ EraseBackground(pDC);
+ return TRUE;
+
+/* ClipChildren(pDC); // old-method (for safety)
+
+ return CDialog::OnEraseBkgnd(pDC);
+*/
+}
diff --git a/src/thirdparty/ui/ResizableLib/ResizableDialog.h b/src/thirdparty/ui/ResizableLib/ResizableDialog.h
new file mode 100644
index 000000000..d00efefc8
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableDialog.h
@@ -0,0 +1,101 @@
+#if !defined(AFX_RESIZABLEDIALOG_H__INCLUDED_)
+#define AFX_RESIZABLEDIALOG_H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+// ResizableDialog.h : header file
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "ResizableLayout.h"
+#include "ResizableGrip.h"
+#include "ResizableMinMax.h"
+#include "ResizableState.h"
+#include "../../../CmdUI/CmdUI.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// CResizableDialog window
+
+class CResizableDialog : public CCmdUIDialog, public CResizableLayout,
+ public CResizableGrip, public CResizableMinMax,
+ public CResizableState
+{
+
+// Construction
+public:
+ CResizableDialog();
+ CResizableDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL);
+ CResizableDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL);
+
+// Attributes
+private:
+ // support for temporarily hiding the grip
+ DWORD m_dwGripTempState;
+
+ // flags
+ BOOL m_bEnableSaveRestore;
+ BOOL m_bRectOnly;
+
+ // internal status
+ CString m_sSection; // section name (identifies a parent window)
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CResizableDialog)
+ protected:
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~CResizableDialog();
+
+// used internally
+private:
+ void PrivateConstruct();
+
+// callable from derived classes
+protected:
+ // section to use in app's profile
+ void EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly = FALSE);
+
+ virtual CWnd* GetResizableWnd()
+ {
+ // make the layout know its parent window
+ return this;
+ };
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CResizableDialog)
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnDestroy();
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_RESIZABLEDIALOG_H__INCLUDED_)
diff --git a/src/thirdparty/ui/ResizableLib/ResizableGrip.cpp b/src/thirdparty/ui/ResizableLib/ResizableGrip.cpp
new file mode 100644
index 000000000..d1551ce6b
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableGrip.cpp
@@ -0,0 +1,304 @@
+// ResizableGrip.cpp: implementation of the CResizableGrip class.
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "ResizableGrip.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CResizableGrip::CResizableGrip()
+{
+ m_nShowCount = 0;
+}
+
+CResizableGrip::~CResizableGrip()
+{
+
+}
+
+void CResizableGrip::UpdateSizeGrip()
+{
+ ASSERT(::IsWindow(m_wndGrip.m_hWnd));
+
+ // size-grip goes bottom right in the client area
+ // (any right-to-left adjustment should go here)
+
+ RECT rect;
+ GetResizableWnd()->GetClientRect(&rect);
+
+ rect.left = rect.right - m_wndGrip.m_size.cx;
+ rect.top = rect.bottom - m_wndGrip.m_size.cy;
+
+ // must stay below other children
+ m_wndGrip.SetWindowPos(&CWnd::wndBottom, rect.left, rect.top, 0, 0,
+ SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREPOSITION
+ | (IsSizeGripVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
+}
+
+// pbStatus points to a variable, maintained by the caller, that
+// holds its visibility status. Initialize the variable with 1
+// to allow to temporarily hide the grip, 0 to allow to
+// temporarily show the grip (with respect to the dwMask bit).
+
+// NB: visibility is effective only after an update
+
+void CResizableGrip::ShowSizeGrip(DWORD* pStatus, DWORD dwMask /*= 1*/)
+{
+ ASSERT(pStatus != NULL);
+
+ if (!(*pStatus & dwMask))
+ {
+ m_nShowCount++;
+ (*pStatus) |= dwMask;
+ }
+}
+
+void CResizableGrip::HideSizeGrip(DWORD* pStatus, DWORD dwMask /*= 1*/)
+{
+ ASSERT(pStatus != NULL);
+
+ if (*pStatus & dwMask)
+ {
+ m_nShowCount--;
+ (*pStatus) &= ~dwMask;
+ }
+}
+
+BOOL CResizableGrip::IsSizeGripVisible()
+{
+ // NB: visibility is effective only after an update
+ return (m_nShowCount > 0);
+}
+
+void CResizableGrip::SetSizeGripVisibility(BOOL bVisible)
+{
+ if (bVisible)
+ m_nShowCount = 1;
+ else
+ m_nShowCount = 0;
+}
+
+BOOL CResizableGrip::SetSizeGripBkMode(int nBkMode)
+{
+ if (::IsWindow(m_wndGrip.m_hWnd))
+ {
+ if (nBkMode == OPAQUE)
+ m_wndGrip.SetTransparency(FALSE);
+ else if (nBkMode == TRANSPARENT)
+ m_wndGrip.SetTransparency(TRUE);
+ else
+ return FALSE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CResizableGrip::SetSizeGripShape(BOOL bTriangular)
+{
+ m_wndGrip.SetTriangularShape(bTriangular);
+}
+
+BOOL CResizableGrip::CreateSizeGrip(BOOL bVisible /*= TRUE*/,
+ BOOL bTriangular /*= TRUE*/, BOOL bTransparent /*= FALSE*/)
+{
+ // create grip
+ CRect rect(0 , 0, m_wndGrip.m_size.cx, m_wndGrip.m_size.cy);
+ BOOL bRet = m_wndGrip.Create(WS_CHILD | WS_CLIPSIBLINGS
+ | SBS_SIZEGRIP, rect, GetResizableWnd(), 0);
+
+ if (bRet)
+ {
+ // set options
+ m_wndGrip.SetTriangularShape(bTriangular);
+ m_wndGrip.SetTransparency(bTransparent);
+ SetSizeGripVisibility(bVisible);
+
+ // update position
+ UpdateSizeGrip();
+ }
+
+ return bRet;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CSizeGrip implementation
+
+BOOL CResizableGrip::CSizeGrip::IsRTL()
+{
+ return GetExStyle() & 0x00400000L/*WS_EX_LAYOUTRTL*/;
+}
+
+BOOL CResizableGrip::CSizeGrip::PreCreateWindow(CREATESTRUCT& cs)
+{
+ // set window size
+ m_size.cx = GetSystemMetrics(SM_CXVSCROLL);
+ m_size.cy = GetSystemMetrics(SM_CYHSCROLL);
+
+ cs.cx = m_size.cx;
+ cs.cy = m_size.cy;
+
+ return CScrollBar::PreCreateWindow(cs);
+}
+
+LRESULT CResizableGrip::CSizeGrip::WindowProc(UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_GETDLGCODE:
+ // fix to prevent the control to gain focus, using arrow keys
+ // (standard grip returns DLGC_WANTARROWS, like any standard scrollbar)
+ return DLGC_STATIC;
+
+ case WM_NCHITTEST:
+ // choose proper cursor shape
+ if (IsRTL())
+ return HTBOTTOMLEFT;
+ else
+ return HTBOTTOMRIGHT;
+ break;
+
+ case WM_SETTINGCHANGE:
+ {
+ // update grip's size
+ CSize sizeOld = m_size;
+ m_size.cx = GetSystemMetrics(SM_CXVSCROLL);
+ m_size.cy = GetSystemMetrics(SM_CYHSCROLL);
+
+ // resize transparency bitmaps
+ if (m_bTransparent)
+ {
+ CClientDC dc(this);
+
+ // destroy bitmaps
+ m_bmGrip.DeleteObject();
+ m_bmMask.DeleteObject();
+
+ // re-create bitmaps
+ m_bmGrip.CreateCompatibleBitmap(&dc, m_size.cx, m_size.cy);
+ m_bmMask.CreateBitmap(m_size.cx, m_size.cy, 1, 1, NULL);
+ }
+
+ // re-calc shape
+ if (m_bTriangular)
+ SetTriangularShape(m_bTriangular);
+
+ // reposition the grip
+ CRect rect;
+ GetWindowRect(rect);
+ rect.InflateRect(m_size.cx - sizeOld.cx, m_size.cy - sizeOld.cy, 0, 0);
+ ::MapWindowPoints(NULL, GetParent()->GetSafeHwnd(), (LPPOINT)&rect, 2);
+ MoveWindow(rect, TRUE);
+ }
+ break;
+
+ case WM_DESTROY:
+ // perform clean up
+ if (m_bTransparent)
+ SetTransparency(FALSE);
+ break;
+
+ case WM_PAINT:
+ if (m_bTransparent)
+ {
+ CPaintDC dc(this);
+
+ // select bitmaps
+ CBitmap *pOldGrip, *pOldMask;
+
+ pOldGrip = m_dcGrip.SelectObject(&m_bmGrip);
+ pOldMask = m_dcMask.SelectObject(&m_bmMask);
+
+ // obtain original grip bitmap, make the mask and prepare masked bitmap
+ CScrollBar::WindowProc(WM_PAINT, (WPARAM)m_dcGrip.GetSafeHdc(), lParam);
+ m_dcGrip.SetBkColor(m_dcGrip.GetPixel(0, 0));
+ m_dcMask.BitBlt(0, 0, m_size.cx, m_size.cy, &m_dcGrip, 0, 0, SRCCOPY);
+ m_dcGrip.BitBlt(0, 0, m_size.cx, m_size.cy, &m_dcMask, 0, 0, 0x00220326);
+
+ // draw transparently
+ dc.BitBlt(0, 0, m_size.cx, m_size.cy, &m_dcMask, 0, 0, SRCAND);
+ dc.BitBlt(0, 0, m_size.cx, m_size.cy, &m_dcGrip, 0, 0, SRCPAINT);
+
+ // unselect bitmaps
+ m_dcGrip.SelectObject(pOldGrip);
+ m_dcMask.SelectObject(pOldMask);
+
+ return 0;
+ }
+ break;
+ }
+
+ return CScrollBar::WindowProc(message, wParam, lParam);
+}
+
+void CResizableGrip::CSizeGrip::SetTransparency(BOOL bActivate)
+{
+ // creates or deletes DCs and Bitmaps used for
+ // implementing a transparent size grip
+
+ if (bActivate && !m_bTransparent)
+ {
+ m_bTransparent = TRUE;
+
+ CClientDC dc(this);
+
+ // create memory DCs and bitmaps
+ m_dcGrip.CreateCompatibleDC(&dc);
+ m_bmGrip.CreateCompatibleBitmap(&dc, m_size.cx, m_size.cy);
+
+ m_dcMask.CreateCompatibleDC(&dc);
+ m_bmMask.CreateBitmap(m_size.cx, m_size.cy, 1, 1, NULL);
+ }
+ else if (!bActivate && m_bTransparent)
+ {
+ m_bTransparent = FALSE;
+
+ // destroy memory DCs and bitmaps
+ m_dcGrip.DeleteDC();
+ m_bmGrip.DeleteObject();
+
+ m_dcMask.DeleteDC();
+ m_bmMask.DeleteObject();
+ }
+}
+
+void CResizableGrip::CSizeGrip::SetTriangularShape(BOOL bEnable)
+{
+ m_bTriangular = bEnable;
+
+ if (bEnable)
+ {
+ // set a triangular window region
+ CRect rect;
+ GetWindowRect(rect);
+ rect.OffsetRect(-rect.TopLeft());
+ POINT arrPoints[] =
+ {
+ { rect.left, rect.bottom },
+ { rect.right, rect.bottom },
+ { rect.right, rect.top }
+ };
+ CRgn rgnGrip;
+ rgnGrip.CreatePolygonRgn(arrPoints, 3, WINDING);
+ SetWindowRgn((HRGN)rgnGrip.Detach(), IsWindowVisible());
+ }
+ else
+ {
+ SetWindowRgn((HRGN)NULL, IsWindowVisible());
+ }
+}
diff --git a/src/thirdparty/ui/ResizableLib/ResizableGrip.h b/src/thirdparty/ui/ResizableLib/ResizableGrip.h
new file mode 100644
index 000000000..0a85514b9
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableGrip.h
@@ -0,0 +1,81 @@
+// ResizableGrip.h: interface for the CResizableGrip class.
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_RESIZABLEGRIP_H__INCLUDED_)
+#define AFX_RESIZABLEGRIP_H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+class CResizableGrip
+{
+private:
+ class CSizeGrip : public CScrollBar
+ {
+ public:
+ CSizeGrip()
+ {
+ m_bTransparent = FALSE;
+ m_bTriangular = FALSE;
+ m_size.cx = 0;
+ m_size.cy = 0;
+ }
+
+ void SetTriangularShape(BOOL bEnable);
+ void SetTransparency(BOOL bActivate);
+
+ BOOL IsRTL(); // right-to-left layout support
+
+ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
+
+ SIZE m_size; // holds grip size
+
+ protected:
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+
+ BOOL m_bTriangular; // triangular shape active
+ BOOL m_bTransparent; // transparency active
+
+ // memory DCs and bitmaps for transparent grip
+ CDC m_dcGrip, m_dcMask;
+ CBitmap m_bmGrip, m_bmMask;
+ };
+
+ CSizeGrip m_wndGrip; // grip control
+ int m_nShowCount; // support for hiding the grip
+
+protected:
+ // create a size grip, with options
+ BOOL CreateSizeGrip(BOOL bVisible = TRUE,
+ BOOL bTriangular = TRUE, BOOL bTransparent = FALSE);
+
+ BOOL IsSizeGripVisible(); // TRUE if grip is set to be visible
+ void SetSizeGripVisibility(BOOL bVisible); // set default visibility
+ void UpdateSizeGrip(); // update the grip's visibility and position
+ void ShowSizeGrip(DWORD* pStatus, DWORD dwMask = 1); // temp show the size grip
+ void HideSizeGrip(DWORD* pStatus, DWORD dwMask = 1); // temp hide the size grip
+ BOOL SetSizeGripBkMode(int nBkMode); // like CDC::SetBkMode
+ void SetSizeGripShape(BOOL bTriangular);
+
+ virtual CWnd* GetResizableWnd() = 0;
+
+public:
+ CResizableGrip();
+ virtual ~CResizableGrip();
+};
+
+#endif // !defined(AFX_RESIZABLEGRIP_H__INCLUDED_)
diff --git a/src/thirdparty/ui/ResizableLib/ResizableLayout.cpp b/src/thirdparty/ui/ResizableLib/ResizableLayout.cpp
new file mode 100644
index 000000000..750404b02
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableLayout.cpp
@@ -0,0 +1,516 @@
+// ResizableLayout.cpp: implementation of the CResizableLayout class.
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "commctrl.h"
+#include "ResizableLayout.h"
+#include "ResizableMsgSupport.inl"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+// In August 2002 Platform SDK, some guy at MS thought it was time to
+// add the missing symbol BS_TYPEMASK, but forgot its original meaning
+// and so now he's telling us not to use that symbol because its
+// value is likely to change in the future SDK releases, including all
+// the BS_* style bits in the mask, not just the button's type as the
+// symbol's name suggests. So now we're forced to use another symbol!
+#define _BS_TYPEMASK 0x0000000FL
+
+void CResizableLayout::AddAnchor(HWND hWnd, CSize sizeTypeTL, CSize sizeTypeBR)
+{
+ CWnd* pParent = GetResizableWnd();
+
+ // child window must be valid
+ ASSERT(::IsWindow(hWnd));
+ // must be child of parent window
+// ASSERT(::IsChild(pParent->GetSafeHwnd(), hWnd));
+ // top-left anchor must be valid
+ ASSERT(sizeTypeTL != NOANCHOR);
+
+ // get control's window class
+ CString sClassName;
+ GetClassName(hWnd, sClassName.GetBufferSetLength(MAX_PATH), MAX_PATH);
+ sClassName.ReleaseBuffer();
+
+ // get parent window's rect
+ CRect rectParent;
+ GetTotalClientRect(&rectParent);
+ // and child control's rect
+ CRect rectChild;
+ ::GetWindowRect(hWnd, &rectChild);
+ ::MapWindowPoints(NULL, pParent->m_hWnd, (LPPOINT)&rectChild, 2);
+
+ // adjust position, if client area has been scrolled
+ rectChild.OffsetRect(-rectParent.TopLeft());
+
+ // go calculate margins
+ CSize sizeMarginTL, sizeMarginBR;
+
+ if (sizeTypeBR == NOANCHOR)
+ sizeTypeBR = sizeTypeTL;
+
+ // calculate margin for the top-left corner
+
+ sizeMarginTL.cx = rectChild.left - rectParent.Width() * sizeTypeTL.cx / 100;
+ sizeMarginTL.cy = rectChild.top - rectParent.Height() * sizeTypeTL.cy / 100;
+
+ // calculate margin for the bottom-right corner
+
+ sizeMarginBR.cx = rectChild.right - rectParent.Width() * sizeTypeBR.cx / 100;
+ sizeMarginBR.cy = rectChild.bottom - rectParent.Height() * sizeTypeBR.cy / 100;
+
+ // prepare the structure
+ LayoutInfo layout(hWnd, sizeTypeTL, sizeMarginTL,
+ sizeTypeBR, sizeMarginBR, sClassName);
+
+ // initialize resize properties (overridable)
+ InitResizeProperties(layout);
+
+ // must not be already there!
+ // (this is probably due to a duplicate call to AddAnchor)
+ POSITION pos;
+ ASSERT(!m_mapLayout.Lookup(hWnd, pos));
+
+ // add to the list and the map
+ pos = m_listLayout.AddTail(layout);
+ m_mapLayout.SetAt(hWnd, pos);
+}
+
+void CResizableLayout::AddAnchorCallback(UINT nCallbackID)
+{
+ // one callback control cannot rely upon another callback control's
+ // size and/or position (they're updated all together at the end)
+ // it can however use a non-callback control, which is updated before
+
+ // add to the list
+ LayoutInfo layout;
+ layout.nCallbackID = nCallbackID;
+ m_listLayoutCB.AddTail(layout);
+}
+
+BOOL CResizableLayout::ArrangeLayoutCallback(CResizableLayout::LayoutInfo& /*layout*/)
+{
+ ASSERT(FALSE);
+ // must be overridden, if callback is used
+
+ return FALSE; // no output data
+}
+
+void CResizableLayout::ArrangeLayout()
+{
+ // common vars
+ UINT uFlags;
+ LayoutInfo layout;
+ CRect rectParent, rectChild;
+ GetTotalClientRect(&rectParent); // get parent window's rect
+ int count = m_listLayout.GetCount();
+ int countCB = m_listLayoutCB.GetCount();
+
+ // reposition child windows
+ HDWP hdwp = ::BeginDeferWindowPos(count + countCB);
+
+ POSITION pos = m_listLayout.GetHeadPosition();
+ while (pos != NULL)
+ {
+ // get layout info
+ layout = m_listLayout.GetNext(pos);
+
+ // calculate new child's position, size and flags for SetWindowPos
+ CalcNewChildPosition(layout, rectParent, rectChild, uFlags);
+
+ // only if size or position changed
+ if ((uFlags & (SWP_NOMOVE|SWP_NOSIZE)) != (SWP_NOMOVE|SWP_NOSIZE))
+ {
+ hdwp = ::DeferWindowPos(hdwp, layout.hWnd, NULL, rectChild.left,
+ rectChild.top, rectChild.Width(), rectChild.Height(), uFlags);
+ }
+ }
+
+ // for callback items you may use GetAnchorPosition to know the
+ // new position and size of a non-callback item after resizing
+
+ pos = m_listLayoutCB.GetHeadPosition();
+ while (pos != NULL)
+ {
+ // get layout info
+ layout = m_listLayoutCB.GetNext(pos);
+ // request layout data
+ if (!ArrangeLayoutCallback(layout))
+ continue;
+
+ // calculate new child's position, size and flags for SetWindowPos
+ CalcNewChildPosition(layout, rectParent, rectChild, uFlags);
+
+ // only if size or position changed
+ if ((uFlags & (SWP_NOMOVE|SWP_NOSIZE)) != (SWP_NOMOVE|SWP_NOSIZE))
+ {
+ hdwp = ::DeferWindowPos(hdwp, layout.hWnd, NULL, rectChild.left,
+ rectChild.top, rectChild.Width(), rectChild.Height(), uFlags);
+ }
+ }
+
+ // finally move all the windows at once
+ ::EndDeferWindowPos(hdwp);
+}
+
+void CResizableLayout::ClipChildWindow(const CResizableLayout::LayoutInfo& layout,
+ CRgn* pRegion)
+{
+ // obtain window position
+ CRect rect;
+ ::GetWindowRect(layout.hWnd, &rect);
+ ::MapWindowPoints(NULL, GetResizableWnd()->m_hWnd, (LPPOINT)&rect, 2);
+
+ // use window region if any
+ CRgn rgn;
+ rgn.CreateRectRgn(0,0,0,0);
+ switch (::GetWindowRgn(layout.hWnd, rgn))
+ {
+ case COMPLEXREGION:
+ case SIMPLEREGION:
+ rgn.OffsetRgn(rect.TopLeft());
+ break;
+
+ default:
+ rgn.SetRectRgn(&rect);
+ }
+
+ // get the clipping property
+ BOOL bClipping = layout.properties.bAskClipping ?
+ LikesClipping(layout) : layout.properties.bCachedLikesClipping;
+
+ // modify region accordingly
+ if (bClipping)
+ pRegion->CombineRgn(pRegion, &rgn, RGN_DIFF);
+ else
+ pRegion->CombineRgn(pRegion, &rgn, RGN_OR);
+}
+
+void CResizableLayout::GetClippingRegion(CRgn* pRegion)
+{
+ CWnd* pWnd = GetResizableWnd();
+
+ // System's default clipping area is screen's size,
+ // not enough for max track size, for example:
+ // if screen is 1024 x 768 and resizing border is 4 pixels,
+ // maximized size is 1024+4*2=1032 x 768+4*2=776,
+ // but max track size is 4 pixels bigger 1036 x 780 (don't ask me why!)
+ // So, if you resize the window to maximum size, the last 4 pixels
+ // are clipped out by the default clipping region, that gets created
+ // as soon as you call clipping functions (my guess).
+
+ // reset clipping region to the whole client area
+ CRect rect;
+ pWnd->GetClientRect(&rect);
+ pRegion->CreateRectRgnIndirect(&rect);
+
+ // clip only anchored controls
+ LayoutInfo layout;
+ POSITION pos = m_listLayout.GetHeadPosition();
+ while (pos != NULL)
+ {
+ // get layout info
+ layout = m_listLayout.GetNext(pos);
+
+ if (::IsWindowVisible(layout.hWnd))
+ ClipChildWindow(layout, pRegion);
+ }
+ pos = m_listLayoutCB.GetHeadPosition();
+ while (pos != NULL)
+ {
+ // get layout info
+ layout = m_listLayoutCB.GetNext(pos);
+ // request data
+ if (!ArrangeLayoutCallback(layout))
+ continue;
+
+ if (::IsWindowVisible(layout.hWnd))
+ ClipChildWindow(layout, pRegion);
+ }
+
+ // fix for RTL layouts (1 pixel of horz offset)
+ if (pWnd->GetExStyle() & 0x00400000L/*WS_EX_LAYOUTRTL*/)
+ pRegion->OffsetRgn(-1,0);
+}
+
+void CResizableLayout::EraseBackground(CDC* pDC)
+{
+ HWND hWnd = GetResizableWnd()->GetSafeHwnd();
+
+ // retrieve the background brush
+ HBRUSH hBrush = NULL;
+
+ // is this a dialog box?
+ // (using class atom is quickier than using the class name)
+ ATOM atomWndClass = (ATOM)::GetClassLong(hWnd, GCW_ATOM);
+ if (atomWndClass == (ATOM)0x8002)
+ {
+ // send a message to the dialog box
+ hBrush = (HBRUSH)::SendMessage(hWnd, WM_CTLCOLORDLG,
+ (WPARAM)pDC->GetSafeHdc(), (LPARAM)hWnd);
+ }
+ else
+ {
+ // take the background brush from the window's class
+#ifdef _WIN64
+ hBrush = (HBRUSH)::GetClassLongPtr(hWnd, GCLP_HBRBACKGROUND);
+#else
+ hBrush = (HBRUSH)::GetClassLongPtr(hWnd, GCL_HBRBACKGROUND);
+#endif
+ }
+
+ // fill the clipped background
+ CRgn rgn;
+ GetClippingRegion(&rgn);
+
+ ::FillRgn(pDC->GetSafeHdc(), rgn, hBrush);
+}
+
+// support legacy code (will disappear in future versions)
+void CResizableLayout::ClipChildren(CDC* pDC)
+{
+ CRgn rgn;
+ GetClippingRegion(&rgn);
+ // the clipping region is in device units
+ rgn.OffsetRgn(-pDC->GetWindowOrg());
+ pDC->SelectClipRgn(&rgn);
+}
+
+void CResizableLayout::GetTotalClientRect(LPRECT lpRect)
+{
+ GetResizableWnd()->GetClientRect(lpRect);
+}
+
+BOOL CResizableLayout::NeedsRefresh(const CResizableLayout::LayoutInfo& layout,
+ const CRect& rectOld, const CRect& rectNew)
+{
+ if (layout.bMsgSupport)
+ {
+ REFRESHPROPERTY refresh;
+ refresh.rcOld = rectOld;
+ refresh.rcNew = rectNew;
+ if (Send_NeedsRefresh(layout.hWnd, &refresh))
+ return refresh.bNeedsRefresh;
+ }
+
+ int nDiffWidth = (rectNew.Width() - rectOld.Width());
+ int nDiffHeight = (rectNew.Height() - rectOld.Height());
+
+ // is the same size?
+ if (nDiffWidth == 0 && nDiffHeight == 0)
+ return FALSE;
+
+ // optimistic, no need to refresh
+ BOOL bRefresh = FALSE;
+
+ // window classes that need refresh when resized
+ if (layout.sWndClass == WC_STATIC)
+ {
+ DWORD style = ::GetWindowLong(layout.hWnd, GWL_STYLE);
+
+ switch (style & SS_TYPEMASK)
+ {
+ case SS_LEFT:
+ case SS_CENTER:
+ case SS_RIGHT:
+ // word-wrapped text
+ bRefresh = bRefresh || (nDiffWidth != 0);
+ // vertically centered text
+ if (style & SS_CENTERIMAGE)
+ bRefresh = bRefresh || (nDiffHeight != 0);
+ break;
+
+ case SS_LEFTNOWORDWRAP:
+ // text with ellipsis
+ if (style & SS_ELLIPSISMASK)
+ bRefresh = bRefresh || (nDiffWidth != 0);
+ // vertically centered text
+ if (style & SS_CENTERIMAGE)
+ bRefresh = bRefresh || (nDiffHeight != 0);
+ break;
+
+ case SS_ENHMETAFILE:
+ case SS_BITMAP:
+ case SS_ICON:
+ // images
+ case SS_BLACKFRAME:
+ case SS_GRAYFRAME:
+ case SS_WHITEFRAME:
+ case SS_ETCHEDFRAME:
+ // and frames
+ bRefresh = TRUE;
+ break;
+ }
+ }
+
+ // window classes that don't redraw client area correctly
+ // when the hor scroll pos changes due to a resizing
+ BOOL bHScroll = FALSE;
+ if (layout.sWndClass == WC_LISTBOX)
+ bHScroll = TRUE;
+
+ // fix for horizontally scrollable windows
+ if (bHScroll && (nDiffWidth > 0))
+ {
+ // get max scroll position
+ SCROLLINFO info;
+ info.cbSize = sizeof(SCROLLINFO);
+ info.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
+ if (::GetScrollInfo(layout.hWnd, SB_HORZ, &info))
+ {
+ // subtract the page size
+ info.nMax -= __max(info.nPage-1,0);
+ }
+
+ // resizing will cause the text to scroll on the right
+ // because the scrollbar is going beyond the right limit
+ if ((info.nMax > 0) && (info.nPos + nDiffWidth > info.nMax))
+ {
+ // needs repainting, due to horiz scrolling
+ bRefresh = TRUE;
+ }
+ }
+
+ return bRefresh;
+}
+
+BOOL CResizableLayout::LikesClipping(const CResizableLayout::LayoutInfo& layout)
+{
+ if (layout.bMsgSupport)
+ {
+ CLIPPINGPROPERTY clipping;
+ if (Send_LikesClipping(layout.hWnd, &clipping))
+ return clipping.bLikesClipping;
+ }
+
+ DWORD style = ::GetWindowLong(layout.hWnd, GWL_STYLE);
+
+ // skip windows that wants background repainted
+ if (layout.sWndClass == TOOLBARCLASSNAME && (style & TBSTYLE_TRANSPARENT))
+ return FALSE;
+ else if (layout.sWndClass == WC_BUTTON)
+ {
+ CRect rect;
+ switch (style & _BS_TYPEMASK)
+ {
+ case BS_GROUPBOX:
+ return FALSE;
+
+ case BS_OWNERDRAW:
+ // ownerdraw buttons must return correct hittest code
+ // to notify their transparency to the system and this library
+ ::GetWindowRect(layout.hWnd, &rect);
+ if ( HTTRANSPARENT == ::SendMessage(layout.hWnd,
+ WM_NCHITTEST, 0, MAKELPARAM(rect.left, rect.top)) )
+ return FALSE;
+ break;
+ }
+ return TRUE;
+ }
+ else if (layout.sWndClass == WC_STATIC)
+ {
+ switch (style & SS_TYPEMASK)
+ {
+ case SS_LEFT:
+ case SS_CENTER:
+ case SS_RIGHT:
+ case SS_SIMPLE:
+ case SS_LEFTNOWORDWRAP:
+ // text
+ case SS_BLACKRECT:
+ case SS_GRAYRECT:
+ case SS_WHITERECT:
+ // filled rects
+ case SS_ETCHEDHORZ:
+ case SS_ETCHEDVERT:
+ // etched lines
+ case SS_BITMAP:
+ // bitmaps
+ return TRUE;
+ break;
+
+ case SS_ICON:
+ case SS_ENHMETAFILE:
+ if (style & SS_CENTERIMAGE)
+ return FALSE;
+ return TRUE;
+ break;
+
+ default:
+ return FALSE;
+ }
+ }
+
+ // assume the others like clipping
+ return TRUE;
+}
+
+void CResizableLayout::CalcNewChildPosition(const CResizableLayout::LayoutInfo& layout,
+ const CRect &rectParent, CRect &rectChild, UINT& uFlags)
+{
+ CWnd* pParent = GetResizableWnd();
+
+ ::GetWindowRect(layout.hWnd, &rectChild);
+ ::MapWindowPoints(NULL, pParent->m_hWnd, (LPPOINT)&rectChild, 2);
+
+ CRect rectNew;
+
+ // calculate new top-left corner
+ rectNew.left = layout.sizeMarginTL.cx + rectParent.Width() * layout.sizeTypeTL.cx / 100;
+ rectNew.top = layout.sizeMarginTL.cy + rectParent.Height() * layout.sizeTypeTL.cy / 100;
+
+ // calculate new bottom-right corner
+ rectNew.right = layout.sizeMarginBR.cx + rectParent.Width() * layout.sizeTypeBR.cx / 100;
+ rectNew.bottom = layout.sizeMarginBR.cy + rectParent.Height() * layout.sizeTypeBR.cy / 100;
+
+ // adjust position, if client area has been scrolled
+ rectNew.OffsetRect(rectParent.TopLeft());
+
+ // get the refresh property
+ BOOL bRefresh = layout.properties.bAskRefresh ?
+ NeedsRefresh(layout, rectChild, rectNew) : layout.properties.bCachedNeedsRefresh;
+
+ // set flags
+ uFlags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREPOSITION;
+ if (bRefresh)
+ uFlags |= SWP_NOCOPYBITS;
+ if (rectNew.TopLeft() == rectChild.TopLeft())
+ uFlags |= SWP_NOMOVE;
+ if (rectNew.Size() == rectChild.Size())
+ uFlags |= SWP_NOSIZE;
+
+ // update rect
+ rectChild = rectNew;
+}
+
+void CResizableLayout::InitResizeProperties(CResizableLayout::LayoutInfo &layout)
+{
+ // check if custom window supports this library
+ // (properties must be correctly set by the window)
+ layout.bMsgSupport = Send_QueryProperties(layout.hWnd, &layout.properties);
+
+ // default properties
+ if (!layout.bMsgSupport)
+ {
+ // clipping property is assumed as static
+ layout.properties.bAskClipping = FALSE;
+ layout.properties.bCachedLikesClipping = LikesClipping(layout);
+ // refresh property is assumed as dynamic
+ layout.properties.bAskRefresh = TRUE;
+ }
+}
diff --git a/src/thirdparty/ui/ResizableLib/ResizableLayout.h b/src/thirdparty/ui/ResizableLib/ResizableLayout.h
new file mode 100644
index 000000000..0d57623db
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableLayout.h
@@ -0,0 +1,196 @@
+// ResizableLayout.h: interface for the CResizableLayout class.
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_RESIZABLELAYOUT_H__INCLUDED_)
+#define AFX_RESIZABLELAYOUT_H__INCLUDED_
+
+#include <afxtempl.h>
+#include "ResizableMsgSupport.h"
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+// useful compatibility constants (the only one required is NOANCHOR)
+
+const CSize NOANCHOR(-1,-1),
+ TOP_LEFT(0,0), TOP_CENTER(50,0), TOP_RIGHT(100,0),
+ MIDDLE_LEFT(0,50), MIDDLE_CENTER(50,50), MIDDLE_RIGHT(100,50),
+ BOTTOM_LEFT(0,100), BOTTOM_CENTER(50,100), BOTTOM_RIGHT(100,100);
+
+
+class CResizableLayout
+{
+protected:
+ class LayoutInfo
+ {
+ public:
+ HWND hWnd;
+ UINT nCallbackID;
+
+ CString sWndClass;
+
+ // upper-left corner
+ SIZE sizeTypeTL;
+ SIZE sizeMarginTL;
+
+ // bottom-right corner
+ SIZE sizeTypeBR;
+ SIZE sizeMarginBR;
+
+ // custom window support
+ BOOL bMsgSupport;
+ RESIZEPROPERTIES properties;
+
+ public:
+ LayoutInfo() : hWnd(NULL), nCallbackID(0), bMsgSupport(FALSE)
+ {
+ sizeTypeTL.cx = 0;
+ sizeTypeTL.cy = 0;
+ sizeMarginTL.cx = 0;
+ sizeMarginTL.cy = 0;
+ sizeTypeBR.cx = 0;
+ sizeTypeBR.cy = 0;
+ sizeMarginBR.cx = 0;
+ sizeMarginBR.cy = 0;
+ memset(&properties, 0, sizeof properties);
+ }
+
+ LayoutInfo(HWND hwnd, SIZE tl_t, SIZE tl_m,
+ SIZE br_t, SIZE br_m, CString classname)
+ : hWnd(hwnd), nCallbackID(0),
+ sWndClass(classname), bMsgSupport(FALSE),
+ sizeTypeTL(tl_t), sizeMarginTL(tl_m),
+ sizeTypeBR(br_t), sizeMarginBR(br_m)
+ {
+ memset(&properties, 0, sizeof properties);
+ }
+ };
+
+private:
+ // list of repositionable controls
+ CMap<HWND, HWND, POSITION, POSITION> m_mapLayout;
+ CList<LayoutInfo, LayoutInfo&> m_listLayout;
+ CList<LayoutInfo, LayoutInfo&> m_listLayoutCB;
+
+ void ClipChildWindow(const CResizableLayout::LayoutInfo &layout, CRgn* pRegion);
+
+ void CalcNewChildPosition(const CResizableLayout::LayoutInfo &layout,
+ const CRect &rectParent, CRect &rectChild, UINT& uFlags);
+
+protected:
+ // override to initialize resize properties (clipping, refresh)
+ virtual void InitResizeProperties(CResizableLayout::LayoutInfo& layout);
+
+ // override to specify clipping for unsupported windows
+ virtual BOOL LikesClipping(const CResizableLayout::LayoutInfo &layout);
+
+ // override to specify refresh for unsupported windows
+ virtual BOOL NeedsRefresh(const CResizableLayout::LayoutInfo &layout,
+ const CRect &rectOld, const CRect &rectNew);
+
+ // paint the background on the given DC (for XP theme's compatibility)
+ void EraseBackground(CDC* pDC);
+
+ // clip out child windows from the given DC (support old code)
+ void ClipChildren(CDC* pDC);
+
+ // get the clipping region (without clipped child windows)
+ void GetClippingRegion(CRgn* pRegion);
+
+ // override for scrollable or expanding parent windows
+ virtual void GetTotalClientRect(LPRECT lpRect);
+
+ // add anchors to a control, given its HWND
+ void AddAnchor(HWND hWnd, CSize sizeTypeTL, CSize sizeTypeBR = NOANCHOR);
+
+ // add anchors to a control, given its ID
+ void AddAnchor(UINT nID, CSize sizeTypeTL, CSize sizeTypeBR = NOANCHOR)
+ {
+ AddAnchor(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID),
+ sizeTypeTL, sizeTypeBR);
+ }
+
+ // add a callback (control ID or HWND is unknown or may change)
+ void AddAnchorCallback(UINT nCallbackID);
+
+ // get rect of an anchored window, given the parent's client area
+ BOOL GetAnchorPosition(HWND hWnd, const CRect &rectParent,
+ CRect &rectChild, UINT* lpFlags = NULL)
+ {
+ POSITION pos;
+ if (!m_mapLayout.Lookup(hWnd, pos))
+ return FALSE;
+
+ UINT uTmpFlags;
+ CalcNewChildPosition(m_listLayout.GetAt(pos), rectParent, rectChild,
+ (lpFlags != NULL) ? (*lpFlags) : uTmpFlags);
+ return TRUE;
+ }
+
+ // get rect of an anchored window, given the parent's client area
+ BOOL GetAnchorPosition(UINT nID, const CRect &rectParent,
+ CRect &rectChild, UINT* lpFlags = NULL)
+ {
+ return GetAnchorPosition(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID),
+ rectParent, rectChild, lpFlags);
+ }
+
+ // remove an anchored control from the layout, given its HWND
+ BOOL RemoveAnchor(HWND hWnd)
+ {
+ POSITION pos;
+ if (!m_mapLayout.Lookup(hWnd, pos))
+ return FALSE;
+
+ m_listLayout.RemoveAt(pos);
+ return m_mapLayout.RemoveKey(hWnd);
+ }
+
+ // remove an anchored control from the layout, given its HWND
+ BOOL RemoveAnchor(UINT nID)
+ {
+ return RemoveAnchor(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID));
+ }
+
+ // reset layout content
+ void RemoveAllAnchors()
+ {
+ m_mapLayout.RemoveAll();
+ m_listLayout.RemoveAll();
+ m_listLayoutCB.RemoveAll();
+ }
+
+ // adjust children's layout, when parent's size changes
+ void ArrangeLayout();
+
+ // override to provide dynamic control's layout info
+ virtual BOOL ArrangeLayoutCallback(CResizableLayout::LayoutInfo& layout);
+
+ // override to provide the parent window
+ virtual CWnd* GetResizableWnd() = 0;
+
+public:
+ CResizableLayout() { }
+
+ virtual ~CResizableLayout()
+ {
+ // just for safety
+ RemoveAllAnchors();
+ }
+};
+
+#endif // !defined(AFX_RESIZABLELAYOUT_H__INCLUDED_)
diff --git a/src/thirdparty/ui/ResizableLib/ResizableLib.vcproj b/src/thirdparty/ui/ResizableLib/ResizableLib.vcproj
new file mode 100644
index 000000000..aeeeeafc3
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableLib.vcproj
@@ -0,0 +1,370 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="ResizableLib"
+ ProjectGUID="{4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}"
+ RootNamespace="ResizableLib"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\debug.vsprops"
+ UseOfMFC="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\debug.vsprops"
+ UseOfMFC="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="_WIN64;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\release.vsprops"
+ UseOfMFC="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\release.vsprops"
+ UseOfMFC="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="_WIN64;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ EnableEnhancedInstructionSet="0"
+ DisableSpecificWarnings="4244"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\ResizableDialog.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ResizableGrip.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ResizableLayout.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ResizableMinMax.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ResizablePage.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ResizableSheet.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ResizableState.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\ResizableDialog.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ResizableGrip.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ResizableLayout.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ResizableMinMax.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ResizableMsgSupport.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ResizableMsgSupport.inl"
+ >
+ </File>
+ <File
+ RelativePath=".\ResizablePage.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ResizableSheet.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ResizableState.h"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ <Global
+ Name="DevPartner_IsInstrumented"
+ Value="0"
+ />
+ </Globals>
+</VisualStudioProject>
diff --git a/src/thirdparty/ui/ResizableLib/ResizableLib.vcxproj b/src/thirdparty/ui/ResizableLib/ResizableLib.vcxproj
new file mode 100644
index 000000000..401956ac4
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableLib.vcxproj
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{4CC7AE86-3E0A-430A-BFF4-BF00204CAFB0}</ProjectGuid>
+ <RootNamespace>ResizableLib</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>Static</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>Static</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>Static</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>Static</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\debug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\debug.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Lib>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <PreprocessorDefinitions>_WIN64;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Lib>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Lib>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <PreprocessorDefinitions>_WIN64;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <DisableSpecificWarnings>4244</DisableSpecificWarnings>
+ </ClCompile>
+ <Lib>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="ResizableDialog.cpp" />
+ <ClCompile Include="ResizableGrip.cpp" />
+ <ClCompile Include="ResizableLayout.cpp" />
+ <ClCompile Include="ResizableMinMax.cpp" />
+ <ClCompile Include="ResizablePage.cpp" />
+ <ClCompile Include="ResizableSheet.cpp" />
+ <ClCompile Include="ResizableState.cpp" />
+ <ClCompile Include="stdafx.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="ResizableDialog.h" />
+ <ClInclude Include="ResizableGrip.h" />
+ <ClInclude Include="ResizableLayout.h" />
+ <ClInclude Include="ResizableMinMax.h" />
+ <ClInclude Include="ResizableMsgSupport.h" />
+ <ClInclude Include="ResizablePage.h" />
+ <ClInclude Include="ResizableSheet.h" />
+ <ClInclude Include="ResizableState.h" />
+ <ClInclude Include="stdafx.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="ResizableMsgSupport.inl" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+ <ProjectExtensions>
+ <VisualStudio>
+ <UserProperties DevPartner_IsInstrumented="0" />
+ </VisualStudio>
+ </ProjectExtensions>
+</Project> \ No newline at end of file
diff --git a/src/thirdparty/ui/ResizableLib/ResizableLib.vcxproj.filters b/src/thirdparty/ui/ResizableLib/ResizableLib.vcxproj.filters
new file mode 100644
index 000000000..53f8a1d66
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableLib.vcxproj.filters
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="ResizableDialog.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ResizableGrip.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ResizableLayout.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ResizableMinMax.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ResizablePage.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ResizableSheet.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ResizableState.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stdafx.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="ResizableDialog.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ResizableGrip.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ResizableLayout.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ResizableMinMax.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ResizableMsgSupport.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ResizablePage.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ResizableSheet.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ResizableState.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="stdafx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="ResizableMsgSupport.inl">
+ <Filter>Header Files</Filter>
+ </None>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/src/thirdparty/ui/ResizableLib/ResizableMinMax.cpp b/src/thirdparty/ui/ResizableLib/ResizableMinMax.cpp
new file mode 100644
index 000000000..0a19f3002
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableMinMax.cpp
@@ -0,0 +1,89 @@
+// ResizableMinMax.cpp: implementation of the CResizableMinMax class.
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "ResizableMinMax.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CResizableMinMax::CResizableMinMax()
+{
+ m_bUseMinTrack = FALSE;
+ m_bUseMaxTrack = FALSE;
+ m_bUseMaxRect = FALSE;
+}
+
+CResizableMinMax::~CResizableMinMax()
+{
+
+}
+
+void CResizableMinMax::MinMaxInfo(LPMINMAXINFO lpMMI)
+{
+ if (m_bUseMinTrack)
+ lpMMI->ptMinTrackSize = m_ptMinTrackSize;
+
+ if (m_bUseMaxTrack)
+ lpMMI->ptMaxTrackSize = m_ptMaxTrackSize;
+
+ if (m_bUseMaxRect)
+ {
+ lpMMI->ptMaxPosition = m_ptMaxPos;
+ lpMMI->ptMaxSize = m_ptMaxSize;
+ }
+}
+
+void CResizableMinMax::SetMaximizedRect(const CRect& rc)
+{
+ m_bUseMaxRect = TRUE;
+
+ m_ptMaxPos = rc.TopLeft();
+ m_ptMaxSize.x = rc.Width();
+ m_ptMaxSize.y = rc.Height();
+}
+
+void CResizableMinMax::ResetMaximizedRect()
+{
+ m_bUseMaxRect = FALSE;
+}
+
+void CResizableMinMax::SetMinTrackSize(const CSize& size)
+{
+ m_bUseMinTrack = TRUE;
+
+ m_ptMinTrackSize.x = size.cx;
+ m_ptMinTrackSize.y = size.cy;
+}
+
+void CResizableMinMax::ResetMinTrackSize()
+{
+ m_bUseMinTrack = FALSE;
+}
+
+void CResizableMinMax::SetMaxTrackSize(const CSize& size)
+{
+ m_bUseMaxTrack = TRUE;
+
+ m_ptMaxTrackSize.x = size.cx;
+ m_ptMaxTrackSize.y = size.cy;
+}
+
+void CResizableMinMax::ResetMaxTrackSize()
+{
+ m_bUseMaxTrack = FALSE;
+}
diff --git a/src/thirdparty/ui/ResizableLib/ResizableMinMax.h b/src/thirdparty/ui/ResizableLib/ResizableMinMax.h
new file mode 100644
index 000000000..557780323
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableMinMax.h
@@ -0,0 +1,53 @@
+// ResizableMinMax.h: interface for the CResizableMinMax class.
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_RESIZABLEMINMAX_H__INCLUDED_)
+#define AFX_RESIZABLEMINMAX_H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+class CResizableMinMax
+{
+// Attributes
+private:
+ // flags
+ BOOL m_bUseMaxTrack;
+ BOOL m_bUseMinTrack;
+ BOOL m_bUseMaxRect;
+
+ POINT m_ptMinTrackSize; // min tracking size
+ POINT m_ptMaxTrackSize; // max tracking size
+ POINT m_ptMaxPos; // maximized position
+ POINT m_ptMaxSize; // maximized size
+
+public:
+ CResizableMinMax();
+ virtual ~CResizableMinMax();
+
+protected:
+ void MinMaxInfo(LPMINMAXINFO lpMMI);
+
+ void SetMaximizedRect(const CRect& rc); // set window rect when maximized
+ void ResetMaximizedRect(); // reset to default maximized rect
+ void SetMinTrackSize(const CSize& size); // set minimum tracking size
+ void ResetMinTrackSize(); // reset to default minimum tracking size
+ void SetMaxTrackSize(const CSize& size); // set maximum tracking size
+ void ResetMaxTrackSize(); // reset to default maximum tracking size
+};
+
+#endif // !defined(AFX_RESIZABLEMINMAX_H__INCLUDED_)
diff --git a/src/thirdparty/ui/ResizableLib/ResizableMsgSupport.h b/src/thirdparty/ui/ResizableLib/ResizableMsgSupport.h
new file mode 100644
index 000000000..68d45fe9f
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableMsgSupport.h
@@ -0,0 +1,61 @@
+// ResizableMsgSupport.h: some declarations to support custom resizable wnds
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_RESIZABLEMSGSUPPORT_H__INCLUDED_)
+#define AFX_RESIZABLEMSGSUPPORT_H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+typedef struct tagRESIZEPROPERTIES
+{
+ // wether to ask for resizing properties every time
+ BOOL bAskClipping;
+ BOOL bAskRefresh;
+ // otherwise, use the cached properties
+ BOOL bCachedLikesClipping;
+ BOOL bCachedNeedsRefresh;
+
+ // initialize with valid data
+ tagRESIZEPROPERTIES() : bAskClipping(TRUE), bAskRefresh(TRUE) {}
+
+} RESIZEPROPERTIES, *PRESIZEPROPERTIES, *LPRESIZEPROPERTIES;
+
+
+typedef struct tagCLIPPINGPROPERTY
+{
+ BOOL bLikesClipping;
+
+ // initialize with valid data
+ tagCLIPPINGPROPERTY() : bLikesClipping(FALSE) {}
+
+} CLIPPINGPROPERTY, *PCLIPPINGPROPERTY, *LPCLIPPINGPROPERTY;
+
+
+typedef struct tagREFRESHPROPERTY
+{
+ BOOL bNeedsRefresh;
+ RECT rcOld;
+ RECT rcNew;
+
+ // initialize with valid data
+ tagREFRESHPROPERTY() : bNeedsRefresh(TRUE) {}
+
+} REFRESHPROPERTY, *PREFRESHPROPERTY, *LPREFRESHPROPERTY;
+
+
+#endif // !defined(AFX_RESIZABLEMSGSUPPORT_H__INCLUDED_)
diff --git a/src/thirdparty/ui/ResizableLib/ResizableMsgSupport.inl b/src/thirdparty/ui/ResizableLib/ResizableMsgSupport.inl
new file mode 100644
index 000000000..f8f3b41e8
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableMsgSupport.inl
@@ -0,0 +1,56 @@
+// ResizableMsgSupport.inl: some definitions to support custom resizable wnds
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+
+// registered message to communicate with the library
+// (defined so that in the same executable it is initialized only once)
+const UINT WMU_RESIZESUPPORT = ::RegisterWindowMessage(_T("WMU_RESIZESUPPORT"));
+
+// if the message is implemented the returned value must be non-zero
+// the default window procedure returns zero for unhandled messages
+
+// wParam is one of the following RSZSUP_* values, lParam as specified
+
+#define RSZSUP_QUERYPROPERTIES 101 // lParam = LPRESIZEPROPERTIES
+
+#define RSZSUP_LIKESCLIPPING 102 // lParam = LPCLIPPINGPROPERTY
+
+#define RSZSUP_NEEDSREFRESH 103 // lParam = LPREFRESHPROPERTY
+
+
+/////////////////////////////////////////////////////////////////////////////
+// utility functions
+
+inline BOOL Send_QueryProperties(HWND hWnd, LPRESIZEPROPERTIES pResizeProperties)
+{
+ ASSERT(::IsWindow(hWnd));
+ return (0 != SendMessage(hWnd, WMU_RESIZESUPPORT,
+ RSZSUP_QUERYPROPERTIES, (LPARAM)pResizeProperties));
+}
+
+inline BOOL Send_LikesClipping(HWND hWnd, LPCLIPPINGPROPERTY pClippingProperty)
+{
+ ASSERT(::IsWindow(hWnd));
+ return (0 != SendMessage(hWnd, WMU_RESIZESUPPORT,
+ RSZSUP_LIKESCLIPPING, (LPARAM)pClippingProperty));
+}
+
+inline BOOL Send_NeedsRefresh(HWND hWnd, LPREFRESHPROPERTY pRefreshProperty)
+{
+ ASSERT(::IsWindow(hWnd));
+ return (0 != SendMessage(hWnd, WMU_RESIZESUPPORT,
+ RSZSUP_NEEDSREFRESH, (LPARAM)pRefreshProperty));
+}
diff --git a/src/thirdparty/ui/ResizableLib/ResizablePage.cpp b/src/thirdparty/ui/ResizableLib/ResizablePage.cpp
new file mode 100644
index 000000000..06dcc6b96
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizablePage.cpp
@@ -0,0 +1,72 @@
+// ResizablePage.cpp : implementation file
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "ResizablePage.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// CResizablePage
+
+IMPLEMENT_DYNCREATE(CResizablePage, CPropertyPage)
+
+CResizablePage::CResizablePage()
+{
+}
+
+CResizablePage::CResizablePage(UINT nIDTemplate, UINT nIDCaption)
+ : CPropertyPage(nIDTemplate, nIDCaption)
+{
+}
+
+CResizablePage::CResizablePage(LPCTSTR lpszTemplateName, UINT nIDCaption)
+ : CPropertyPage(lpszTemplateName, nIDCaption)
+{
+}
+
+CResizablePage::~CResizablePage()
+{
+}
+
+
+BEGIN_MESSAGE_MAP(CResizablePage, CPropertyPage)
+ //{{AFX_MSG_MAP(CResizablePage)
+ ON_WM_SIZE()
+ ON_WM_ERASEBKGND()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CResizablePage message handlers
+
+void CResizablePage::OnSize(UINT nType, int cx, int cy)
+{
+ CWnd::OnSize(nType, cx, cy);
+
+ ArrangeLayout();
+}
+
+BOOL CResizablePage::OnEraseBkgnd(CDC* pDC)
+{
+ // Windows XP doesn't like clipping regions ...try this!
+ EraseBackground(pDC);
+ return TRUE;
+
+/* ClipChildren(pDC); // old-method (for safety)
+
+ return CPropertyPage::OnEraseBkgnd(pDC);
+*/
+}
diff --git a/src/thirdparty/ui/ResizableLib/ResizablePage.h b/src/thirdparty/ui/ResizableLib/ResizablePage.h
new file mode 100644
index 000000000..4c8218634
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizablePage.h
@@ -0,0 +1,78 @@
+#if !defined(AFX_RESIZABLEPAGE_H__INCLUDED_)
+#define AFX_RESIZABLEPAGE_H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+// ResizablePage.h : header file
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "ResizableLayout.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CResizablePage window
+
+class CResizablePage : public CPropertyPage, public CResizableLayout
+{
+ DECLARE_DYNCREATE(CResizablePage)
+
+// Construction
+public:
+ CResizablePage();
+ CResizablePage(UINT nIDTemplate, UINT nIDCaption = 0);
+ CResizablePage(LPCTSTR lpszTemplateName, UINT nIDCaption = 0);
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CResizablePage)
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~CResizablePage();
+
+// callable from derived classes
+protected:
+
+ virtual CWnd* GetResizableWnd()
+ {
+ // make the layout know its parent window
+ return this;
+ };
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CResizablePage)
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_RESIZABLEPAGE_H__INCLUDED_)
diff --git a/src/thirdparty/ui/ResizableLib/ResizableSheet.cpp b/src/thirdparty/ui/ResizableLib/ResizableSheet.cpp
new file mode 100644
index 000000000..a7048b085
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableSheet.cpp
@@ -0,0 +1,349 @@
+// ResizableSheet.cpp : implementation file
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "ResizableSheet.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// CResizableSheet
+
+IMPLEMENT_DYNAMIC(CResizableSheet, CPropertySheet)
+
+inline void CResizableSheet::PrivateConstruct()
+{
+ m_bEnableSaveRestore = FALSE;
+ m_bSavePage = FALSE;
+ m_dwGripTempState = 1;
+}
+
+
+CResizableSheet::CResizableSheet()
+{
+ PrivateConstruct();
+}
+
+CResizableSheet::CResizableSheet(UINT nIDCaption, CWnd *pParentWnd, UINT iSelectPage)
+ : CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
+{
+ PrivateConstruct();
+}
+
+CResizableSheet::CResizableSheet(LPCTSTR pszCaption, CWnd *pParentWnd, UINT iSelectPage)
+ : CPropertySheet(pszCaption, pParentWnd, iSelectPage)
+{
+ PrivateConstruct();
+}
+
+CResizableSheet::~CResizableSheet()
+{
+}
+
+BEGIN_MESSAGE_MAP(CResizableSheet, CPropertySheet)
+ //{{AFX_MSG_MAP(CResizableSheet)
+ ON_WM_GETMINMAXINFO()
+ ON_WM_SIZE()
+ ON_WM_DESTROY()
+ ON_WM_CREATE()
+ ON_WM_ERASEBKGND()
+ //}}AFX_MSG_MAP
+ ON_NOTIFY_REFLECT_EX(PSN_SETACTIVE, OnPageChanging)
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CResizableSheet message handlers
+
+int CResizableSheet::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CPropertySheet::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ // keep client area
+ CRect rect;
+ GetClientRect(&rect);
+ // set resizable style
+ ModifyStyle(DS_MODALFRAME, WS_POPUP | WS_THICKFRAME);
+ // adjust size to reflect new style
+ ::AdjustWindowRectEx(&rect, GetStyle(),
+ ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());
+ SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(), SWP_FRAMECHANGED|
+ SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREPOSITION);
+
+ // create and init the size-grip
+ if (!CreateSizeGrip())
+ return -1;
+
+ return 0;
+}
+
+BOOL CResizableSheet::OnInitDialog()
+{
+ BOOL bResult = CPropertySheet::OnInitDialog();
+
+ // set the initial size as the min track size
+ CRect rc;
+ GetWindowRect(&rc);
+ SetMinTrackSize(rc.Size());
+
+ // initialize layout
+ PresetLayout();
+
+ // prevent flickering
+ GetTabControl()->ModifyStyle(0, WS_CLIPSIBLINGS);
+
+ return bResult;
+}
+
+void CResizableSheet::OnDestroy()
+{
+ if (m_bEnableSaveRestore)
+ {
+ SaveWindowRect(m_sSection, m_bRectOnly);
+ SavePage();
+ }
+
+ RemoveAllAnchors();
+
+ CPropertySheet::OnDestroy();
+}
+
+// maps an index to a button ID and vice-versa
+static UINT _propButtons[] =
+{
+ IDOK, IDCANCEL, ID_APPLY_NOW, IDHELP,
+ ID_WIZBACK, ID_WIZNEXT, ID_WIZFINISH
+};
+const int _propButtonsCount = sizeof(_propButtons)/sizeof(UINT);
+
+// horizontal line in wizard mode
+#define ID_WIZLINE ID_WIZFINISH+1
+
+void CResizableSheet::PresetLayout()
+{
+ if (IsWizard()) // wizard mode
+ {
+ // hide tab control
+ GetTabControl()->ShowWindow(SW_HIDE);
+
+ AddAnchor(ID_WIZLINE, BOTTOM_LEFT, BOTTOM_RIGHT);
+ }
+ else // tab mode
+ {
+ AddAnchor(AFX_IDC_TAB_CONTROL, TOP_LEFT, BOTTOM_RIGHT);
+ }
+
+ // add a callback for active page (which can change at run-time)
+ AddAnchorCallback(1);
+
+ // use *total* parent size to have correct margins
+ CRect rectPage, rectSheet;
+ GetTotalClientRect(&rectSheet);
+
+ GetActivePage()->GetWindowRect(&rectPage);
+ ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectPage, 2);
+
+ // pre-calculate margins
+ m_sizePageTL = rectPage.TopLeft() - rectSheet.TopLeft();
+ m_sizePageBR = rectPage.BottomRight() - rectSheet.BottomRight();
+
+ // add all possible buttons, if they exist
+ for (int i = 0; i < _propButtonsCount; i++)
+ {
+ if (NULL != GetDlgItem(_propButtons[i]))
+ AddAnchor(_propButtons[i], BOTTOM_RIGHT);
+ }
+}
+
+BOOL CResizableSheet::ArrangeLayoutCallback(LayoutInfo &layout)
+{
+ if (layout.nCallbackID != 1) // we only added 1 callback
+ return CResizableLayout::ArrangeLayoutCallback(layout);
+
+ // set layout info for active page
+ layout.hWnd = (HWND)::SendMessage(m_hWnd, PSM_GETCURRENTPAGEHWND, 0, 0);
+ if (!::IsWindow(layout.hWnd))
+ return FALSE;
+
+ // set margins
+ if (IsWizard()) // wizard mode
+ {
+ // use pre-calculated margins
+ layout.sizeMarginTL = m_sizePageTL;
+ layout.sizeMarginBR = m_sizePageBR;
+ }
+ else // tab mode
+ {
+ CTabCtrl* pTab = GetTabControl();
+ ASSERT(pTab != NULL);
+
+ // get tab position after resizing and calc page rect
+ CRect rectPage, rectSheet;
+ GetTotalClientRect(&rectSheet);
+
+ VERIFY(GetAnchorPosition(pTab->m_hWnd, rectSheet, rectPage));
+ pTab->AdjustRect(FALSE, &rectPage);
+
+ // set margins
+ layout.sizeMarginTL = rectPage.TopLeft() - rectSheet.TopLeft();
+ layout.sizeMarginBR = rectPage.BottomRight() - rectSheet.BottomRight();
+ }
+
+ // set anchor types
+ layout.sizeTypeTL = TOP_LEFT;
+ layout.sizeTypeBR = BOTTOM_RIGHT;
+
+ // use this layout info
+ return TRUE;
+}
+
+void CResizableSheet::OnSize(UINT nType, int cx, int cy)
+{
+ CWnd::OnSize(nType, cx, cy);
+
+ if (nType == SIZE_MAXHIDE || nType == SIZE_MAXSHOW)
+ return; // arrangement not needed
+
+ if (nType == SIZE_MAXIMIZED)
+ HideSizeGrip(&m_dwGripTempState);
+ else
+ ShowSizeGrip(&m_dwGripTempState);
+
+ // update grip and layout
+ UpdateSizeGrip();
+ ArrangeLayout();
+}
+
+BOOL CResizableSheet::OnPageChanging(NMHDR* /*pNotifyStruct*/, LRESULT* /*pResult*/)
+{
+ // update new wizard page
+ // active page changes after this notification
+ PostMessage(WM_SIZE);
+
+ return FALSE; // continue routing
+}
+
+BOOL CResizableSheet::OnEraseBkgnd(CDC* pDC)
+{
+ // Windows XP doesn't like clipping regions ...try this!
+ EraseBackground(pDC);
+ return TRUE;
+
+/* ClipChildren(pDC); // old-method (for safety)
+
+ return CPropertySheet::OnEraseBkgnd(pDC);
+*/
+}
+
+void CResizableSheet::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
+{
+ MinMaxInfo(lpMMI);
+}
+
+// protected members
+
+int CResizableSheet::GetMinWidth()
+{
+ CWnd* pWnd = NULL;
+ CRect rectWnd, rectSheet;
+ GetTotalClientRect(&rectSheet);
+
+ int max = 0, min = rectSheet.Width();
+ // search for leftmost and rightmost button margins
+ for (int i = 0; i < 7; i++)
+ {
+ pWnd = GetDlgItem(_propButtons[i]);
+ // exclude not present or hidden buttons
+ if (pWnd == NULL || !(pWnd->GetStyle() & WS_VISIBLE))
+ continue;
+
+ // left position is relative to the right border
+ // of the parent window (negative value)
+ pWnd->GetWindowRect(&rectWnd);
+ ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectWnd, 2);
+ int left = rectSheet.right - rectWnd.left;
+ int right = rectSheet.right - rectWnd.right;
+
+ if (left > max)
+ max = left;
+ if (right < min)
+ min = right;
+ }
+
+ // sizing border width
+ int border = GetSystemMetrics(SM_CXSIZEFRAME);
+
+ // compute total width
+ return max + min + 2*border;
+}
+
+
+// NOTE: this must be called after all the other settings
+// to have the window and its controls displayed properly
+void CResizableSheet::EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly, BOOL bWithPage)
+{
+ m_sSection = pszSection;
+ m_bSavePage = bWithPage;
+
+ m_bEnableSaveRestore = TRUE;
+ m_bRectOnly = bRectOnly;
+
+ // restore immediately
+ LoadWindowRect(pszSection, bRectOnly);
+ LoadPage();
+}
+
+// private memebers
+
+// used to save/restore active page
+// either in the registry or a private .INI file
+// depending on your application settings
+
+#define ACTIVEPAGE _T("ActivePage")
+
+void CResizableSheet::SavePage()
+{
+ if (!m_bSavePage)
+ return;
+
+ // saves active page index, zero (the first) if problems
+ // cannot use GetActivePage, because it always fails
+
+ CTabCtrl *pTab = GetTabControl();
+ int page = 0;
+
+ if (pTab != NULL)
+ page = pTab->GetCurSel();
+ if (page < 0)
+ page = 0;
+
+ AfxGetApp()->WriteProfileInt(m_sSection, ACTIVEPAGE, page);
+}
+
+void CResizableSheet::LoadPage()
+{
+ // restore active page, zero (the first) if not found
+ int page = AfxGetApp()->GetProfileInt(m_sSection, ACTIVEPAGE, 0);
+
+ if (m_bSavePage)
+ {
+ SetActivePage(page);
+ ArrangeLayout(); // needs refresh
+ }
+}
+
+void CResizableSheet::RefreshLayout()
+{
+ SendMessage(WM_SIZE);
+}
diff --git a/src/thirdparty/ui/ResizableLib/ResizableSheet.h b/src/thirdparty/ui/ResizableLib/ResizableSheet.h
new file mode 100644
index 000000000..c82a63798
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableSheet.h
@@ -0,0 +1,114 @@
+#if !defined(AFX_RESIZABLESHEET_H__INCLUDED_)
+#define AFX_RESIZABLESHEET_H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "ResizableLayout.h"
+#include "ResizableGrip.h"
+#include "ResizableMinMax.h"
+#include "ResizableState.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// ResizableSheet.h : header file
+//
+
+class CResizableSheet : public CPropertySheet, public CResizableLayout,
+ public CResizableGrip, public CResizableMinMax,
+ public CResizableState
+{
+ DECLARE_DYNAMIC(CResizableSheet)
+
+// Construction
+public:
+ CResizableSheet();
+ CResizableSheet(UINT nIDCaption, CWnd *pParentWnd = NULL, UINT iSelectPage = 0);
+ CResizableSheet(LPCTSTR pszCaption, CWnd *pParentWnd = NULL, UINT iSelectPage = 0);
+
+// Attributes
+private:
+ // support for temporarily hiding the grip
+ DWORD m_dwGripTempState;
+
+ // flags
+ BOOL m_bEnableSaveRestore;
+ BOOL m_bRectOnly;
+ BOOL m_bSavePage;
+
+ // layout vars
+ CSize m_sizePageTL, m_sizePageBR;
+
+ // internal status
+ CString m_sSection; // section name (identifies a parent window)
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CResizableSheet)
+ public:
+ virtual BOOL OnInitDialog();
+ //}}AFX_VIRTUAL
+ protected:
+
+// Implementation
+public:
+ void RefreshLayout();
+ virtual ~CResizableSheet();
+
+// used internally
+private:
+ void PresetLayout();
+ void PrivateConstruct();
+ void SavePage();
+ void LoadPage();
+
+ BOOL IsWizard() { return (m_psh.dwFlags & PSH_WIZARD); }
+
+// callable from derived classes
+protected:
+ // section to use in app's profile
+ void EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly = FALSE,
+ BOOL bWithPage = FALSE);
+ int GetMinWidth(); // minimum width to display all buttons
+
+
+ virtual CWnd* GetResizableWnd()
+ {
+ // make the layout know its parent window
+ return this;
+ };
+
+// Generated message map functions
+protected:
+ virtual BOOL ArrangeLayoutCallback(LayoutInfo& layout);
+ //{{AFX_MSG(CResizableSheet)
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnDestroy();
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ //}}AFX_MSG
+ afx_msg BOOL OnPageChanging(NMHDR* pNotifyStruct, LRESULT* pResult);
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // AFX_RESIZABLESHEET_H__INCLUDED_
diff --git a/src/thirdparty/ui/ResizableLib/ResizableState.cpp b/src/thirdparty/ui/ResizableLib/ResizableState.cpp
new file mode 100644
index 000000000..748038d1a
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableState.cpp
@@ -0,0 +1,105 @@
+// ResizableState.cpp: implementation of the CResizableState class.
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "ResizableState.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CResizableState::CResizableState()
+{
+
+}
+
+CResizableState::~CResizableState()
+{
+
+}
+
+
+// used to save/restore window's size and position
+// either in the registry or a private .INI file
+// depending on your application settings
+
+#define PLACEMENT_ENT _T("WindowPlacement")
+#define PLACEMENT_FMT _T("%d,%d,%d,%d,%d,%d")
+
+BOOL CResizableState::SaveWindowRect(LPCTSTR pszSection, BOOL bRectOnly)
+{
+ CString data;
+ WINDOWPLACEMENT wp;
+
+ ZeroMemory(&wp, sizeof(WINDOWPLACEMENT));
+ wp.length = sizeof(WINDOWPLACEMENT);
+ if (!GetResizableWnd()->GetWindowPlacement(&wp))
+ return FALSE;
+
+ RECT& rc = wp.rcNormalPosition; // alias
+
+ if (bRectOnly) // save size/pos only (normal state)
+ {
+ // use screen coordinates
+ GetResizableWnd()->GetWindowRect(&rc);
+
+ data.Format(PLACEMENT_FMT, rc.left, rc.top,
+ rc.right, rc.bottom, SW_NORMAL, 0);
+ }
+ else // save also min/max state
+ {
+ // use workspace coordinates
+ data.Format(PLACEMENT_FMT, rc.left, rc.top,
+ rc.right, rc.bottom, wp.showCmd, wp.flags);
+ }
+
+ return AfxGetApp()->WriteProfileString(pszSection, PLACEMENT_ENT, data);
+}
+
+BOOL CResizableState::LoadWindowRect(LPCTSTR pszSection, BOOL bRectOnly)
+{
+ CString data;
+ WINDOWPLACEMENT wp;
+
+ data = AfxGetApp()->GetProfileString(pszSection, PLACEMENT_ENT);
+
+ if (data.IsEmpty()) // never saved before
+ return FALSE;
+
+ ZeroMemory(&wp, sizeof(WINDOWPLACEMENT));
+ wp.length = sizeof(WINDOWPLACEMENT);
+ if (!GetResizableWnd()->GetWindowPlacement(&wp))
+ return FALSE;
+
+ RECT& rc = wp.rcNormalPosition; // alias
+
+ if (_stscanf(data, PLACEMENT_FMT, &rc.left, &rc.top,
+ &rc.right, &rc.bottom, &wp.showCmd, &wp.flags) == 6)
+ {
+ if (bRectOnly) // restore size/pos only
+ {
+ CRect rect(rc);
+ return GetResizableWnd()->SetWindowPos(NULL, rect.left, rect.top,
+ rect.Width(), rect.Height(), SWP_NOACTIVATE | SWP_NOZORDER |
+ SWP_NOREPOSITION);
+ }
+ else // restore also min/max state
+ {
+ return GetResizableWnd()->SetWindowPlacement(&wp);
+ }
+ }
+ return FALSE;
+}
diff --git a/src/thirdparty/ui/ResizableLib/ResizableState.h b/src/thirdparty/ui/ResizableLib/ResizableState.h
new file mode 100644
index 000000000..1e5e7c35f
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/ResizableState.h
@@ -0,0 +1,38 @@
+// ResizableState.h: interface for the CResizableState class.
+//
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2000-2002 by Paolo Messina
+// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
+//
+// The contents of this file are subject to the Artistic License (the "License").
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+// http://www.opensource.org/licenses/artistic-license.html
+//
+// If you find this code useful, credits would be nice!
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_RESIZABLESTATE_H__INCLUDED_)
+#define AFX_RESIZABLESTATE_H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+class CResizableState
+{
+protected:
+ // non-zero if successful
+ BOOL LoadWindowRect(LPCTSTR pszSection, BOOL bRectOnly);
+ BOOL SaveWindowRect(LPCTSTR pszSection, BOOL bRectOnly);
+
+ virtual CWnd* GetResizableWnd() = 0;
+
+public:
+ CResizableState();
+ virtual ~CResizableState();
+};
+
+#endif // !defined(AFX_RESIZABLESTATE_H__INCLUDED_)
diff --git a/src/thirdparty/ui/ResizableLib/stdafx.cpp b/src/thirdparty/ui/ResizableLib/stdafx.cpp
new file mode 100644
index 000000000..a27b824da
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/stdafx.cpp
@@ -0,0 +1 @@
+#include "stdafx.h"
diff --git a/src/thirdparty/ui/ResizableLib/stdafx.h b/src/thirdparty/ui/ResizableLib/stdafx.h
new file mode 100644
index 000000000..ceeaf2054
--- /dev/null
+++ b/src/thirdparty/ui/ResizableLib/stdafx.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+#endif
+
+#include <afx.h>
+#include <afxwin.h> // MFC core and standard components
+#include <afxcmn.h>
+#include <afxdlgs.h>
diff --git a/src/thirdparty/ui/TreePropSheet/PropPageFrame.cpp b/src/thirdparty/ui/TreePropSheet/PropPageFrame.cpp
new file mode 100644
index 000000000..2cc570d33
--- /dev/null
+++ b/src/thirdparty/ui/TreePropSheet/PropPageFrame.cpp
@@ -0,0 +1,187 @@
+/********************************************************************
+*
+* Copyright (c) 2002 Sven Wiegand <mail@sven-wiegand.de>
+*
+* You can use this and modify this in any way you want,
+* BUT LEAVE THIS HEADER INTACT.
+*
+* Redistribution is appreciated.
+*
+* $Workfile:$
+* $Revision: 8 $
+* $Modtime:$
+* $Author: gabest $
+*
+* Revision History:
+* $History:$
+*
+*********************************************************************/
+
+#include "stdafx.h"
+#include "PropPageFrame.h"
+
+namespace TreePropSheet
+{
+
+
+//-------------------------------------------------------------------
+// class CPropPageFrame
+//-------------------------------------------------------------------
+
+CPropPageFrame::CPropPageFrame()
+: m_bShowCaption(FALSE),
+ m_nCaptionHeight(0),
+ m_hCaptionIcon(NULL),
+ m_dwMsgFormat(DT_CENTER|DT_VCENTER|DT_NOPREFIX|DT_SINGLELINE)
+{
+}
+
+
+CPropPageFrame::~CPropPageFrame()
+{
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Operations
+
+
+void CPropPageFrame::ShowCaption(BOOL bEnable)
+{
+ m_bShowCaption = bEnable;
+ SafeUpdateWindow(CalcCaptionArea());
+}
+
+
+BOOL CPropPageFrame::GetShowCaption() const
+{
+ return m_bShowCaption;
+}
+
+
+void CPropPageFrame::SetCaption(LPCTSTR lpszCaption, HICON hIcon /*= NULL*/)
+{
+ m_strCaption = lpszCaption;
+ m_hCaptionIcon = hIcon;
+ SafeUpdateWindow(CalcCaptionArea());
+}
+
+
+CString CPropPageFrame::GetCaption(HICON *pIcon /* = NULL */) const
+{
+ if (pIcon)
+ *pIcon = m_hCaptionIcon;
+ return m_strCaption;
+}
+
+
+void CPropPageFrame::SetCaptionHeight(int nCaptionHeight)
+{
+ m_nCaptionHeight = nCaptionHeight;
+ SafeUpdateWindow(CalcCaptionArea());
+}
+
+
+int CPropPageFrame::GetCaptionHeight() const
+{
+ return m_nCaptionHeight;
+}
+
+
+void CPropPageFrame::SetMsgText(LPCTSTR lpszMsg)
+{
+ m_strMsg = lpszMsg;
+ SafeUpdateWindow(CalcMsgArea());
+}
+
+
+CString CPropPageFrame::GetMsgText() const
+{
+ return m_strMsg;
+}
+
+
+void CPropPageFrame::SetMsgFormat(DWORD dwFormat)
+{
+ m_dwMsgFormat = dwFormat;
+ SafeUpdateWindow(CalcMsgArea());
+}
+
+
+DWORD CPropPageFrame::GetMsgFormat() const
+{
+ return m_dwMsgFormat;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Overridable implementation helpers
+
+void CPropPageFrame::Draw(CDC *pDc)
+{
+ if (GetShowCaption())
+ DrawCaption(pDc, CalcCaptionArea(), m_strCaption, m_hCaptionIcon);
+ DrawMsg(pDc, CalcMsgArea(), m_strMsg, m_dwMsgFormat);
+}
+
+
+CRect CPropPageFrame::CalcMsgArea()
+{
+ ASSERT(IsWindow(GetWnd()->GetSafeHwnd()));
+
+ CRect rectMsg;
+ GetWnd()->GetClientRect(rectMsg);
+ if (GetShowCaption())
+ rectMsg.top+= GetCaptionHeight();
+
+ return rectMsg;
+}
+
+
+void CPropPageFrame::DrawMsg(CDC *pDc, CRect rect, LPCTSTR /*lpszMsg*/, DWORD /*dwFormat*/)
+{
+ CFont *pPrevFont = dynamic_cast<CFont*>(pDc->SelectStockObject(DEFAULT_GUI_FONT));
+ int nPrevBkMode = pDc->SetBkMode(TRANSPARENT);
+
+ pDc->DrawText(GetMsgText(), rect, GetMsgFormat());
+
+ pDc->SetBkMode(nPrevBkMode);
+ pDc->SelectObject(pPrevFont);
+}
+
+
+CRect CPropPageFrame::CalcCaptionArea()
+{
+ ASSERT(IsWindow(GetWnd()->GetSafeHwnd()));
+
+ CRect rectCaption;
+ GetWnd()->GetClientRect(rectCaption);
+ if (!GetShowCaption())
+ rectCaption.bottom = rectCaption.top;
+ else
+ rectCaption.bottom = rectCaption.top+GetCaptionHeight();
+
+ return rectCaption;
+}
+
+
+void CPropPageFrame::DrawCaption(CDC* /*pDc*/, CRect /*rect*/, LPCTSTR /*lpszCaption*/, HICON /*hIcon*/)
+{
+ // should be implemented by specialized classes
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Implementation helpers
+
+void CPropPageFrame::SafeUpdateWindow(LPCRECT lpRect /* = NULL */)
+{
+ if (!IsWindow(GetWnd()->GetSafeHwnd()))
+ return;
+
+ GetWnd()->InvalidateRect(lpRect, TRUE);
+}
+
+
+
+} //namespace TreePropSheet
diff --git a/src/thirdparty/ui/TreePropSheet/PropPageFrame.h b/src/thirdparty/ui/TreePropSheet/PropPageFrame.h
new file mode 100644
index 000000000..9c8c63f5d
--- /dev/null
+++ b/src/thirdparty/ui/TreePropSheet/PropPageFrame.h
@@ -0,0 +1,306 @@
+/********************************************************************
+*
+* Copyright (c) 2002 Sven Wiegand <mail@sven-wiegand.de>
+*
+* You can use this and modify this in any way you want,
+* BUT LEAVE THIS HEADER INTACT.
+*
+* Redistribution is appreciated.
+*
+* $Workfile:$
+* $Revision: 126 $
+* $Modtime:$
+* $Author: gabest $
+*
+* Revision History:
+* $History:$
+*
+*********************************************************************/
+
+
+#if !defined(AFX_PROPPAGEFRAME_H__B968548B_F0B4_4C35_85DD_C44242A9D368__INCLUDED_)
+#define AFX_PROPPAGEFRAME_H__B968548B_F0B4_4C35_85DD_C44242A9D368__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+namespace TreePropSheet
+{
+
+
+/**
+An object of an CPropertyPageFrame-derived class is used by
+CTreePropSheet to display a frame for the property pages.
+
+Derived classes have to implement at least the Create() and the
+GetWnd() method, which
+returns a pointer to the CWnd-obect of the window, that has been
+created by the call to the Create() method. An implementation can
+provide the CWnd-object by using it as a property or by deriving
+from CWnd or a more specialiced class. This way has been choosen
+instead of deriving CPropPageFrame from CWnd, to allow derived class
+to derive from more specialized classes than CWnd
+(i.e. CStatic, etc.). From the WM_PAINT-handler of your derived class
+you have to call the Draw()-method.
+
+Most implementations will also implement the DrawCaption() and
+DrawMsg() methods, to provide custom drawing functionality.
+
+@author Sven Wiegand
+*/
+class /*AFX_EXT_CLASS*/ CPropPageFrame
+{
+// Construction/Destruction
+public:
+ CPropPageFrame();
+ virtual ~CPropPageFrame();
+
+// Operations
+public:
+ /**
+ Has to create a window with the specified properties.
+
+ @param dwWindowStyle
+ Standard window styles, to apply to the window to create.
+ @param rect
+ Position and size of the window to create.
+ @param pwndParent
+ Parent window. (Never be NULL).
+ @param nID
+ Window id.
+
+ @return
+ TRUE on success, FALSE otherwise.
+ */
+ virtual BOOL Create(DWORD dwWindowStyle, const RECT &rect, CWnd *pwndParent, UINT nID) = 0;
+
+ /**
+ Returns a pointer to the window object, that represents the frame.
+ */
+ virtual CWnd* GetWnd() = 0;
+
+ /**
+ Enables or disables page caption.
+
+ This default implementation calls the SafeUpdateWindow() method
+ with the caption rectangle, to force it to be redrawn.
+ */
+ virtual void ShowCaption(BOOL bEnable);
+
+ /**
+ Returns TRUE if captions are enabled, FALSE otherwise.
+ */
+ BOOL GetShowCaption() const;
+
+ /**
+ Sets the height of the caption in pixels. This value is ignored
+ until the caption is enabled by ShowCaption(TRUE).
+
+ This default implementation calls the SafeUpdateWindow() method
+ with the caption rectangle, to force it to be redrawn.
+ */
+ virtual void SetCaptionHeight(int nCaptionHeight);
+
+ /**
+ Returns the caption height, that has been most recently set by a
+ call to the SetCaptionHeight() method.
+ */
+ int GetCaptionHeight() const;
+
+ /**
+ Sets caption text an icon.
+
+ This default implementation calls the SafeUpdateWindow() method
+ with the caption rectangle, to force it to be redrawn.
+
+ @param lpszCaption
+ Text to display for the caption.
+ @param hIcon
+ Icon to display for the caption.
+ */
+ virtual void SetCaption(LPCTSTR lpszCaption, HICON hIcon = NULL);
+
+ /**
+ Returns the caption, that has been set most recently using the
+ SetCaption() method.
+
+ @param pIcon
+ Pointer to a HICON variable, that should receive the handle of
+ the currently set icon or NULL, if there is no icon or a NULL
+ pointer, if the caller is not interested in the icon.
+
+ @return
+ The text that has been set most recently using the SetCaption()
+ method.
+ */
+ CString GetCaption(HICON *pIcon = NULL) const;
+
+ /**
+ Sets the text to display.
+
+ This default implementation calls the SafeUpdateWindow() method
+ with the message rectangle, to force it to be redrawn.
+ */
+ virtual void SetMsgText(LPCTSTR lpszMsg);
+
+ /**
+ Returns the text currently displayed.
+ */
+ CString GetMsgText() const;
+
+ /**
+ Specifies the format to draw the text with, set by SetMsgText().
+
+ This default implementation calls the SafeUpdateWindow() method
+ with the message rectangle, to force it to be redrawn.
+
+ @param dwFormat
+ Combination of the DT_* flags, specified by the Win32 function
+ DrawText().
+ */
+ virtual void SetMsgFormat(DWORD dwFormat);
+
+ /**
+ Returns the format to draw the text with, set by SetMsgText().
+
+ @see SetMsgFormat()
+ */
+ DWORD GetMsgFormat() const;
+
+// Overridable implementation helpers
+protected:
+ /**
+ Draws the whole frame including caption (if enabled) and message.
+
+ This method calculates the rectangles for the message area and
+ the caption area using the CalcMsgArea() and the CalcCaptionArea()
+ methods, draws then the caption calling the DrawCaption() method
+ (only if caption is enabled) and afterwards the message calling
+ the DrawMsg() method.
+
+ You should call this method from the WM_PAINT-handler of your
+ derived class.
+
+ @param pDc
+ Device context to draw in.
+ */
+ virtual void Draw(CDC *pDc);
+
+ /**
+ Calculates the area, the message, set by SetMsgText() should be
+ displayed in. The returned rectangle (client coordinates) will be
+ passed to DrawMsg().
+
+ This default implementation calls the CalcCaptionArea() method,
+ substracts the returned rectangle from the client area and returns
+ the result.
+ */
+ virtual CRect CalcMsgArea();
+
+ /**
+ Draws the message with the specified format.
+
+ This default implementation draws the given msg using the specified
+ properties.
+
+ @param pDc
+ Device context to draw in.
+ @param rect
+ Rectangle to draw the message in.
+ @param lpszMsg
+ Message to draw.
+ @param dwFormat.
+ Combination of the DT_* flags, specified by the Win32 function
+ DrawText() to draw the message with.
+ */
+ virtual void DrawMsg(CDC *pDc, CRect rect, LPCTSTR lpszMsg, DWORD dwFormat);
+
+ /**
+ Calculates the caption area. The caption area is the rectangular
+ range, the current page's caption should be drawn in.
+
+ The caption can be enabled or disabled using the ShowCaption()
+ method. This method should return an empty rect, if the caption
+ is disabled. If the caption is enabled the height of the rect
+ should be as large, as specified by the latest call to the
+ SetCaptionHeight() method.
+
+ The rectangle, returned by this method will be passed to the
+ DrawCaption() method to draw the caption.
+
+ If the caption is enabled currently, this default implementation
+ returns a rectangle, that has the width of the client area and
+ the height, specified by the latest call to SetCaptionHeight(),
+ starting and y-position 0. If the caption is disabled at the
+ moment, this method returns an empty rectangle with the width of
+ the client area.
+ */
+ virtual CRect CalcCaptionArea();
+
+ /**
+ Draws the caption.
+
+ This default implementation draws nothing.
+
+ @param pDc
+ Device context to draw in.
+ @param rect
+ Rectangle to draw the caption in.
+ @param lpszCaption
+ Text to display in the caption.
+ @param hIcon
+ Icon to display in the caption.
+ */
+ virtual void DrawCaption(CDC *pDc, CRect rect, LPCTSTR lpszCaption, HICON hIcon);
+
+// Implementation helpers
+protected:
+ /**
+ If the m_hWnd property of the CWnd-object returend by GetWnd()
+ specifies a valid window, this method will invalidate the specified
+ rectangle, to schedule it for repaint, otherwise the method will
+ return without doing anything.
+
+ @param lpRect
+ Pointer to the rectangular area, that should be marked for
+ repainting or NULL, if the whole client area should be marked
+ for repainting.
+ */
+ void SafeUpdateWindow(LPCRECT lpRect = NULL);
+
+// Properties
+private:
+ /** TRUE if the caption should be drawn, FALSE otherwise. */
+ BOOL m_bShowCaption;
+
+ /** Height of the caption in pixels, if it is enabled. */
+ int m_nCaptionHeight;
+
+ /** Text to display in the caption. */
+ CString m_strCaption;
+
+ /**
+ Icon to display in the caption or NULL if no icon should be
+ displayed.
+ */
+ HICON m_hCaptionIcon;
+
+ /** Message text to display. */
+ CString m_strMsg;
+
+ /** Style to use when drawing the message text m_strMsg. */
+ DWORD m_dwMsgFormat;
+};
+
+
+} //namespace TreePropSheet
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ fügt unmittelbar vor der vorhergehenden Zeile zusätzliche Deklarationen ein.
+
+#endif // AFX_PROPPAGEFRAME_H__B968548B_F0B4_4C35_85DD_C44242A9D368__INCLUDED_
diff --git a/src/thirdparty/ui/TreePropSheet/PropPageFrameDefault.cpp b/src/thirdparty/ui/TreePropSheet/PropPageFrameDefault.cpp
new file mode 100644
index 000000000..a0da46b5d
--- /dev/null
+++ b/src/thirdparty/ui/TreePropSheet/PropPageFrameDefault.cpp
@@ -0,0 +1,393 @@
+/********************************************************************
+*
+* Copyright (c) 2002 Sven Wiegand <mail@sven-wiegand.de>
+*
+* You can use this and modify this in any way you want,
+* BUT LEAVE THIS HEADER INTACT.
+*
+* Redistribution is appreciated.
+*
+* $Workfile:$
+* $Revision: 8 $
+* $Modtime:$
+* $Author: gabest $
+*
+* Revision History:
+* $History:$
+*
+*********************************************************************/
+
+#include "stdafx.h"
+#include "PropPageFrameDefault.h"
+
+
+namespace TreePropSheet
+{
+
+
+//uncomment the following line, if you don't have installed the
+//new platform SDK
+#define XPSUPPORT
+
+#ifdef XPSUPPORT
+#include <uxtheme.h>
+#include <vssym32.h>
+#endif
+
+//-------------------------------------------------------------------
+// class CThemeLib
+//-------------------------------------------------------------------
+
+#define THEMEAPITYPE(f) typedef HRESULT (__stdcall *_##f)
+#define THEMEAPITYPE_(t, f) typedef t (__stdcall *_##f)
+#define THEMEAPIPTR(f) _##f m_p##f
+
+#ifdef XPSUPPORT
+ #define THEMECALL(f) return (*m_p##f)
+ #define GETTHEMECALL(f) m_p##f = (_##f)GetProcAddress(m_hThemeLib, #f)
+#else
+ void ThemeDummy(...) {ASSERT(FALSE);}
+ #define HTHEME void*
+ #define TABP_PANE 0
+ #define THEMECALL(f) return 0; ThemeDummy
+ #define GETTHEMECALL(f) m_p##f = NULL
+#endif
+
+
+/**
+Helper class for loading the uxtheme DLL and providing their
+functions.
+
+One global object of this class exists.
+
+@author Sven Wiegand
+*/
+class CThemeLib
+{
+// construction/destruction
+public:
+ CThemeLib();
+ ~CThemeLib();
+
+// operations
+public:
+ /**
+ Returns TRUE if the call wrappers are available, FALSE otherwise.
+ */
+ BOOL IsAvailable() const;
+
+// call wrappers
+public:
+ BOOL IsThemeActive() const
+ {THEMECALL(IsThemeActive)();}
+
+ HTHEME OpenThemeData(HWND hwnd, LPCWSTR pszClassList) const
+ {THEMECALL(OpenThemeData)(hwnd, pszClassList);}
+
+ HRESULT CloseThemeData(HTHEME hTheme) const
+ {THEMECALL(CloseThemeData)(hTheme);}
+
+ HRESULT GetThemeBackgroundContentRect(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, const RECT *pBoundingRect, OUT RECT *pContentRect) const
+ {THEMECALL(GetThemeBackgroundContentRect)(hTheme, hdc, iPartId, iStateId, pBoundingRect, pContentRect);}
+
+ HRESULT DrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect) const
+ {THEMECALL(DrawThemeBackground)(hTheme, hdc, iPartId, iStateId, pRect, pClipRect);}
+
+// function pointers
+private:
+#ifdef XPSUPPORT
+ THEMEAPITYPE_(BOOL, IsThemeActive)();
+ THEMEAPIPTR(IsThemeActive);
+
+ THEMEAPITYPE_(HTHEME, OpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
+ THEMEAPIPTR(OpenThemeData);
+
+ THEMEAPITYPE(CloseThemeData)(HTHEME hTheme);
+ THEMEAPIPTR(CloseThemeData);
+
+ THEMEAPITYPE(GetThemeBackgroundContentRect)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, const RECT *pBoundingRect, OUT RECT *pContentRect);
+ THEMEAPIPTR(GetThemeBackgroundContentRect);
+
+ THEMEAPITYPE(DrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
+ THEMEAPIPTR(DrawThemeBackground);
+#endif
+
+// properties
+private:
+ /** instance handle to the library or NULL. */
+ HINSTANCE m_hThemeLib;
+};
+
+/**
+One and only instance of CThemeLib.
+*/
+static CThemeLib g_ThemeLib;
+
+
+CThemeLib::CThemeLib()
+: m_hThemeLib(NULL)
+{
+#ifdef XPSUPPORT
+ m_hThemeLib = LoadLibrary(_T("uxtheme.dll"));
+ if (!m_hThemeLib)
+ return;
+
+ GETTHEMECALL(IsThemeActive);
+ GETTHEMECALL(OpenThemeData);
+ GETTHEMECALL(CloseThemeData);
+ GETTHEMECALL(GetThemeBackgroundContentRect);
+ GETTHEMECALL(DrawThemeBackground);
+#endif
+}
+
+
+CThemeLib::~CThemeLib()
+{
+ if (m_hThemeLib)
+ FreeLibrary(m_hThemeLib);
+}
+
+
+BOOL CThemeLib::IsAvailable() const
+{
+ return m_hThemeLib!=NULL;
+}
+
+
+//-------------------------------------------------------------------
+// class CPropPageFrameDefault
+//-------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP(CPropPageFrameDefault, CWnd)
+ //{{AFX_MSG_MAP(CPropPageFrameDefault)
+ ON_WM_PAINT()
+ ON_WM_ERASEBKGND()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+CPropPageFrameDefault::CPropPageFrameDefault()
+{
+}
+
+
+CPropPageFrameDefault::~CPropPageFrameDefault()
+{
+ if (m_Images.GetSafeHandle())
+ m_Images.DeleteImageList();
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Overridings
+
+BOOL CPropPageFrameDefault::Create(DWORD dwWindowStyle, const RECT &rect, CWnd *pwndParent, UINT nID)
+{
+ return CWnd::Create(
+ AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, AfxGetApp()->LoadStandardCursor(IDC_ARROW), GetSysColorBrush(COLOR_3DFACE)),
+ _T("Page Frame"),
+ dwWindowStyle, rect, pwndParent, nID);
+}
+
+CWnd* CPropPageFrameDefault::GetWnd()
+{
+ return static_cast<CWnd*>(this);
+}
+
+void CPropPageFrameDefault::SetCaption(LPCTSTR lpszCaption, HICON hIcon /*= NULL*/)
+{
+ CPropPageFrame::SetCaption(lpszCaption, hIcon);
+
+ // build image list
+ if (m_Images.GetSafeHandle())
+ m_Images.DeleteImageList();
+ if (hIcon)
+ {
+ ICONINFO ii;
+ if (!GetIconInfo(hIcon, &ii))
+ return;
+
+ CBitmap bmMask;
+ bmMask.Attach(ii.hbmMask);
+ if (ii.hbmColor) DeleteObject(ii.hbmColor);
+
+ BITMAP bm;
+ bmMask.GetBitmap(&bm);
+
+ if (!m_Images.Create(bm.bmWidth, bm.bmHeight, ILC_COLOR32|ILC_MASK, 0, 1))
+ return;
+
+ if (m_Images.Add(hIcon) == -1)
+ m_Images.DeleteImageList();
+ }
+}
+
+CRect CPropPageFrameDefault::CalcMsgArea()
+{
+ CRect rect;
+ GetClientRect(rect);
+ if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive())
+ {
+ HTHEME hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"Tab");
+ if (hTheme)
+ {
+ CRect rectContent;
+ CDC *pDc = GetDC();
+ g_ThemeLib.GetThemeBackgroundContentRect(hTheme, pDc->m_hDC, TABP_PANE, 0, rect, rectContent);
+ ReleaseDC(pDc);
+ g_ThemeLib.CloseThemeData(hTheme);
+
+ if (GetShowCaption())
+ rectContent.top = rect.top+GetCaptionHeight()+1;
+ rect = rectContent;
+ }
+ }
+ else if (GetShowCaption())
+ rect.top+= GetCaptionHeight()+1;
+
+ return rect;
+}
+
+
+CRect CPropPageFrameDefault::CalcCaptionArea()
+{
+ CRect rect;
+ GetClientRect(rect);
+ if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive())
+ {
+ HTHEME hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"Tab");
+ if (hTheme)
+ {
+ CRect rectContent;
+ CDC *pDc = GetDC();
+ g_ThemeLib.GetThemeBackgroundContentRect(hTheme, pDc->m_hDC, TABP_PANE, 0, rect, rectContent);
+ ReleaseDC(pDc);
+ g_ThemeLib.CloseThemeData(hTheme);
+
+ if (GetShowCaption())
+ rectContent.bottom = rect.top+GetCaptionHeight();
+ else
+ rectContent.bottom = rectContent.top;
+
+ rect = rectContent;
+ }
+ }
+ else
+ {
+ if (GetShowCaption())
+ rect.bottom = rect.top+GetCaptionHeight();
+ else
+ rect.bottom = rect.top;
+ }
+
+ return rect;
+}
+
+void CPropPageFrameDefault::DrawCaption(CDC *pDc, CRect rect, LPCTSTR lpszCaption, HICON hIcon)
+{
+ COLORREF clrLeft = GetSysColor(COLOR_INACTIVECAPTION);
+ COLORREF clrRight = pDc->GetPixel(rect.right-1, rect.top);
+ FillGradientRectH(pDc, rect, clrLeft, clrRight);
+
+ // draw icon
+ if (hIcon && m_Images.GetSafeHandle() && m_Images.GetImageCount() == 1)
+ {
+ IMAGEINFO ii;
+ m_Images.GetImageInfo(0, &ii);
+ CPoint pt(3, rect.CenterPoint().y - (ii.rcImage.bottom-ii.rcImage.top)/2);
+ m_Images.Draw(pDc, 0, pt, ILD_TRANSPARENT);
+ rect.left+= (ii.rcImage.right-ii.rcImage.left) + 3;
+ }
+
+ // draw text
+ rect.left+= 2;
+
+ COLORREF clrPrev = pDc->SetTextColor(GetSysColor(COLOR_CAPTIONTEXT));
+ int nBkStyle = pDc->SetBkMode(TRANSPARENT);
+ CFont *pFont = (CFont*)pDc->SelectStockObject(SYSTEM_FONT);
+
+ CFont* pSysFont = pDc->GetCurrentFont();
+ LOGFONT lf;
+ pSysFont->GetLogFont(&lf);
+ lf.lfHeight = rect.Height();
+ lf.lfWidth = 0;
+ _tcscpy(lf.lfFaceName, _T("Arial"));
+ CFont f;
+ f.CreateFontIndirect(&lf);
+ pDc->SelectObject(&f);
+
+ pDc->DrawText(lpszCaption, rect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS);
+
+ pDc->SetTextColor(clrPrev);
+ pDc->SetBkMode(nBkStyle);
+ pDc->SelectObject(pFont);
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Implementation helpers
+
+void CPropPageFrameDefault::FillGradientRectH(CDC *pDc, const RECT &rect, COLORREF clrLeft, COLORREF clrRight)
+{
+ // pre calculation
+ int nSteps = rect.right-rect.left;
+ int nRRange = GetRValue(clrRight)-GetRValue(clrLeft);
+ int nGRange = GetGValue(clrRight)-GetGValue(clrLeft);
+ int nBRange = GetBValue(clrRight)-GetBValue(clrLeft);
+
+ double dRStep = (double)nRRange/(double)nSteps;
+ double dGStep = (double)nGRange/(double)nSteps;
+ double dBStep = (double)nBRange/(double)nSteps;
+
+ double dR = (double)GetRValue(clrLeft);
+ double dG = (double)GetGValue(clrLeft);
+ double dB = (double)GetBValue(clrLeft);
+
+ CPen *pPrevPen = NULL;
+ for (int x = rect.left; x <= rect.right; ++x)
+ {
+ CPen Pen(PS_SOLID, 1, RGB((BYTE)dR, (BYTE)dG, (BYTE)dB));
+ pPrevPen = pDc->SelectObject(&Pen);
+ pDc->MoveTo(x, rect.top);
+ pDc->LineTo(x, rect.bottom);
+ pDc->SelectObject(pPrevPen);
+
+ dR+= dRStep;
+ dG+= dGStep;
+ dB+= dBStep;
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// message handlers
+
+void CPropPageFrameDefault::OnPaint()
+{
+ CPaintDC dc(this);
+ Draw(&dc);
+}
+
+
+BOOL CPropPageFrameDefault::OnEraseBkgnd(CDC* pDC)
+{
+ if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive())
+ {
+ HTHEME hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"Tab");
+ if (hTheme)
+ {
+ CRect rect;
+ GetClientRect(rect);
+ g_ThemeLib.DrawThemeBackground(hTheme, pDC->m_hDC, TABP_PANE, 0, rect, NULL);
+
+ g_ThemeLib.CloseThemeData(hTheme);
+ }
+ return TRUE;
+ }
+ else
+ {
+ return CWnd::OnEraseBkgnd(pDC);
+ }
+}
+
+} //namespace TreePropSheet
diff --git a/src/thirdparty/ui/TreePropSheet/PropPageFrameDefault.h b/src/thirdparty/ui/TreePropSheet/PropPageFrameDefault.h
new file mode 100644
index 000000000..0e0523151
--- /dev/null
+++ b/src/thirdparty/ui/TreePropSheet/PropPageFrameDefault.h
@@ -0,0 +1,119 @@
+/********************************************************************
+*
+* Copyright (c) 2002 Sven Wiegand <mail@sven-wiegand.de>
+*
+* You can use this and modify this in any way you want,
+* BUT LEAVE THIS HEADER INTACT.
+*
+* Redistribution is appreciated.
+*
+* $Workfile:$
+* $Revision: 126 $
+* $Modtime:$
+* $Author: gabest $
+*
+* Revision History:
+* $History:$
+*
+*********************************************************************/
+
+
+#if !defined(AFX_PROPPAGEFRAMEDEFAULT_H__5C5B7AC9_2DF5_4E8C_8F5E_DE2CC04BBED7__INCLUDED_)
+#define AFX_PROPPAGEFRAMEDEFAULT_H__5C5B7AC9_2DF5_4E8C_8F5E_DE2CC04BBED7__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "PropPageFrame.h"
+#include <afxcmn.h>
+
+
+namespace TreePropSheet
+{
+
+
+/**
+An implementation of CPropPageFrame, that works well for Windows XP
+styled systems and older windows versions (without themes).
+
+@author Sven Wiegand
+*/
+class /*AFX_EXT_CLASS*/ CPropPageFrameDefault : public CWnd,
+ public CPropPageFrame
+{
+// construction/destruction
+public:
+ CPropPageFrameDefault();
+ virtual ~CPropPageFrameDefault();
+
+// operations
+public:
+
+// overridings
+public:
+ virtual BOOL Create(DWORD dwWindowStyle, const RECT &rect, CWnd *pwndParent, UINT nID);
+ virtual CWnd* GetWnd();
+ virtual void SetCaption(LPCTSTR lpszCaption, HICON hIcon = NULL);
+
+
+protected:
+ virtual CRect CalcMsgArea();
+ virtual CRect CalcCaptionArea();
+ virtual void DrawCaption(CDC *pDc, CRect rect, LPCTSTR lpszCaption, HICON hIcon);
+
+// Implementation helpers
+protected:
+ /**
+ Fills a rectangular area with a gradient color starting at the left
+ side with the color clrLeft and ending at the right sight with the
+ color clrRight.
+
+ @param pDc
+ Device context to draw the rectangle in.
+ @param rect
+ Rectangular area to fill.
+ @param clrLeft
+ Color on the left side.
+ @param clrRight
+ Color on the right side.
+ */
+ void FillGradientRectH(CDC *pDc, const RECT &rect, COLORREF clrLeft, COLORREF clrRight);
+
+ /**
+ Returns TRUE if Windows XP theme support is available, FALSE
+ otherwise.
+ */
+ BOOL ThemeSupport() const;
+
+protected:
+ //{{AFX_VIRTUAL(CPropPageFrameDefault)
+ //}}AFX_VIRTUAL
+
+// message handlers
+protected:
+ //{{AFX_MSG(CPropPageFrameDefault)
+ afx_msg void OnPaint();
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+
+// attributes
+protected:
+ /**
+ Image list that contains only the current icon or nothing if there
+ is no icon.
+ */
+ CImageList m_Images;
+};
+
+
+} //namespace TreePropSheet
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ fügt unmittelbar vor der vorhergehenden Zeile zusätzliche Deklarationen ein.
+
+#endif // AFX_PROPPAGEFRAMEDEFAULT_H__5C5B7AC9_2DF5_4E8C_8F5E_DE2CC04BBED7__INCLUDED_
diff --git a/src/thirdparty/ui/TreePropSheet/TreePropSheet.cpp b/src/thirdparty/ui/TreePropSheet/TreePropSheet.cpp
new file mode 100644
index 000000000..866e0e423
--- /dev/null
+++ b/src/thirdparty/ui/TreePropSheet/TreePropSheet.cpp
@@ -0,0 +1,982 @@
+/********************************************************************
+*
+* Copyright (c) 2002 Sven Wiegand <mail@sven-wiegand.de>
+*
+* You can use this and modify this in any way you want,
+* BUT LEAVE THIS HEADER INTACT.
+*
+* Redistribution is appreciated.
+*
+* $Workfile:$
+* $Revision: 126 $
+* $Modtime:$
+* $Author: gabest $
+*
+* Revision History:
+* $History:$
+*
+*********************************************************************/
+
+
+#include "stdafx.h"
+#include "TreePropSheet.h"
+#include "PropPageFrameDefault.h"
+
+
+namespace TreePropSheet
+{
+
+//-------------------------------------------------------------------
+// class CTreePropSheet
+//-------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP(CTreePropSheet, CPropertySheet)
+ //{{AFX_MSG_MAP(CTreePropSheet)
+ ON_WM_DESTROY()
+ //}}AFX_MSG_MAP
+ ON_MESSAGE(PSM_ADDPAGE, OnAddPage)
+ ON_MESSAGE(PSM_REMOVEPAGE, OnRemovePage)
+ ON_MESSAGE(PSM_SETCURSEL, OnSetCurSel)
+ ON_MESSAGE(PSM_SETCURSELID, OnSetCurSelId)
+ ON_MESSAGE(PSM_ISDIALOGMESSAGE, OnIsDialogMessage)
+
+ ON_NOTIFY(TVN_SELCHANGINGA, s_unPageTreeId, OnPageTreeSelChanging)
+ ON_NOTIFY(TVN_SELCHANGINGW, s_unPageTreeId, OnPageTreeSelChanging)
+ ON_NOTIFY(TVN_SELCHANGEDA, s_unPageTreeId, OnPageTreeSelChanged)
+ ON_NOTIFY(TVN_SELCHANGEDW, s_unPageTreeId, OnPageTreeSelChanged)
+END_MESSAGE_MAP()
+
+IMPLEMENT_DYNAMIC(CTreePropSheet, CPropertySheet)
+
+const UINT CTreePropSheet::s_unPageTreeId = 0x7EEE;
+
+CTreePropSheet::CTreePropSheet()
+: m_bPageTreeSelChangedActive(FALSE),
+ m_bTreeViewMode(TRUE),
+ m_bPageCaption(FALSE),
+ m_bTreeImages(FALSE),
+ m_nPageTreeWidth(150),
+ m_pwndPageTree(NULL),
+ m_pFrame(NULL)
+{}
+
+
+CTreePropSheet::CTreePropSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
+: CPropertySheet(nIDCaption, pParentWnd, iSelectPage),
+ m_bPageTreeSelChangedActive(FALSE),
+ m_bTreeViewMode(TRUE),
+ m_bPageCaption(FALSE),
+ m_bTreeImages(FALSE),
+ m_nPageTreeWidth(150),
+ m_pwndPageTree(NULL),
+ m_pFrame(NULL)
+{
+}
+
+
+CTreePropSheet::CTreePropSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
+: CPropertySheet(pszCaption, pParentWnd, iSelectPage),
+ m_bPageTreeSelChangedActive(FALSE),
+ m_bTreeViewMode(TRUE),
+ m_bPageCaption(FALSE),
+ m_bTreeImages(FALSE),
+ m_nPageTreeWidth(150),
+ m_pwndPageTree(NULL),
+ m_pFrame(NULL)
+{
+}
+
+
+CTreePropSheet::~CTreePropSheet()
+{
+ if(m_Images.GetSafeHandle()) m_Images.DeleteImageList();
+ delete m_pwndPageTree, m_pwndPageTree = NULL;
+ delete m_pFrame, m_pFrame = NULL;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Operationen
+
+BOOL CTreePropSheet::SetTreeViewMode(BOOL bTreeViewMode /* = TRUE */, BOOL bPageCaption /* = FALSE */, BOOL bTreeImages /* = FALSE */)
+{
+ if (IsWindow(m_hWnd))
+ {
+ // needs to becalled, before the window has been created
+ ASSERT(FALSE);
+ return FALSE;
+ }
+
+ m_bTreeViewMode = bTreeViewMode;
+ if (m_bTreeViewMode)
+ {
+ m_bPageCaption = bPageCaption;
+ m_bTreeImages = bTreeImages;
+ }
+
+ return TRUE;
+}
+
+
+BOOL CTreePropSheet::SetTreeWidth(int nWidth)
+{
+ if (IsWindow(m_hWnd))
+ {
+ // needs to be called, before the window is created.
+ ASSERT(FALSE);
+ return FALSE;
+ }
+
+ m_nPageTreeWidth = nWidth;
+
+ return TRUE;
+}
+
+
+void CTreePropSheet::SetEmptyPageText(LPCTSTR lpszEmptyPageText)
+{
+ m_strEmptyPageMessage = lpszEmptyPageText;
+}
+
+
+DWORD CTreePropSheet::SetEmptyPageTextFormat(DWORD dwFormat)
+{
+ DWORD dwPrevFormat = m_pFrame->GetMsgFormat();
+ m_pFrame->SetMsgFormat(dwFormat);
+ return dwPrevFormat;
+}
+
+
+BOOL CTreePropSheet::SetTreeDefaultImages(CImageList *pImages)
+{
+ if (pImages->GetImageCount() != 2)
+ {
+ ASSERT(FALSE);
+ return FALSE;
+ }
+
+ if (m_DefaultImages.GetSafeHandle())
+ m_DefaultImages.DeleteImageList();
+ m_DefaultImages.Create(pImages);
+
+ // update, if necessary
+ if (IsWindow(m_hWnd))
+ RefillPageTree();
+
+ return TRUE;
+}
+
+
+BOOL CTreePropSheet::SetTreeDefaultImages(UINT unBitmapID, int cx, COLORREF crMask)
+{
+ if (m_DefaultImages.GetSafeHandle())
+ m_DefaultImages.DeleteImageList();
+ if (!m_DefaultImages.Create(unBitmapID, cx, 0, crMask))
+ return FALSE;
+
+ if (m_DefaultImages.GetImageCount() != 2)
+ {
+ m_DefaultImages.DeleteImageList();
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+CTreeCtrl* CTreePropSheet::GetPageTreeControl()
+{
+ return m_pwndPageTree;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// public helpers
+
+BOOL CTreePropSheet::SetPageIcon(CPropertyPage *pPage, HICON hIcon)
+{
+ pPage->m_psp.dwFlags|= PSP_USEHICON;
+ pPage->m_psp.hIcon = hIcon;
+ return TRUE;
+}
+
+
+BOOL CTreePropSheet::SetPageIcon(CPropertyPage *pPage, UINT unIconId)
+{
+ HICON hIcon = AfxGetApp()->LoadIcon(unIconId);
+ if (!hIcon)
+ return FALSE;
+
+ return SetPageIcon(pPage, hIcon);
+}
+
+
+BOOL CTreePropSheet::SetPageIcon(CPropertyPage *pPage, CImageList &Images, int nImage)
+{
+ HICON hIcon = Images.ExtractIcon(nImage);
+ if (!hIcon)
+ return FALSE;
+
+ return SetPageIcon(pPage, hIcon);
+}
+
+
+BOOL CTreePropSheet::DestroyPageIcon(CPropertyPage *pPage)
+{
+ if (!pPage || !(pPage->m_psp.dwFlags&PSP_USEHICON) || !pPage->m_psp.hIcon)
+ return FALSE;
+
+ DestroyIcon(pPage->m_psp.hIcon);
+ pPage->m_psp.dwFlags&= ~PSP_USEHICON;
+ pPage->m_psp.hIcon = NULL;
+
+ return TRUE;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Overridable implementation helpers
+
+CString CTreePropSheet::GenerateEmptyPageMessage(LPCTSTR lpszEmptyPageMessage, LPCTSTR lpszCaption)
+{
+ CString strMsg;
+ strMsg.Format(lpszEmptyPageMessage, lpszCaption);
+ return strMsg;
+}
+
+
+CTreeCtrl* CTreePropSheet::CreatePageTreeObject()
+{
+ return DNew CTreeCtrl;
+}
+
+
+CPropPageFrame* CTreePropSheet::CreatePageFrame()
+{
+ return DNew CPropPageFrameDefault;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Implementation helpers
+
+void CTreePropSheet::MoveChildWindows(int nDx, int nDy)
+{
+ CWnd *pWnd = GetWindow(GW_CHILD);
+ while (pWnd)
+ {
+ CRect rect;
+ pWnd->GetWindowRect(rect);
+ rect.OffsetRect(nDx, nDy);
+ ScreenToClient(rect);
+ pWnd->MoveWindow(rect);
+
+ pWnd = pWnd->GetNextWindow();
+ }
+}
+
+
+void CTreePropSheet::RefillPageTree()
+{
+ if (!IsWindow(m_hWnd))
+ return;
+
+ m_pwndPageTree->DeleteAllItems();
+
+ CTabCtrl *pTabCtrl = GetTabControl();
+ if (!IsWindow(pTabCtrl->GetSafeHwnd()))
+ {
+ ASSERT(FALSE);
+ return;
+ }
+
+ const int nPageCount = pTabCtrl->GetItemCount();
+
+ // rebuild image list
+ if (m_bTreeImages)
+ {
+ for (int i = m_Images.GetImageCount()-1; i >= 0; --i)
+ m_Images.Remove(i);
+
+ // add page images
+ CImageList *pPageImages = pTabCtrl->GetImageList();
+ if (pPageImages)
+ {
+ for (int nImage = 0; nImage < pPageImages->GetImageCount(); ++nImage)
+ {
+ HICON hIcon = pPageImages->ExtractIcon(nImage);
+ m_Images.Add(hIcon);
+ DestroyIcon(hIcon);
+ }
+ }
+
+ // add default images
+ if (m_DefaultImages.GetSafeHandle())
+ {
+ HICON hIcon;
+
+ // add default images
+ hIcon = m_DefaultImages.ExtractIcon(0);
+ if (hIcon)
+ {
+ m_Images.Add(hIcon);
+ DestroyIcon(hIcon);
+ }
+ hIcon = m_DefaultImages.ExtractIcon(1);
+ {
+ m_Images.Add(hIcon);
+ DestroyIcon(hIcon);
+ }
+ }
+ }
+
+ // insert tree items
+ for (int nPage = 0; nPage < nPageCount; ++nPage)
+ {
+ // Get title and image of the page
+ CString strPagePath;
+
+ TCITEM ti;
+ ZeroMemory(&ti, sizeof(ti));
+ ti.mask = TCIF_TEXT|TCIF_IMAGE;
+ ti.cchTextMax = MAX_PATH;
+ ti.pszText = strPagePath.GetBuffer(ti.cchTextMax);
+ ASSERT(ti.pszText);
+ if (!ti.pszText)
+ return;
+
+ pTabCtrl->GetItem(nPage, &ti);
+ strPagePath.ReleaseBuffer();
+
+ // Create an item in the tree for the page
+ HTREEITEM hItem = CreatePageTreeItem(ti.pszText);
+ ASSERT(hItem);
+ if (hItem)
+ {
+ m_pwndPageTree->SetItemData(hItem, nPage);
+
+ // set image
+ if (m_bTreeImages)
+ {
+ int nImage = ti.iImage;
+ if (nImage < 0 || nImage >= m_Images.GetImageCount())
+ nImage = m_DefaultImages.GetSafeHandle()? m_Images.GetImageCount()-1 : -1;
+
+ m_pwndPageTree->SetItemImage(hItem, nImage, nImage);
+ }
+ }
+ }
+}
+
+
+HTREEITEM CTreePropSheet::CreatePageTreeItem(LPCTSTR lpszPath, HTREEITEM hParent /* = TVI_ROOT */)
+{
+ CString strPath(lpszPath);
+ CString strTopMostItem(SplitPageTreePath(strPath));
+
+ // Check if an item with the given text does already exist
+ HTREEITEM hItem = NULL;
+ HTREEITEM hChild = m_pwndPageTree->GetChildItem(hParent);
+ while (hChild)
+ {
+ if (m_pwndPageTree->GetItemText(hChild) == strTopMostItem)
+ {
+ hItem = hChild;
+ break;
+ }
+ hChild = m_pwndPageTree->GetNextItem(hChild, TVGN_NEXT);
+ }
+
+ // If item with that text does not already exist, create a new one
+ if (!hItem)
+ {
+ hItem = m_pwndPageTree->InsertItem(strTopMostItem, hParent);
+ m_pwndPageTree->SetItemData(hItem, (DWORD_PTR)-1);
+ if (!strPath.IsEmpty() && m_bTreeImages && m_DefaultImages.GetSafeHandle())
+ // set folder image
+ m_pwndPageTree->SetItemImage(hItem, m_Images.GetImageCount()-2, m_Images.GetImageCount()-2);
+ }
+ if (!hItem)
+ {
+ ASSERT(FALSE);
+ return NULL;
+ }
+
+ if (strPath.IsEmpty())
+ return hItem;
+ else
+ return CreatePageTreeItem(strPath, hItem);
+}
+
+
+CString CTreePropSheet::SplitPageTreePath(CString &strRest)
+{
+ int nSeperatorPos = 0;
+ while (TRUE)
+ {
+ nSeperatorPos = strRest.Find(_T("::"), nSeperatorPos);
+ if (nSeperatorPos == -1)
+ {
+ CString strItem(strRest);
+ strRest.Empty();
+ return strItem;
+ }
+ else if (nSeperatorPos>0)
+ {
+ // if there is an odd number of backslashes infront of the
+ // seperator, than do not interpret it as separator
+ int nBackslashCount = 0;
+ for (int nPos = nSeperatorPos-1; nPos >= 0 && strRest[nPos]==_T('\\'); --nPos, ++nBackslashCount);
+ if (nBackslashCount%2 == 0)
+ break;
+ else
+ ++nSeperatorPos;
+ }
+ }
+
+ CString strItem(strRest.Left(nSeperatorPos));
+ strItem.Replace(_T("\\::"), _T("::"));
+ strItem.Replace(_T("\\\\"), _T("\\"));
+ strRest = strRest.Mid(nSeperatorPos+2);
+ return strItem;
+}
+
+
+BOOL CTreePropSheet::KillActiveCurrentPage()
+{
+ HWND hCurrentPage = PropSheet_GetCurrentPageHwnd(m_hWnd);
+ if (!IsWindow(hCurrentPage))
+ {
+ ASSERT(FALSE);
+ return TRUE;
+ }
+
+ // Check if the current page is really active (if page is invisible
+ // an virtual empty page is the active one.
+ if (!::IsWindowVisible(hCurrentPage))
+ return TRUE;
+
+ // Try to deactivate current page
+ PSHNOTIFY pshn;
+ pshn.hdr.code = PSN_KILLACTIVE;
+ pshn.hdr.hwndFrom = m_hWnd;
+ pshn.hdr.idFrom = GetDlgCtrlID();
+ pshn.lParam = 0;
+ if (::SendMessage(hCurrentPage, WM_NOTIFY, pshn.hdr.idFrom, (LPARAM)&pshn))
+ // current page does not allow page change
+ return FALSE;
+
+ // Hide the page
+ ::ShowWindow(hCurrentPage, SW_HIDE);
+
+ return TRUE;
+}
+
+
+HTREEITEM CTreePropSheet::GetPageTreeItem(int nPage, HTREEITEM hRoot /* = TVI_ROOT */)
+{
+ // Special handling for root case
+ if (hRoot == TVI_ROOT)
+ hRoot = m_pwndPageTree->GetNextItem(NULL, TVGN_ROOT);
+
+ // Check parameters
+ if (nPage < 0 || nPage >= GetPageCount())
+ {
+ ASSERT(FALSE);
+ return NULL;
+ }
+
+ if (hRoot == NULL)
+ {
+ ASSERT(FALSE);
+ return NULL;
+ }
+
+ // we are performing a simple linear search here, because we are
+ // expecting only little data
+ HTREEITEM hItem = hRoot;
+ while (hItem)
+ {
+ if ((signed)m_pwndPageTree->GetItemData(hItem) == nPage)
+ return hItem;
+ if (m_pwndPageTree->ItemHasChildren(hItem))
+ {
+ HTREEITEM hResult = GetPageTreeItem(nPage, m_pwndPageTree->GetNextItem(hItem, TVGN_CHILD));
+ if (hResult)
+ return hResult;
+ }
+
+ hItem = m_pwndPageTree->GetNextItem(hItem, TVGN_NEXT);
+ }
+
+ // we've found nothing, if we arrive here
+ return hItem;
+}
+
+
+BOOL CTreePropSheet::SelectPageTreeItem(int nPage)
+{
+ HTREEITEM hItem = GetPageTreeItem(nPage);
+ if (!hItem)
+ return FALSE;
+
+ return m_pwndPageTree->SelectItem(hItem);
+}
+
+
+BOOL CTreePropSheet::SelectCurrentPageTreeItem()
+{
+ CTabCtrl *pTab = GetTabControl();
+ if (!IsWindow(pTab->GetSafeHwnd()))
+ return FALSE;
+
+ return SelectPageTreeItem(pTab->GetCurSel());
+}
+
+
+void CTreePropSheet::UpdateCaption()
+{
+ HWND hPage = PropSheet_GetCurrentPageHwnd(GetSafeHwnd());
+ BOOL bRealPage = IsWindow(hPage) && ::IsWindowVisible(hPage);
+ HTREEITEM hItem = m_pwndPageTree->GetSelectedItem();
+ if (!hItem)
+ return;
+ CString strCaption = m_pwndPageTree->GetItemText(hItem);
+
+ // if empty page, then update empty page message
+ if (!bRealPage)
+ m_pFrame->SetMsgText(GenerateEmptyPageMessage(m_strEmptyPageMessage, strCaption));
+
+ // if no captions are displayed, cancel here
+ if (!m_pFrame->GetShowCaption())
+ return;
+
+ // get tab control, to the the images from
+ CTabCtrl *pTabCtrl = GetTabControl();
+ if (!IsWindow(pTabCtrl->GetSafeHwnd()))
+ {
+ ASSERT(FALSE);
+ return;
+ }
+
+ if (m_bTreeImages)
+ {
+ // get image from tree
+ int nImage;
+ m_pwndPageTree->GetItemImage(hItem, nImage, nImage);
+ HICON hIcon = m_Images.ExtractIcon(nImage);
+ m_pFrame->SetCaption(strCaption, hIcon);
+ if (hIcon)
+ DestroyIcon(hIcon);
+ }
+ else if (bRealPage)
+ {
+ // get image from hidden (original) tab provided by the original
+ // implementation
+ CImageList *pImages = pTabCtrl->GetImageList();
+ if (pImages)
+ {
+ TCITEM ti;
+ ZeroMemory(&ti, sizeof(ti));
+ ti.mask = TCIF_IMAGE;
+
+ HICON hIcon = NULL;
+ if (pTabCtrl->GetItem((int)m_pwndPageTree->GetItemData(hItem), &ti))
+ hIcon = pImages->ExtractIcon(ti.iImage);
+
+ m_pFrame->SetCaption(strCaption, hIcon);
+ if (hIcon)
+ DestroyIcon(hIcon);
+ }
+ else
+ m_pFrame->SetCaption(strCaption);
+ }
+ else
+ m_pFrame->SetCaption(strCaption);
+}
+
+
+void CTreePropSheet::ActivatePreviousPage()
+{
+ if (!IsWindow(m_hWnd))
+ return;
+
+ if (!IsWindow(m_pwndPageTree->GetSafeHwnd()))
+ {
+ // normal tab property sheet. Simply use page index
+ int nPageIndex = GetActiveIndex();
+ if (nPageIndex<0 || nPageIndex>=GetPageCount())
+ return;
+
+ int nPrevIndex = (nPageIndex==0)? GetPageCount()-1 : nPageIndex-1;
+ SetActivePage(nPrevIndex);
+ }
+ else
+ {
+ // property sheet with page tree.
+ // we need a more sophisticated handling here, than simply using
+ // the page index, because we won't skip empty pages.
+ // so we have to walk the page tree
+ HTREEITEM hItem = m_pwndPageTree->GetSelectedItem();
+ ASSERT(hItem);
+ if (!hItem)
+ return;
+
+ HTREEITEM hPrevItem = m_pwndPageTree->GetPrevSiblingItem(hItem);
+ if (hPrevItem)
+ {
+ while (m_pwndPageTree->ItemHasChildren(hPrevItem))
+ {
+ hPrevItem = m_pwndPageTree->GetChildItem(hPrevItem);
+ while (m_pwndPageTree->GetNextSiblingItem(hPrevItem))
+ hPrevItem = m_pwndPageTree->GetNextSiblingItem(hPrevItem);
+ }
+ }
+ else
+ hPrevItem = m_pwndPageTree->GetParentItem(hItem);
+
+ if (!hPrevItem)
+ {
+ // no prev item, so cycle to the last item
+ hPrevItem = m_pwndPageTree->GetRootItem();
+
+ while (TRUE)
+ {
+ while (m_pwndPageTree->GetNextSiblingItem(hPrevItem))
+ hPrevItem = m_pwndPageTree->GetNextSiblingItem(hPrevItem);
+
+ if (m_pwndPageTree->ItemHasChildren(hPrevItem))
+ hPrevItem = m_pwndPageTree->GetChildItem(hPrevItem);
+ else
+ break;
+ }
+ }
+
+ if (hPrevItem)
+ m_pwndPageTree->SelectItem(hPrevItem);
+ }
+}
+
+
+void CTreePropSheet::ActivateNextPage()
+{
+ if (!IsWindow(m_hWnd))
+ return;
+
+ if (!IsWindow(m_pwndPageTree->GetSafeHwnd()))
+ {
+ // normal tab property sheet. Simply use page index
+ int nPageIndex = GetActiveIndex();
+ if (nPageIndex<0 || nPageIndex>=GetPageCount())
+ return;
+
+ int nNextIndex = (nPageIndex==GetPageCount()-1)? 0 : nPageIndex+1;
+ SetActivePage(nNextIndex);
+ }
+ else
+ {
+ // property sheet with page tree.
+ // we need a more sophisticated handling here, than simply using
+ // the page index, because we won't skip empty pages.
+ // so we have to walk the page tree
+ HTREEITEM hItem = m_pwndPageTree->GetSelectedItem();
+ ASSERT(hItem);
+ if (!hItem)
+ return;
+
+ HTREEITEM hNextItem = m_pwndPageTree->GetChildItem(hItem);
+ if (!hNextItem)
+ {
+ hNextItem = m_pwndPageTree->GetNextSiblingItem(hItem);
+ if (!hNextItem && m_pwndPageTree->GetParentItem(hItem))
+ {
+ while (!hNextItem)
+ {
+ hItem = m_pwndPageTree->GetParentItem(hItem);
+ if (!hItem)
+ break;
+
+ hNextItem = m_pwndPageTree->GetNextSiblingItem(hItem);
+ }
+ }
+ }
+
+ if (!hNextItem)
+ // no next item -- so cycle to the first item
+ hNextItem = m_pwndPageTree->GetRootItem();
+
+ if (hNextItem)
+ m_pwndPageTree->SelectItem(hNextItem);
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Overridings
+
+BOOL CTreePropSheet::OnInitDialog()
+{
+ if (m_bTreeViewMode)
+ {
+ // be sure, there are no stacked tabs, because otherwise the
+ // page caption will be to large in tree view mode
+ EnableStackedTabs(FALSE);
+
+ // Initialize image list.
+ if (m_DefaultImages.GetSafeHandle())
+ {
+ IMAGEINFO ii;
+ m_DefaultImages.GetImageInfo(0, &ii);
+ if (ii.hbmImage) DeleteObject(ii.hbmImage);
+ if (ii.hbmMask) DeleteObject(ii.hbmMask);
+ m_Images.Create(ii.rcImage.right-ii.rcImage.left, ii.rcImage.bottom-ii.rcImage.top, ILC_COLOR32|ILC_MASK, 0, 1);
+ }
+ else
+ m_Images.Create(16, 16, ILC_COLOR32|ILC_MASK, 0, 1);
+ }
+
+ // perform default implementation
+ BOOL bResult = __super::OnInitDialog();
+
+ if (!m_bTreeViewMode)
+ // stop here, if we would like to use tabs
+ return bResult;
+
+ // Get tab control...
+ CTabCtrl *pTab = GetTabControl();
+ if (!IsWindow(pTab->GetSafeHwnd()))
+ {
+ ASSERT(FALSE);
+ return bResult;
+ }
+
+ // ... and hide it
+ pTab->ShowWindow(SW_HIDE);
+ pTab->EnableWindow(FALSE);
+
+ // Place another (empty) tab ctrl, to get a frame instead
+ CRect rectFrame;
+ pTab->GetWindowRect(rectFrame);
+ ScreenToClient(rectFrame);
+
+ m_pFrame = CreatePageFrame();
+ if (!m_pFrame)
+ {
+ ASSERT(FALSE);
+ AfxThrowMemoryException();
+ }
+ m_pFrame->Create(WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS, rectFrame, this, 0xFFFF);
+ m_pFrame->ShowCaption(m_bPageCaption);
+
+ // Lets make place for the tree ctrl
+ const int nTreeWidth = m_nPageTreeWidth;
+ const int nTreeSpace = 5;
+
+ CRect rectSheet;
+ GetWindowRect(rectSheet);
+ rectSheet.right+= nTreeWidth;
+ SetWindowPos(NULL, -1, -1, rectSheet.Width(), rectSheet.Height(), SWP_NOZORDER|SWP_NOMOVE);
+ CenterWindow();
+
+ MoveChildWindows(nTreeWidth, 0);
+
+ // Lets calculate the rectangle for the tree ctrl
+ CRect rectTree(rectFrame);
+ rectTree.right = rectTree.left + nTreeWidth - nTreeSpace;
+
+ // calculate caption height
+ CTabCtrl wndTabCtrl;
+ wndTabCtrl.Create(WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS, rectFrame, this, 0x1234);
+ wndTabCtrl.InsertItem(0, _T(""));
+ CRect rectFrameCaption;
+ wndTabCtrl.GetItemRect(0, rectFrameCaption);
+ wndTabCtrl.DestroyWindow();
+ m_pFrame->SetCaptionHeight(rectFrameCaption.Height());
+
+ // if no caption should be displayed, make the window smaller in
+ // height
+ if (!m_bPageCaption)
+ {
+ // make frame smaller
+ m_pFrame->GetWnd()->GetWindowRect(rectFrame);
+ ScreenToClient(rectFrame);
+ rectFrame.top+= rectFrameCaption.Height();
+ m_pFrame->GetWnd()->MoveWindow(rectFrame);
+
+ // move all child windows up
+ MoveChildWindows(0, -rectFrameCaption.Height());
+
+ // modify rectangle for the tree ctrl
+ rectTree.bottom-= rectFrameCaption.Height();
+
+ // make us smaller
+ CRect rect;
+ GetWindowRect(rect);
+ rect.top+= rectFrameCaption.Height()/2;
+ rect.bottom-= rectFrameCaption.Height()-rectFrameCaption.Height()/2;
+// if (GetParent())
+// GetParent()->ScreenToClient(rect);
+ MoveWindow(rect);
+ }
+
+ // finally create tht tree control
+ const DWORD dwTreeStyle = TVS_SHOWSELALWAYS|TVS_TRACKSELECT|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS;
+ m_pwndPageTree = CreatePageTreeObject();
+ if (!m_pwndPageTree)
+ {
+ ASSERT(FALSE);
+ AfxThrowMemoryException();
+ }
+
+ // MFC7-support here (Thanks to Rainer Wollgarten)
+ #if _MFC_VER >= 0x0700
+ {
+ m_pwndPageTree->CreateEx(
+ WS_EX_CLIENTEDGE|WS_EX_NOPARENTNOTIFY,
+ WS_TABSTOP|WS_CHILD|WS_VISIBLE|dwTreeStyle,
+ rectTree, this, s_unPageTreeId);
+ }
+ #else
+ {
+ m_pwndPageTree->CreateEx(
+ WS_EX_CLIENTEDGE|WS_EX_NOPARENTNOTIFY,
+ _T("SysTreeView32"), _T("PageTree"),
+ WS_TABSTOP|WS_CHILD|WS_VISIBLE|dwTreeStyle,
+ rectTree, this, s_unPageTreeId);
+ }
+ #endif
+
+ if (m_bTreeImages)
+ {
+ m_pwndPageTree->SetImageList(&m_Images, TVSIL_NORMAL);
+ m_pwndPageTree->SetImageList(&m_Images, TVSIL_STATE);
+ }
+
+ // Fill the tree ctrl
+ RefillPageTree();
+
+ // Select item for the current page
+ if (pTab->GetCurSel() > -1)
+ SelectPageTreeItem(pTab->GetCurSel());
+
+ return bResult;
+}
+
+
+void CTreePropSheet::OnDestroy()
+{
+ __super::OnDestroy();
+
+ if(m_pwndPageTree && m_pwndPageTree->m_hWnd)
+ m_pwndPageTree->DestroyWindow();
+
+ if(m_pFrame && m_pFrame->GetWnd()->m_hWnd)
+ m_pFrame->GetWnd()->DestroyWindow();
+}
+
+
+LRESULT CTreePropSheet::OnAddPage(WPARAM wParam, LPARAM lParam)
+{
+ LRESULT lResult = DefWindowProc(PSM_ADDPAGE, wParam, lParam);
+ if (!m_bTreeViewMode)
+ return lResult;
+
+ RefillPageTree();
+ SelectCurrentPageTreeItem();
+
+ return lResult;
+}
+
+
+LRESULT CTreePropSheet::OnRemovePage(WPARAM wParam, LPARAM lParam)
+{
+ LRESULT lResult = DefWindowProc(PSM_REMOVEPAGE, wParam, lParam);
+ if (!m_bTreeViewMode)
+ return lResult;
+
+ RefillPageTree();
+ SelectCurrentPageTreeItem();
+
+ return lResult;
+}
+
+
+LRESULT CTreePropSheet::OnSetCurSel(WPARAM wParam, LPARAM lParam)
+{
+ LRESULT lResult = DefWindowProc(PSM_SETCURSEL, wParam, lParam);
+ if (!m_bTreeViewMode)
+ return lResult;
+
+ SelectCurrentPageTreeItem();
+ UpdateCaption();
+ return lResult;
+}
+
+
+LRESULT CTreePropSheet::OnSetCurSelId(WPARAM wParam, LPARAM lParam)
+{
+ LRESULT lResult = DefWindowProc(PSM_SETCURSEL, wParam, lParam);
+ if (!m_bTreeViewMode)
+ return lResult;
+
+ SelectCurrentPageTreeItem();
+ UpdateCaption();
+ return lResult;
+}
+
+
+void CTreePropSheet::OnPageTreeSelChanging(NMHDR *pNotifyStruct, LRESULT *plResult)
+{
+ *plResult = 0;
+ if (m_bPageTreeSelChangedActive)
+ return;
+ else
+ m_bPageTreeSelChangedActive = TRUE;
+
+ NMTREEVIEW *pTvn = reinterpret_cast<NMTREEVIEW*>(pNotifyStruct);
+ int nPage = m_pwndPageTree->GetItemData(pTvn->itemNew.hItem);
+ BOOL bResult;
+ if (nPage<0 || (unsigned)nPage>=m_pwndPageTree->GetCount())
+ bResult = KillActiveCurrentPage();
+ else
+ bResult = SetActivePage(nPage);
+
+ if (!bResult)
+ // prevent selection to change
+ *plResult = TRUE;
+
+ // Set focus to tree ctrl (I guess that's what the user expects)
+ m_pwndPageTree->SetFocus();
+
+ m_bPageTreeSelChangedActive = FALSE;
+
+ return;
+}
+
+
+void CTreePropSheet::OnPageTreeSelChanged(NMHDR* /*pNotifyStruct*/, LRESULT *plResult)
+{
+ *plResult = 0;
+
+ UpdateCaption();
+
+ return;
+}
+
+
+LRESULT CTreePropSheet::OnIsDialogMessage(WPARAM wParam, LPARAM lParam)
+{
+ MSG *pMsg = reinterpret_cast<MSG*>(lParam);
+ if (pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_TAB && GetKeyState(VK_CONTROL)&0x8000)
+ {
+ if (GetKeyState(VK_SHIFT)&0x8000)
+ ActivatePreviousPage();
+ else
+ ActivateNextPage();
+ return TRUE;
+ }
+
+
+ return __super::DefWindowProc(PSM_ISDIALOGMESSAGE, wParam, lParam);
+}
+
+} //namespace TreePropSheet
diff --git a/src/thirdparty/ui/TreePropSheet/TreePropSheet.h b/src/thirdparty/ui/TreePropSheet/TreePropSheet.h
new file mode 100644
index 000000000..ba98a396e
--- /dev/null
+++ b/src/thirdparty/ui/TreePropSheet/TreePropSheet.h
@@ -0,0 +1,483 @@
+/********************************************************************
+*
+* Copyright (c) 2002 Sven Wiegand <mail@sven-wiegand.de>
+*
+* You can use this and modify this in any way you want,
+* BUT LEAVE THIS HEADER INTACT.
+*
+* Redistribution is appreciated.
+*
+* $Workfile:$
+* $Revision: 126 $
+* $Modtime:$
+* $Author: gabest $
+*
+* Revision History:
+* $History:$
+*
+*********************************************************************/
+
+
+#if !defined(AFX_TREEPROPSHEET_H__50695CFB_FCE4_4188_ADB4_BF05A5488E41__INCLUDED_)
+#define AFX_TREEPROPSHEET_H__50695CFB_FCE4_4188_ADB4_BF05A5488E41__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "PropPageFrame.h"
+#include <afxtempl.h>
+#include <afxdlgs.h>
+#include <afxcmn.h>
+
+namespace TreePropSheet
+{
+
+/**
+A property sheet, which can use a tree control instead of a tab
+control, to give the user access to the different pages.
+
+You can use it exactly the same way, as a CPropertySheet object.
+Simply create CPropertyPage objects and add them via AddPage() to
+the sheet. If you would like to use the tree view mode (default),
+you can specify the path of the pages in the tree, by their name:
+The names of the pages can contain
+double colons ("::"), which will specify the path of that page in the
+tree control. I.e. if you have three pages with the following names:
+1. _T("Appearance::Toolbars")
+2. _T("Appearance::Menus")
+3. _T("Directories")
+the tree would look as follow:
+\verbatim
+Appearance
+|
++-Toolbars
+|
++-Menus
+
+Directories
+\endverbatim
+If you would like to use a double colon, which should not be
+interpreted as a path seperator, prefix it with a backslash ("\\::").
+
+To disable tree view mode and use the standard tabbed mode, call
+the SetTreeViewMode() method. This also allows you, to enable page
+captions and tree images for tree view mode. If you would like to
+have images in the tree, but not all of your pages specify images or
+there are tree view items, which are not attached to a page (only
+parent items for real page items), you have to set default images
+using the SetTreeDefaultImages() method -- otherwise their may appear
+display errors.
+
+If the user selects a tree view item, which does not belong to a page,
+because it is just a parent item for real page items, no page will
+be displayed, instead a message will be displayed, that can be set
+via SetEmptyPageText().
+
+@author Sven Wiegand
+*/
+
+class /*AFX_EXT_CLASS*/ CTreePropSheet : public CPropertySheet
+{
+ DECLARE_DYNAMIC(CTreePropSheet)
+
+// Construction/Destruction
+public:
+ CTreePropSheet();
+ CTreePropSheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
+ CTreePropSheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
+ virtual ~CTreePropSheet();
+
+// Operations
+public:
+ /**
+ Call this method, if you would like to use a tree control to browse
+ the pages, instead of the tab control.
+
+ This method needs to becalled, before DoModal() or Create(). If the
+ window has already been created, the method will fail.
+
+ @param bTreeViewMode
+ Pass TRUE to provide a tree view control instead of a tab control
+ to browse the pages, pass FALSE to use the normal tab control.
+ @param bPageCaption
+ TRUE if a caption should be displayed for each page. The caption
+ contains the page title and an icon if specified with the page.
+ Ignored if bTreeViewMode is FALSE.
+ @param bTreeImages
+ TRUE if the page icons should be displayed in the page tree,
+ FALSE if there should be no icons in the page tree. Ignored if
+ bTreeViewMode is FALSE. If not all of your pages are containing
+ icons, or if there will be empty pages (parent nodes without a
+ related page, you need to call SetTreeDefaultImages() to avoid
+ display errors.
+
+ @return
+ TRUE on success or FALSE, if the window has already been created.
+ */
+ BOOL SetTreeViewMode(BOOL bTreeViewMode = TRUE, BOOL bPageCaption = FALSE, BOOL bTreeImages = FALSE);
+
+ /**
+ Specifies the width of the tree control, when the sheet is in tree
+ view mode. The default value (if this method is not called) is 150
+ pixels.
+
+ This method needs to be called, before DoModeal() or Create().
+ Otherwise it will fail.
+
+ @param nWidth
+ The width in pixels for the page tree.
+
+ @return
+ TRUE on success, FALSE otherwise (if the window has already been
+ created).
+ */
+ BOOL SetTreeWidth(int nWidth);
+
+ /**
+ Specifies the text to be drawn on empty pages (pages for tree view
+ items, that are not related to a page, because they are only
+ parents for other items). This is only needed in tree view mode.
+
+ The specified text can contains a single "%s" placeholder which
+ will be replaced with the title of the empty page.
+ */
+ void SetEmptyPageText(LPCTSTR lpszEmptyPageText);
+
+ /**
+ Allows you to specify, how the empty page message (see
+ SetEmptyPageText()) should be drawn.
+
+ @param dwFormat
+ A combination of the DT_* flags available for the Win32-API
+ function DrawText(), that should be used to draw the text.
+ The default value is:
+ \code
+ DT_CENTER|DT_VCENTER|DT_NOPREFIX|DT_SINGLELINE
+ \endcode
+
+ @return
+ The previous format.
+ */
+ DWORD SetEmptyPageTextFormat(DWORD dwFormat);
+
+ //@{
+ /**
+ Defines the images, that should be used for pages without icons and
+ for empty parent nodes. The list contains exactly to images:
+ 1. An image that should be used for parent tree nodes, without a
+ page asignd.
+ 2. An image that should be used for pages, which are not specifying
+ any icons.
+ Standard image size is 16x16 Pixels, but if you call this method
+ before creating the sheet, the size of image 0 in this list will
+ be assumed as your preferred image size and all other icons must
+ have the same size.
+
+ @param pImages
+ Pointer to an image list with exactly to images, that should be
+ used as default images. The images are copied to an internal
+ list, so that the given list can be deleted after this call.
+ @param unBitmapID
+ Resource identifier for the bitmap, that contains the default
+ images. The resource should contain exactly to images.
+ @param cx
+ Width of a singe image in pixels.
+ @param crMask
+ Color that should be interpreted as transparent.
+
+ @return
+ TRUE on success, FALSE otherwise.
+ */
+ BOOL SetTreeDefaultImages(CImageList *pImages);
+ BOOL SetTreeDefaultImages(UINT unBitmapID, int cx, COLORREF crMask);
+ //@}
+
+ /**
+ Returns a pointer to the tree control, when the sheet is in
+ tree view mode, NULL otherwise.
+ */
+ CTreeCtrl* GetPageTreeControl();
+
+// Public helpers
+public:
+ //@{
+ /**
+ This helper allows you to easily set the icon of a property page.
+
+ This static method does nothing more, than extracting the specified
+ image as an icon from the given image list and assign the
+ icon-handle to the hIcon property of the pages PROPSHEETPAGE
+ structure (m_psp) and modify the structures flags, so that the
+ image will be recognized.
+
+ You need to call this method for a page, before adding the page
+ to a property sheet.
+
+ @important
+ If you are using the CImageList-version, you are responsible for
+ destroying the extracted icon with DestroyIcon() or the static
+ DestroyPageIcon() method.
+
+ @see DestroyPageIcon()
+
+ @param pPage
+ Property page to set the image for.
+ @param hIcon
+ Handle to icon that should be set for the page.
+ @param unIconId
+ Ressource identifier for the icon to set.
+ @param Images
+ Reference of the image list to extract the icon from.
+ @param nImage
+ Zero based index of the image in pImages, that should be used
+ as an icon.
+
+ @return
+ TRUE on success, FALSE if an error occured.
+ */
+ static BOOL SetPageIcon(CPropertyPage *pPage, HICON hIcon);
+ static BOOL SetPageIcon(CPropertyPage *pPage, UINT unIconId);
+ static BOOL SetPageIcon(CPropertyPage *pPage, CImageList &Images, int nImage);
+ //@}
+
+ /**
+ Checks, if the PSP_USEHICON flag is set in the PROPSHEETPAGE struct;
+ If this is the case, the flag will be removed and the icon
+ specified by the hIcon attribute of the PROPSHEETPAGE struct will
+ be destroyed using DestroyIcon().
+
+ @note
+ You only have to call DestroyIcon() for icons, that have been
+ created using CreateIconIndirect() (i.e. used by
+ CImageList::ExtractIcon()).
+
+ @return
+ TRUE on success, FALSE if the PSP_USEHICON flag was not set or
+ if the icon handle was NULL.
+ */
+ static BOOL DestroyPageIcon(CPropertyPage *pPage);
+
+// Overridable implementation helpers
+protected:
+ /**
+ Will be called to generate the message, that should be displayed on
+ an empty page, when the sheet is in tree view mode
+
+ This default implementation simply returns lpszEmptyPageMessage
+ with the optional "%s" placeholder replaced by lpszCaption.
+
+ @param lpszEmptyPageMessage
+ The string, set by SetEmptyPageMessage(). This string may contain
+ a "%s" placeholder.
+ @param lpszCaption
+ The title of the empty page.
+ */
+ virtual CString GenerateEmptyPageMessage(LPCTSTR lpszEmptyPageMessage, LPCTSTR lpszCaption);
+
+ /**
+ Will be called during creation process, to create the CTreeCtrl
+ object (the object, not the window!).
+
+ Allows you to inject your own CTreeCtrl-derived classes.
+
+ This default implementation simply creates a CTreeCtrl with new
+ and returns it.
+ */
+ virtual CTreeCtrl* CreatePageTreeObject();
+
+ /**
+ Will be called during creation process, to create the object, that
+ is responsible for drawing the frame around the pages, drawing the
+ empty page message and the caption.
+
+ Allows you to inject your own CPropPageFrame-derived classes.
+
+ This default implementation simply creates a CPropPageFrameTab with
+ new and returns it.
+ */
+ virtual CPropPageFrame* CreatePageFrame();
+
+// Implementation helpers
+protected:
+ /**
+ Moves all childs by the specified amount of pixels.
+
+ @param nDx
+ Pixels to move the childs in horizontal direction (can be
+ negative).
+ @param nDy
+ Pixels to move the childs in vertical direction (can be
+ negative).
+ */
+ void MoveChildWindows(int nDx, int nDy);
+
+ /**
+ Refills the tree that contains the entries for the several pages.
+ */
+ void RefillPageTree();
+
+ /**
+ Creates the specified path in the page tree and returns the handle
+ of the most child item created.
+
+ @param lpszPath
+ Path of the item to create (see description of this class).
+ @param hParentItem
+ Handle of the item under which the path should be created or
+ TVI_ROOT to start from the root.
+ */
+ HTREEITEM CreatePageTreeItem(LPCTSTR lpszPath, HTREEITEM hParent = TVI_ROOT);
+
+ /**
+ Splits the given path into the topmost item and the rest. See
+ description of this class for detailed path information.
+
+ I.e. when given the string "Appearance::Toolbars::Customize", the
+ method will return "Appearance" and after the call strRest will
+ be "Toolbars::Customize".
+ */
+ CString SplitPageTreePath(CString &strRest);
+
+ /**
+ Tries to deactivate the current page, and hides it if successfull,
+ so that an empty page becomes visible.
+
+ @return
+ TRUE if the current page has been deactivated successfully,
+ FALSE if the currently active page prevents a page change.
+ */
+ BOOL KillActiveCurrentPage();
+
+ /**
+ Returns the page tree item, that representates the specified page
+ or NULL, if no such icon exists.
+
+ @param nPage
+ Zero based page index, for which the item to retrieve.
+ @param hRoot
+ Item to start the search at or TVI_ROOT to search the whole
+ tree.
+ */
+ HTREEITEM GetPageTreeItem(int nPage, HTREEITEM hRoot = TVI_ROOT);
+
+ /**
+ Selects and shows the item, representing the specified page.
+
+ @param nPage
+ Zero based page index.
+
+ @return
+ TRUE on success, FALSE if no item does exist for the specified
+ page.
+ */
+ BOOL SelectPageTreeItem(int nPage);
+
+ /**
+ Selects and shows the tree item for the currently active page.
+
+ @return
+ TRUE on success, FALSE if no item exists for the currently active
+ page or if it was not possible to get information about the
+ currently active page.
+ */
+ BOOL SelectCurrentPageTreeItem();
+
+ /**
+ Updates the caption for the currently selected page (if the caption
+ is enabled).
+ */
+ void UpdateCaption();
+
+ /**
+ Activates the previous page in the page order or the last one, if
+ the current one is the first.
+
+ This method does never fail.
+ */
+ void ActivatePreviousPage();
+
+ /**
+ Activates the next page in the page order or the first one, if the
+ current one is the last.
+
+ This method does never fail.
+ */
+ void ActivateNextPage();
+
+// Overridings
+protected:
+ //{{AFX_VIRTUAL(CTreePropSheet)
+ public:
+ virtual BOOL OnInitDialog();
+ //}}AFX_VIRTUAL
+
+// Message handlers
+protected:
+ //{{AFX_MSG(CTreePropSheet)
+ afx_msg void OnDestroy();
+ //}}AFX_MSG
+ afx_msg LRESULT OnAddPage(WPARAM wParam, LPARAM lParam);
+ afx_msg LRESULT OnRemovePage(WPARAM wParam, LPARAM lParam);
+ afx_msg LRESULT OnSetCurSel(WPARAM wParam, LPARAM lParam);
+ afx_msg LRESULT OnSetCurSelId(WPARAM wParam, LPARAM lParam);
+ afx_msg LRESULT OnIsDialogMessage(WPARAM wParam, LPARAM lParam);
+
+ afx_msg void OnPageTreeSelChanging(NMHDR *pNotifyStruct, LRESULT *plResult);
+ afx_msg void OnPageTreeSelChanged(NMHDR *pNotifyStruct, LRESULT *plResult);
+ DECLARE_MESSAGE_MAP()
+
+// Properties
+private:
+ /** TRUE if we should use the tree control instead of the tab ctrl. */
+ BOOL m_bTreeViewMode;
+
+ /** The tree control */
+ CTreeCtrl *m_pwndPageTree;
+
+ /** The frame around the pages */
+ CPropPageFrame *m_pFrame;
+
+ /**
+ TRUE, if a tree item selection by OnPageTreeSelChanged() is
+ performed currently.
+ */
+ BOOL m_bPageTreeSelChangedActive;
+
+ /** TRUE if a page caption should be displayed, FALSE otherwise. */
+ BOOL m_bPageCaption;
+
+ /** TRUE if images should be displayed in the tree. */
+ BOOL m_bTreeImages;
+
+ /** Images to be displayed in the tree control. */
+ CImageList m_Images;
+
+ /** Default images. */
+ CImageList m_DefaultImages;
+
+ /**
+ Message to be displayed on empty pages. May contain a "%s"
+ placeholder which will be replaced by the caption of the empty
+ page.
+ */
+ CString m_strEmptyPageMessage;
+
+ /** The width of the page tree control in pixels. */
+ int m_nPageTreeWidth;
+
+// Static Properties
+private:
+ /** The id of the tree view control, that shows the pages. */
+ static const UINT s_unPageTreeId;
+};
+
+
+} //namespace TreePropSheet
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ fügt unmittelbar vor der vorhergehenden Zeile zusätzliche Deklarationen ein.
+
+#endif // AFX_TREEPROPSHEET_H__50695CFB_FCE4_4188_ADB4_BF05A5488E41__INCLUDED_
diff --git a/src/thirdparty/ui/TreePropSheet/TreePropSheet.vcproj b/src/thirdparty/ui/TreePropSheet/TreePropSheet.vcproj
new file mode 100644
index 000000000..5c0c2f5c1
--- /dev/null
+++ b/src/thirdparty/ui/TreePropSheet/TreePropSheet.vcproj
@@ -0,0 +1,330 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="TreePropSheet"
+ ProjectGUID="{AB494732-EF6D-44D0-BCF8-80FF04858D10}"
+ RootNamespace="TreePropSheet"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\debug.vsprops"
+ UseOfMFC="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\debug.vsprops"
+ UseOfMFC="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="_WIN64;_DEBUG;_LIB"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\release.vsprops"
+ UseOfMFC="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ UsePrecompiledHeader="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalOptions="/IGNORE:4221"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\release.vsprops"
+ UseOfMFC="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="_WIN64;NDEBUG;_LIB"
+ EnableEnhancedInstructionSet="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalOptions="/IGNORE:4221"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
+ >
+ <File
+ RelativePath=".\PropPageFrame.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\PropPageFrameDefault.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\TreePropSheet.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc"
+ >
+ <File
+ RelativePath=".\PropPageFrame.h"
+ >
+ </File>
+ <File
+ RelativePath=".\PropPageFrameDefault.h"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\TreePropSheet.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ <Global
+ Name="DevPartner_IsInstrumented"
+ Value="0"
+ />
+ </Globals>
+</VisualStudioProject>
diff --git a/src/thirdparty/ui/TreePropSheet/TreePropSheet.vcxproj b/src/thirdparty/ui/TreePropSheet/TreePropSheet.vcxproj
new file mode 100644
index 000000000..b8a189898
--- /dev/null
+++ b/src/thirdparty/ui/TreePropSheet/TreePropSheet.vcxproj
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{AB494732-EF6D-44D0-BCF8-80FF04858D10}</ProjectGuid>
+ <RootNamespace>TreePropSheet</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>Static</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>Static</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>Static</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>Static</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\debug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\debug.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Lib>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <PreprocessorDefinitions>_WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Lib>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Lib>
+ <AdditionalOptions>/IGNORE:4221 %(AdditionalOptions)</AdditionalOptions>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <PreprocessorDefinitions>_WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ </ClCompile>
+ <Lib>
+ <AdditionalOptions>/IGNORE:4221 %(AdditionalOptions)</AdditionalOptions>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="PropPageFrame.cpp" />
+ <ClCompile Include="PropPageFrameDefault.cpp" />
+ <ClCompile Include="stdafx.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="TreePropSheet.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="PropPageFrame.h" />
+ <ClInclude Include="PropPageFrameDefault.h" />
+ <ClInclude Include="stdafx.h" />
+ <ClInclude Include="TreePropSheet.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+ <ProjectExtensions>
+ <VisualStudio>
+ <UserProperties DevPartner_IsInstrumented="0" />
+ </VisualStudio>
+ </ProjectExtensions>
+</Project> \ No newline at end of file
diff --git a/src/thirdparty/ui/TreePropSheet/TreePropSheet.vcxproj.filters b/src/thirdparty/ui/TreePropSheet/TreePropSheet.vcxproj.filters
new file mode 100644
index 000000000..baf26b5f9
--- /dev/null
+++ b/src/thirdparty/ui/TreePropSheet/TreePropSheet.vcxproj.filters
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{669fa26f-0c7f-40c4-bc82-db7a76c85378}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{7bde8366-984f-44a0-8338-3a69a9e0511d}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="PropPageFrame.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="PropPageFrameDefault.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stdafx.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="TreePropSheet.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="PropPageFrame.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="PropPageFrameDefault.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="stdafx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="TreePropSheet.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/src/thirdparty/ui/TreePropSheet/stdafx.cpp b/src/thirdparty/ui/TreePropSheet/stdafx.cpp
new file mode 100644
index 000000000..a27b824da
--- /dev/null
+++ b/src/thirdparty/ui/TreePropSheet/stdafx.cpp
@@ -0,0 +1 @@
+#include "stdafx.h"
diff --git a/src/thirdparty/ui/TreePropSheet/stdafx.h b/src/thirdparty/ui/TreePropSheet/stdafx.h
new file mode 100644
index 000000000..4a20c6fd1
--- /dev/null
+++ b/src/thirdparty/ui/TreePropSheet/stdafx.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "../../../DSUtil/SharedInclude.h"
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+#endif
+
+#include <afx.h>
+#include <afxwin.h> // MFC core and standard components
diff --git a/src/thirdparty/ui/sizecbar/scbarcf.cpp b/src/thirdparty/ui/sizecbar/scbarcf.cpp
new file mode 100644
index 000000000..d5a965e64
--- /dev/null
+++ b/src/thirdparty/ui/sizecbar/scbarcf.cpp
@@ -0,0 +1,234 @@
+/////////////////////////////////////////////////////////////////////////
+//
+// CSizingControlBarCF Version 2.44
+//
+// Created: Dec 21, 1998 Last Modified: March 31, 2002
+//
+// See the official site at www.datamekanix.com for documentation and
+// the latest news.
+//
+/////////////////////////////////////////////////////////////////////////
+// Copyright (C) 1998-2002 by Cristi Posea. All rights reserved.
+//
+// This code is free for personal and commercial use, providing this
+// notice remains intact in the source files and all eventual changes are
+// clearly marked with comments.
+//
+// You must obtain the author's consent before you can include this code
+// in a software library.
+//
+// No warrantee of any kind, express or implied, is included with this
+// software; use at your own risk, responsibility for damages (if any) to
+// anyone resulting from the use of this software rests entirely with the
+// user.
+//
+// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
+// cristi@datamekanix.com or post them at the message board at the site.
+/////////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "scbarcf.h"
+
+/////////////////////////////////////////////////////////////////////////
+// CSizingControlBarCF
+
+IMPLEMENT_DYNAMIC(CSizingControlBarCF, baseCSizingControlBarCF);
+
+int CALLBACK EnumFontFamProc(ENUMLOGFONT FAR *lpelf,
+ NEWTEXTMETRIC FAR *lpntm,
+ int FontType,
+ LPARAM lParam)
+{
+ UNUSED_ALWAYS(lpelf);
+ UNUSED_ALWAYS(lpntm);
+ UNUSED_ALWAYS(FontType);
+ UNUSED_ALWAYS(lParam);
+
+ return 0;
+}
+
+CSizingControlBarCF::CSizingControlBarCF()
+{
+ m_bActive = FALSE;
+
+ CDC dc;
+ dc.CreateCompatibleDC(NULL);
+
+ m_sFontFace = (::EnumFontFamilies(dc.m_hDC,
+ _T("Tahoma"), (FONTENUMPROC) EnumFontFamProc, 0) == 0) ?
+ _T("Tahoma") : _T("Arial");
+
+ dc.DeleteDC();
+
+}
+
+BEGIN_MESSAGE_MAP(CSizingControlBarCF, baseCSizingControlBarCF)
+ //{{AFX_MSG_MAP(CSizingControlBarCF)
+ //}}AFX_MSG_MAP
+ ON_MESSAGE(WM_SETTEXT, OnSetText)
+END_MESSAGE_MAP()
+
+void CSizingControlBarCF::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
+{
+ baseCSizingControlBarCF::OnUpdateCmdUI(pTarget, bDisableIfNoHndler);
+
+ if (!HasGripper())
+ return;
+
+ BOOL bNeedPaint = FALSE;
+
+ CWnd* pFocus = GetFocus();
+ BOOL bActiveOld = m_bActive;
+
+ m_bActive = (pFocus->GetSafeHwnd() && IsChild(pFocus));
+
+ if (m_bActive != bActiveOld)
+ bNeedPaint = TRUE;
+
+ if (bNeedPaint)
+ SendMessage(WM_NCPAINT);
+}
+
+// gradient defines (if not already defined)
+#ifndef COLOR_GRADIENTACTIVECAPTION
+#define COLOR_GRADIENTACTIVECAPTION 27
+#define COLOR_GRADIENTINACTIVECAPTION 28
+#define SPI_GETGRADIENTCAPTIONS 0x1008
+#endif
+
+void CSizingControlBarCF::NcPaintGripper(CDC* pDC, CRect rcClient)
+{
+ if (!HasGripper())
+ return;
+
+ // compute the caption rectangle
+ BOOL bHorz = IsHorzDocked();
+ CRect rcGrip = rcClient;
+ CRect rcBtn = m_biHide.GetRect();
+ if (bHorz)
+ { // right side gripper
+ rcGrip.left -= m_cyGripper + 1;
+ rcGrip.right = rcGrip.left + 11;
+ rcGrip.top = rcBtn.bottom + 3;
+ }
+ else
+ { // gripper at top
+ rcGrip.top -= m_cyGripper + 1;
+ rcGrip.bottom = rcGrip.top + 11;
+ rcGrip.right = rcBtn.left - 3;
+ }
+ rcGrip.InflateRect(bHorz ? 1 : 0, bHorz ? 0 : 1);
+
+ // draw the caption background
+ //CBrush br;
+ COLORREF clrCptn = m_bActive ?
+ ::GetSysColor(COLOR_ACTIVECAPTION) :
+ ::GetSysColor(COLOR_INACTIVECAPTION);
+
+ // query gradient info (usually TRUE for Win98/Win2k)
+ BOOL bGradient = FALSE;
+ ::SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &bGradient, 0);
+
+ if (!bGradient)
+ pDC->FillSolidRect(&rcGrip, clrCptn); // solid color
+ else
+ {
+ // gradient from left to right or from bottom to top
+ // get second gradient color (the right end)
+ COLORREF clrCptnRight = m_bActive ?
+ ::GetSysColor(COLOR_GRADIENTACTIVECAPTION) :
+ ::GetSysColor(COLOR_GRADIENTINACTIVECAPTION);
+
+ // this will make 2^6 = 64 fountain steps
+ int nShift = 6;
+ int nSteps = 1 << nShift;
+
+ for (int i = 0; i < nSteps; i++)
+ {
+ // do a little alpha blending
+ int nR = (GetRValue(clrCptn) * (nSteps - i) +
+ GetRValue(clrCptnRight) * i) >> nShift;
+ int nG = (GetGValue(clrCptn) * (nSteps - i) +
+ GetGValue(clrCptnRight) * i) >> nShift;
+ int nB = (GetBValue(clrCptn) * (nSteps - i) +
+ GetBValue(clrCptnRight) * i) >> nShift;
+
+ COLORREF cr = RGB(nR, nG, nB);
+
+ // then paint with the resulting color
+ CRect r2 = rcGrip;
+ if (bHorz)
+ {
+ r2.bottom = rcGrip.bottom -
+ ((i * rcGrip.Height()) >> nShift);
+ r2.top = rcGrip.bottom -
+ (((i + 1) * rcGrip.Height()) >> nShift);
+ if (r2.Height() > 0)
+ pDC->FillSolidRect(r2, cr);
+ }
+ else
+ {
+ r2.left = rcGrip.left +
+ ((i * rcGrip.Width()) >> nShift);
+ r2.right = rcGrip.left +
+ (((i + 1) * rcGrip.Width()) >> nShift);
+ if (r2.Width() > 0)
+ pDC->FillSolidRect(r2, cr);
+ }
+ }
+ }
+
+ // draw the caption text - first select a font
+ CFont font;
+ int ppi = pDC->GetDeviceCaps(LOGPIXELSX);
+ int pointsize = MulDiv(85, 96, ppi); // 8.5 points at 96 ppi
+
+ LOGFONT lf;
+ BOOL bFont = font.CreatePointFont(pointsize, m_sFontFace);
+ if (bFont)
+ {
+ // get the text color
+ COLORREF clrCptnText = m_bActive ?
+ ::GetSysColor(COLOR_CAPTIONTEXT) :
+ ::GetSysColor(COLOR_INACTIVECAPTIONTEXT);
+
+ int nOldBkMode = pDC->SetBkMode(TRANSPARENT);
+ COLORREF clrOldText = pDC->SetTextColor(clrCptnText);
+
+ if (bHorz)
+ {
+ // rotate text 90 degrees CCW if horizontally docked
+ font.GetLogFont(&lf);
+ font.DeleteObject();
+ lf.lfEscapement = 900;
+ font.CreateFontIndirect(&lf);
+ }
+
+ CFont* pOldFont = pDC->SelectObject(&font);
+ CString sTitle;
+ GetWindowText(sTitle);
+
+ CPoint ptOrg = bHorz ?
+ CPoint(rcGrip.left - 1, rcGrip.bottom - 3) :
+ CPoint(rcGrip.left + 3, rcGrip.top - 1);
+
+ pDC->ExtTextOut(ptOrg.x, ptOrg.y,
+ ETO_CLIPPED, rcGrip, sTitle, NULL);
+
+ pDC->SelectObject(pOldFont);
+ pDC->SetBkMode(nOldBkMode);
+ pDC->SetTextColor(clrOldText);
+ }
+
+ // draw the button
+ m_biHide.Paint(pDC);
+}
+
+LRESULT CSizingControlBarCF::OnSetText(WPARAM wParam, LPARAM lParam)
+{
+ LRESULT lResult = baseCSizingControlBarCF::OnSetText(wParam, lParam);
+
+ SendMessage(WM_NCPAINT);
+
+ return lResult;
+}
diff --git a/src/thirdparty/ui/sizecbar/scbarcf.h b/src/thirdparty/ui/sizecbar/scbarcf.h
new file mode 100644
index 000000000..e5c20d246
--- /dev/null
+++ b/src/thirdparty/ui/sizecbar/scbarcf.h
@@ -0,0 +1,78 @@
+/////////////////////////////////////////////////////////////////////////
+//
+// CSizingControlBarCF Version 2.44
+//
+// Created: Dec 21, 1998 Last Modified: March 31, 2002
+//
+// See the official site at www.datamekanix.com for documentation and
+// the latest news.
+//
+/////////////////////////////////////////////////////////////////////////
+// Copyright (C) 1998-2002 by Cristi Posea. All rights reserved.
+//
+// This code is free for personal and commercial use, providing this
+// notice remains intact in the source files and all eventual changes are
+// clearly marked with comments.
+//
+// You must obtain the author's consent before you can include this code
+// in a software library.
+//
+// No warrantee of any kind, express or implied, is included with this
+// software; use at your own risk, responsibility for damages (if any) to
+// anyone resulting from the use of this software rests entirely with the
+// user.
+//
+// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
+// cristi@datamekanix.com or post them at the message board at the site.
+/////////////////////////////////////////////////////////////////////////
+
+#if !defined(__SCBARCF_H__)
+#define __SCBARCF_H__
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+// scbarcf.h : header file
+//
+
+#include "scbarg.h"
+
+/////////////////////////////////////////////////////////////////////////
+// CSizingControlBarCF
+
+#ifndef baseCSizingControlBarCF
+#define baseCSizingControlBarCF CSizingControlBarG
+#endif
+
+class CSizingControlBarCF : public baseCSizingControlBarCF
+{
+ DECLARE_DYNAMIC(CSizingControlBarCF)
+
+// Construction
+public:
+ CSizingControlBarCF();
+
+// Overridables
+ virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
+
+// Implementation
+protected:
+ // implementation helpers
+ virtual void NcPaintGripper(CDC* pDC, CRect rcClient);
+
+protected:
+ BOOL m_bActive; // a child has focus
+ CString m_sFontFace;
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CSizingControlBarCF)
+ //}}AFX_MSG
+ afx_msg LRESULT OnSetText(WPARAM wParam, LPARAM lParam);
+
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////
+
+#endif // !defined(__SCBARCF_H__)
diff --git a/src/thirdparty/ui/sizecbar/scbarg.cpp b/src/thirdparty/ui/sizecbar/scbarg.cpp
new file mode 100644
index 000000000..7b1cfd2f5
--- /dev/null
+++ b/src/thirdparty/ui/sizecbar/scbarg.cpp
@@ -0,0 +1,239 @@
+/////////////////////////////////////////////////////////////////////////
+//
+// CSizingControlBarG Version 2.45
+//
+// Created: Jan 24, 1998 Last Modified: April 16, 2010
+//
+// See the official site at www.datamekanix.com for documentation and
+// the latest news.
+//
+/////////////////////////////////////////////////////////////////////////
+// Copyright (C) 1998-2010 Cristi Posea. All rights reserved.
+//
+// This code is free for personal and commercial use, providing this
+// notice remains intact in the source files and all eventual changes are
+// clearly marked with comments.
+//
+// No warrantee of any kind, express or implied, is included with this
+// software; use at your own risk, responsibility for damages (if any) to
+// anyone resulting from the use of this software rests entirely with the
+// user.
+//
+// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
+// cristi@datamekanix.com .
+/////////////////////////////////////////////////////////////////////////
+
+// sizecbar.cpp : implementation file
+//
+
+#include "stdafx.h"
+
+#include "scbarg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////
+// CSizingControlBarG
+
+IMPLEMENT_DYNAMIC(CSizingControlBarG, baseCSizingControlBarG);
+
+CSizingControlBarG::CSizingControlBarG()
+{
+ m_cyGripper = 12;
+}
+
+CSizingControlBarG::~CSizingControlBarG()
+{
+}
+
+BEGIN_MESSAGE_MAP(CSizingControlBarG, baseCSizingControlBarG)
+ //{{AFX_MSG_MAP(CSizingControlBarG)
+ ON_WM_NCLBUTTONUP()
+ ON_WM_NCHITTEST()
+ //}}AFX_MSG_MAP
+ ON_MESSAGE(WM_SETTEXT, OnSetText)
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////
+// CSizingControlBarG message handlers
+
+/////////////////////////////////////////////////////////////////////////
+// Mouse Handling
+//
+
+void CSizingControlBarG::OnNcLButtonUp(UINT nHitTest, CPoint point)
+{
+ if (nHitTest == HTCLOSE)
+ m_pDockSite->ShowControlBar(this, FALSE, FALSE); // hide
+
+ baseCSizingControlBarG::OnNcLButtonUp(nHitTest, point);
+}
+
+void CSizingControlBarG::NcCalcClient(LPRECT pRc, UINT nDockBarID)
+{
+ CRect rcBar(pRc); // save the bar rect
+
+ // subtract edges
+ baseCSizingControlBarG::NcCalcClient(pRc, nDockBarID);
+
+ if (!HasGripper())
+ return;
+
+ CRect rc(pRc); // the client rect as calculated by the base class
+
+ BOOL bHorz = (nDockBarID == AFX_IDW_DOCKBAR_TOP) ||
+ (nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);
+
+ if (bHorz)
+ rc.DeflateRect(m_cyGripper, 0, 0, 0);
+ else
+ rc.DeflateRect(0, m_cyGripper, 0, 0);
+
+ // set position for the "x" (hide bar) button
+ CPoint ptOrgBtn;
+ if (bHorz)
+ ptOrgBtn = CPoint(rc.left - 13, rc.top);
+ else
+ ptOrgBtn = CPoint(rc.right - 12, rc.top - 13);
+
+ m_biHide.Move(ptOrgBtn - rcBar.TopLeft());
+
+ *pRc = rc;
+}
+
+void CSizingControlBarG::NcPaintGripper(CDC* pDC, CRect rcClient)
+{
+ if (!HasGripper())
+ return;
+
+ // paints a simple "two raised lines" gripper
+ // override this if you want a more sophisticated gripper
+ CRect gripper = rcClient;
+ CRect rcbtn = m_biHide.GetRect();
+ BOOL bHorz = IsHorzDocked();
+
+ gripper.DeflateRect(1, 1);
+ if (bHorz)
+ { // gripper at left
+ gripper.left -= m_cyGripper;
+ gripper.right = gripper.left + 3;
+ gripper.top = rcbtn.bottom + 3;
+ }
+ else
+ { // gripper at top
+ gripper.top -= m_cyGripper;
+ gripper.bottom = gripper.top + 3;
+ gripper.right = rcbtn.left - 3;
+ }
+
+ pDC->Draw3dRect(gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT),
+ ::GetSysColor(COLOR_BTNSHADOW));
+
+ gripper.OffsetRect(bHorz ? 3 : 0, bHorz ? 0 : 3);
+
+ pDC->Draw3dRect(gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT),
+ ::GetSysColor(COLOR_BTNSHADOW));
+
+ m_biHide.Paint(pDC);
+}
+
+LRESULT CSizingControlBarG::OnNcHitTest(CPoint point)
+{
+ CRect rcBar;
+ GetWindowRect(rcBar);
+
+ LRESULT nRet = baseCSizingControlBarG::OnNcHitTest(point);
+ if (nRet != HTCLIENT)
+ return nRet;
+
+ CRect rc = m_biHide.GetRect();
+ rc.OffsetRect(rcBar.TopLeft());
+ if (rc.PtInRect(point))
+ return HTCLOSE;
+
+ return HTCLIENT;
+}
+
+/////////////////////////////////////////////////////////////////////////
+// CSizingControlBarG implementation helpers
+
+void CSizingControlBarG::OnUpdateCmdUI(CFrameWnd* pTarget,
+ BOOL bDisableIfNoHndler)
+{
+ UNUSED_ALWAYS(bDisableIfNoHndler);
+ UNUSED_ALWAYS(pTarget);
+
+ if (!HasGripper())
+ return;
+
+ BOOL bNeedPaint = FALSE;
+
+ CPoint pt;
+ ::GetCursorPos(&pt);
+ BOOL bHit = (OnNcHitTest(pt) == HTCLOSE);
+ BOOL bLButtonDown = (::GetKeyState(VK_LBUTTON) < 0);
+
+ BOOL bWasPushed = m_biHide.bPushed;
+ m_biHide.bPushed = bHit && bLButtonDown;
+
+ BOOL bWasRaised = m_biHide.bRaised;
+ m_biHide.bRaised = bHit && !bLButtonDown;
+
+ bNeedPaint |= (m_biHide.bPushed ^ bWasPushed) ||
+ (m_biHide.bRaised ^ bWasRaised);
+
+ if (bNeedPaint)
+ SendMessage(WM_NCPAINT);
+}
+
+/////////////////////////////////////////////////////////////////////////
+// CSCBButton
+
+CSCBButton::CSCBButton()
+{
+ bRaised = FALSE;
+ bPushed = FALSE;
+}
+
+void CSCBButton::Paint(CDC* pDC)
+{
+ CRect rc = GetRect();
+
+ if (bPushed)
+ pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNSHADOW),
+ ::GetSysColor(COLOR_BTNHIGHLIGHT));
+ else
+ if (bRaised)
+ pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNHIGHLIGHT),
+ ::GetSysColor(COLOR_BTNSHADOW));
+
+ COLORREF clrOldTextColor = pDC->GetTextColor();
+ pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
+ int nPrevBkMode = pDC->SetBkMode(TRANSPARENT);
+ CFont font;
+ int ppi = pDC->GetDeviceCaps(LOGPIXELSX);
+ int pointsize = MulDiv(60, 96, ppi); // 6 points at 96 ppi
+ font.CreatePointFont(pointsize, _T("Marlett"));
+ CFont* oldfont = pDC->SelectObject(&font);
+
+ pDC->TextOut(ptOrg.x + 2, ptOrg.y + 2, CString(_T("r"))); // x-like
+
+ pDC->SelectObject(oldfont);
+ pDC->SetBkMode(nPrevBkMode);
+ pDC->SetTextColor(clrOldTextColor);
+}
+
+BOOL CSizingControlBarG::HasGripper() const
+{
+#if defined(_SCB_MINIFRAME_CAPTION) || !defined(_SCB_REPLACE_MINIFRAME)
+ // if the miniframe has a caption, don't display the gripper
+ if (IsFloating())
+ return FALSE;
+#endif //_SCB_MINIFRAME_CAPTION
+
+ return TRUE;
+} \ No newline at end of file
diff --git a/src/thirdparty/ui/sizecbar/scbarg.h b/src/thirdparty/ui/sizecbar/scbarg.h
new file mode 100644
index 000000000..134f356b1
--- /dev/null
+++ b/src/thirdparty/ui/sizecbar/scbarg.h
@@ -0,0 +1,110 @@
+/////////////////////////////////////////////////////////////////////////
+//
+// CSizingControlBarG Version 2.45
+//
+// Created: Jan 24, 1998 Last Modified: April 16, 2010
+//
+// See the official site at www.datamekanix.com for documentation and
+// the latest news.
+//
+/////////////////////////////////////////////////////////////////////////
+// Copyright (C) 1998-2010 Cristi Posea. All rights reserved.
+//
+// This code is free for personal and commercial use, providing this
+// notice remains intact in the source files and all eventual changes are
+// clearly marked with comments.
+//
+// No warrantee of any kind, express or implied, is included with this
+// software; use at your own risk, responsibility for damages (if any) to
+// anyone resulting from the use of this software rests entirely with the
+// user.
+//
+// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
+// cristi@datamekanix.com .
+/////////////////////////////////////////////////////////////////////////
+
+#if !defined(__SCBARG_H__)
+#define __SCBARG_H__
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+#include "sizecbar.h"
+
+/////////////////////////////////////////////////////////////////////////
+// CSCBButton (button info) helper class
+
+class CSCBButton
+{
+public:
+ CSCBButton();
+
+ void Move(CPoint ptTo) {ptOrg = ptTo; };
+ CRect GetRect() { return CRect(ptOrg, CSize(11, 11)); };
+ void Paint(CDC* pDC);
+
+ BOOL bPushed;
+ BOOL bRaised;
+
+protected:
+ CPoint ptOrg;
+};
+
+/////////////////////////////////////////////////////////////////////////
+// CSizingControlBar control bar
+
+#ifndef baseCSizingControlBarG
+#define baseCSizingControlBarG CSizingControlBar
+#endif
+
+class CSizingControlBarG : public baseCSizingControlBarG
+{
+ DECLARE_DYNAMIC(CSizingControlBarG);
+
+// Construction
+public:
+ CSizingControlBarG();
+
+// Attributes
+public:
+ virtual BOOL HasGripper() const;
+
+// Operations
+public:
+
+// Overridables
+ virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
+
+// Overrides
+public:
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CSizingControlBarG)
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~CSizingControlBarG();
+
+protected:
+ // implementation helpers
+ virtual void NcPaintGripper(CDC* pDC, CRect rcClient);
+ virtual void NcCalcClient(LPRECT pRc, UINT nDockBarID);
+
+protected:
+ int m_cyGripper;
+
+ CSCBButton m_biHide;
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CSizingControlBarG)
+ afx_msg LRESULT OnNcHitTest(CPoint point);
+ afx_msg void OnNcLButtonUp(UINT nHitTest, CPoint point);
+ //}}AFX_MSG
+
+ DECLARE_MESSAGE_MAP()
+};
+
+#endif // !defined(__SCBARG_H__)
+
diff --git a/src/thirdparty/ui/sizecbar/sizecbar.cpp b/src/thirdparty/ui/sizecbar/sizecbar.cpp
new file mode 100644
index 000000000..639ad7aae
--- /dev/null
+++ b/src/thirdparty/ui/sizecbar/sizecbar.cpp
@@ -0,0 +1,1417 @@
+/////////////////////////////////////////////////////////////////////////
+//
+// CSizingControlBar Version 2.45
+//
+// Created: Jan 24, 1998 Last Modified: April 16, 2010
+//
+// See the official site at www.datamekanix.com for documentation and
+// the latest news.
+//
+/////////////////////////////////////////////////////////////////////////
+// Copyright (C) 1998-2010 Cristi Posea. All rights reserved.
+//
+// This code is free for personal and commercial use, providing this
+// notice remains intact in the source files and all eventual changes are
+// clearly marked with comments.
+//
+// No warrantee of any kind, express or implied, is included with this
+// software; use at your own risk, responsibility for damages (if any) to
+// anyone resulting from the use of this software rests entirely with the
+// user.
+//
+// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
+// cristi@datamekanix.com .
+//
+// The sources and a short version of the docs are also available at
+// www.codeproject.com . Look for a "Docking Windows" section and check
+// the version to be sure you get the latest one ;)
+//
+// Hint: These classes are intended to be used as base classes. Do not
+// simply add your code to these files - instead create a new class
+// derived from one of CSizingControlBarXX classes and put there what
+// you need. See CMyBar classes in the demo projects for examples.
+// Modify this file only to fix bugs, and don't forget to send me a copy.
+/////////////////////////////////////////////////////////////////////////
+// Acknowledgements:
+// o Thanks to Harlan R. Seymour for his continuous support during
+// development of this code.
+// o Thanks to Dundas Software and Formatta Corporation for the
+// opportunities to test this code on real-life applications.
+// o Some ideas for the gripper came from the CToolBarEx flat toolbar
+// by Joerg Koenig. Thanks, Joerg!
+// o Thanks to Robert Wolpow for the code on which CDockContext based
+// dialgonal resizing is based.
+// o Thanks to the following people for various bug fixes and/or
+// enhancements: Chris Maunder, Jakawan Ratiwanich, Udo Schaefer,
+// Anatoly Ivasyuk, Peter Hauptmann, DJ(?), Pat Kusbel, Aleksey
+// Malyshev, and many others who used this code and sent feedback.
+/////////////////////////////////////////////////////////////////////////
+
+// sizecbar.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "sizecbar.h"
+
+/////////////////////////////////////////////////////////////////////////
+// CSizingControlBar
+
+IMPLEMENT_DYNAMIC(CSizingControlBar, baseCSizingControlBar);
+
+CSizingControlBar::CSizingControlBar()
+{
+ m_szMinHorz = CSize(33, 32);
+ m_szMinVert = CSize(33, 32);
+ m_szMinFloat = CSize(37, 32);
+ m_szHorz = CSize(200, 200);
+ m_szVert = CSize(200, 200);
+ m_szFloat = CSize(200, 200);
+ m_bTracking = FALSE;
+ m_bKeepSize = FALSE;
+ m_bParentSizing = FALSE;
+ m_cxEdge = 5;
+ m_bDragShowContent = FALSE;
+ m_nDockBarID = 0;
+ m_dwSCBStyle = 0;
+}
+
+CSizingControlBar::~CSizingControlBar()
+{
+}
+
+BEGIN_MESSAGE_MAP(CSizingControlBar, baseCSizingControlBar)
+ //{{AFX_MSG_MAP(CSizingControlBar)
+ ON_WM_CREATE()
+ ON_WM_PAINT()
+ ON_WM_NCPAINT()
+ ON_WM_NCCALCSIZE()
+ ON_WM_WINDOWPOSCHANGING()
+ ON_WM_CAPTURECHANGED()
+ ON_WM_SETTINGCHANGE()
+ ON_WM_LBUTTONUP()
+ ON_WM_MOUSEMOVE()
+ ON_WM_NCLBUTTONDOWN()
+ ON_WM_LBUTTONDOWN()
+ ON_WM_LBUTTONDBLCLK()
+ ON_WM_RBUTTONDOWN()
+ ON_WM_NCMOUSEMOVE()
+ ON_WM_NCHITTEST()
+ ON_WM_CLOSE()
+ ON_WM_SIZE()
+ //}}AFX_MSG_MAP
+ ON_MESSAGE(WM_SETTEXT, OnSetText)
+END_MESSAGE_MAP()
+
+// old creation method, still here for compatibility reasons
+BOOL CSizingControlBar::Create(LPCTSTR lpszWindowName, CWnd* pParentWnd,
+ CSize sizeDefault, BOOL bHasGripper,
+ UINT nID, DWORD dwStyle)
+{
+ UNUSED_ALWAYS(bHasGripper);
+
+ m_szHorz = m_szVert = m_szFloat = sizeDefault;
+ return Create(lpszWindowName, pParentWnd, nID, dwStyle);
+}
+
+// preffered creation method
+BOOL CSizingControlBar::Create(LPCTSTR lpszWindowName,
+ CWnd* pParentWnd, UINT nID,
+ DWORD dwStyle)
+{
+ // must have a parent
+ ASSERT_VALID(pParentWnd);
+ // cannot be both fixed and dynamic
+ // (CBRS_SIZE_DYNAMIC is used for resizng when floating)
+ ASSERT (!((dwStyle & CBRS_SIZE_FIXED) &&
+ (dwStyle & CBRS_SIZE_DYNAMIC)));
+
+ m_dwStyle = dwStyle & CBRS_ALL; // save the control bar styles
+
+ // register and create the window - skip CControlBar::Create()
+ CString wndclass = ::AfxRegisterWndClass(CS_DBLCLKS,
+ ::LoadCursor(NULL, IDC_ARROW),
+ ::GetSysColorBrush(COLOR_BTNFACE), 0);
+
+ dwStyle &= ~CBRS_ALL; // keep only the generic window styles
+ dwStyle |= WS_CLIPCHILDREN; // prevents flashing
+ if (!CWnd::Create(wndclass, lpszWindowName, dwStyle,
+ CRect(0, 0, 0, 0), pParentWnd, nID))
+ return FALSE;
+
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////
+// CSizingControlBar operations
+#if defined(_SCB_REPLACE_MINIFRAME) && !defined(_SCB_MINIFRAME_CAPTION)
+void CSizingControlBar::EnableDocking(DWORD dwDockStyle)
+{
+ // must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only
+ ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);
+ // cannot have the CBRS_FLOAT_MULTI style
+ ASSERT((dwDockStyle & CBRS_FLOAT_MULTI) == 0);
+ // the bar must have CBRS_SIZE_DYNAMIC style
+ ASSERT((m_dwStyle & CBRS_SIZE_DYNAMIC) != 0);
+
+ m_dwDockStyle = dwDockStyle;
+ if (m_pDockContext == NULL)
+ m_pDockContext = DNew CSCBDockContext(this);
+
+ // permanently wire the bar's owner to its current parent
+ if (m_hWndOwner == NULL)
+ m_hWndOwner = ::GetParent(m_hWnd);
+}
+#endif
+
+/////////////////////////////////////////////////////////////////////////
+// CSizingControlBar message handlers
+
+int CSizingControlBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (baseCSizingControlBar::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ // query SPI_GETDRAGFULLWINDOWS system parameter
+ // OnSettingChange() will update m_bDragShowContent
+ m_bDragShowContent = FALSE;
+ ::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0,
+ &m_bDragShowContent, 0);
+
+ // uncomment this line if you want raised borders
+// m_dwSCBStyle |= SCBS_SHOWEDGES;
+
+ return 0;
+}
+
+
+LRESULT CSizingControlBar::OnSetText(WPARAM wParam, LPARAM lParam)
+{
+ UNUSED_ALWAYS(wParam);
+
+ LRESULT lResult = CWnd::Default();
+
+ if (IsFloating() &&
+ GetParentFrame()->IsKindOf(RUNTIME_CLASS(CMiniDockFrameWnd)))
+ {
+ m_pDockBar->SetWindowText((LPCTSTR) lParam); // update dockbar
+ GetParentFrame()->DelayRecalcLayout(); // refresh miniframe
+ }
+
+ return lResult;
+}
+
+const BOOL CSizingControlBar::IsFloating() const
+{
+ return !IsHorzDocked() && !IsVertDocked();
+}
+
+const BOOL CSizingControlBar::IsHorzDocked() const
+{
+ return (m_nDockBarID == AFX_IDW_DOCKBAR_TOP ||
+ m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);
+}
+
+const BOOL CSizingControlBar::IsVertDocked() const
+{
+ return (m_nDockBarID == AFX_IDW_DOCKBAR_LEFT ||
+ m_nDockBarID == AFX_IDW_DOCKBAR_RIGHT);
+}
+
+const BOOL CSizingControlBar::IsSideTracking() const
+{
+ // don't call this when not tracking
+ ASSERT(m_bTracking && !IsFloating());
+
+ return (m_htEdge == HTLEFT || m_htEdge == HTRIGHT) ?
+ IsHorzDocked() : IsVertDocked();
+}
+
+CSize CSizingControlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
+{
+ if (bStretch) // the bar is stretched (is not the child of a dockbar)
+ if (bHorz)
+ return CSize(32767, m_szHorz.cy);
+ else
+ return CSize(m_szVert.cx, 32767);
+
+ // dirty cast - we need access to protected CDockBar members
+ CSCBDockBar* pDockBar = static_cast<CSCBDockBar*> (m_pDockBar);
+
+ // force imediate RecalcDelayShow() for all sizing bars on the row
+ // with delayShow/delayHide flags set to avoid IsVisible() problems
+ CSCBArray arrSCBars;
+ GetRowSizingBars(arrSCBars);
+ AFX_SIZEPARENTPARAMS layout;
+ layout.hDWP = pDockBar->m_bLayoutQuery ?
+ NULL : ::BeginDeferWindowPos(arrSCBars.GetSize());
+ for (int i = 0; i < arrSCBars.GetSize(); i++)
+ if (arrSCBars[i]->m_nStateFlags & (delayHide|delayShow))
+ arrSCBars[i]->RecalcDelayShow(&layout);
+ if (layout.hDWP != NULL)
+ ::EndDeferWindowPos(layout.hDWP);
+
+ // get available length
+ CRect rc = pDockBar->m_rectLayout;
+ if (rc.IsRectEmpty())
+ m_pDockSite->GetClientRect(&rc);
+ int nLengthTotal = bHorz ? rc.Width() + 2 : rc.Height() - 2;
+
+ if (IsVisible() && !IsFloating() &&
+ m_bParentSizing && arrSCBars[0] == this)
+ if (NegotiateSpace(nLengthTotal, (bHorz != FALSE)))
+ AlignControlBars();
+
+ m_bParentSizing = FALSE;
+
+ if (bHorz)
+ return CSize(max(m_szMinHorz.cx, m_szHorz.cx),
+ max(m_szMinHorz.cy, m_szHorz.cy));
+
+ return CSize(max(m_szMinVert.cx, m_szVert.cx),
+ max(m_szMinVert.cy, m_szVert.cy));
+}
+
+CSize CSizingControlBar::CalcDynamicLayout(int nLength, DWORD dwMode)
+{
+ if (dwMode & (LM_HORZDOCK | LM_VERTDOCK)) // docked ?
+ {
+ if (nLength == -1)
+ m_bParentSizing = TRUE;
+
+ return baseCSizingControlBar::CalcDynamicLayout(nLength, dwMode);
+ }
+
+ if (dwMode & LM_MRUWIDTH) return m_szFloat;
+ if (dwMode & LM_COMMIT) return m_szFloat; // already committed
+
+#ifndef _SCB_REPLACE_MINIFRAME
+ // check for dialgonal resizing hit test
+ int nHitTest = m_pDockContext->m_nHitTest;
+ if (IsFloating() &&
+ (nHitTest == HTTOPLEFT || nHitTest == HTBOTTOMLEFT ||
+ nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT))
+ {
+ CPoint ptCursor;
+ ::GetCursorPos(&ptCursor);
+
+ CRect rFrame, rBar;
+ GetParentFrame()->GetWindowRect(&rFrame);
+ GetWindowRect(&rBar);
+
+ if (nHitTest == HTTOPLEFT || nHitTest == HTBOTTOMLEFT)
+ {
+ m_szFloat.cx = rFrame.left + rBar.Width() - ptCursor.x;
+ m_pDockContext->m_rectFrameDragHorz.left =
+ min(ptCursor.x, rFrame.left + rBar.Width() - m_szMinFloat.cx);
+ }
+
+ if (nHitTest == HTTOPLEFT || nHitTest == HTTOPRIGHT)
+ {
+ m_szFloat.cy = rFrame.top + rBar.Height() - ptCursor.y;
+ m_pDockContext->m_rectFrameDragHorz.top =
+ min(ptCursor.y, rFrame.top + rBar.Height() - m_szMinFloat.cy);
+ }
+
+ if (nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT)
+ m_szFloat.cx = rBar.Width() + ptCursor.x - rFrame.right;
+
+ if (nHitTest == HTBOTTOMLEFT || nHitTest == HTBOTTOMRIGHT)
+ m_szFloat.cy = rBar.Height() + ptCursor.y - rFrame.bottom;
+ }
+ else
+#endif //_SCB_REPLACE_MINIFRAME
+ ((dwMode & LM_LENGTHY) ? m_szFloat.cy : m_szFloat.cx) = nLength;
+
+ m_szFloat.cx = max(m_szFloat.cx, m_szMinFloat.cx);
+ m_szFloat.cy = max(m_szFloat.cy, m_szMinFloat.cy);
+
+ return m_szFloat;
+}
+
+void CSizingControlBar::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
+{
+ // force non-client recalc if moved or resized
+ lpwndpos->flags |= SWP_FRAMECHANGED;
+
+ baseCSizingControlBar::OnWindowPosChanging(lpwndpos);
+
+ // find on which side are we docked
+ m_nDockBarID = GetParent()->GetDlgCtrlID();
+
+ if (!IsFloating())
+ if (lpwndpos->flags & SWP_SHOWWINDOW)
+ m_bKeepSize = TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////
+// Mouse Handling
+//
+void CSizingControlBar::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ if (m_pDockBar != NULL)
+ {
+ // start the drag
+ ASSERT(m_pDockContext != NULL);
+ ClientToScreen(&point);
+ m_pDockContext->StartDrag(point);
+ }
+ else
+ CWnd::OnLButtonDown(nFlags, point);
+}
+
+void CSizingControlBar::OnLButtonDblClk(UINT nFlags, CPoint point)
+{
+ if (m_pDockBar != NULL)
+ {
+ // toggle docking
+ ASSERT(m_pDockContext != NULL);
+ m_pDockContext->ToggleDocking();
+ }
+ else
+ CWnd::OnLButtonDblClk(nFlags, point);
+}
+
+void CSizingControlBar::OnNcLButtonDown(UINT nHitTest, CPoint point)
+{
+ UNUSED_ALWAYS(point);
+
+ if (m_bTracking || IsFloating())
+ return;
+
+ if ((nHitTest >= HTSIZEFIRST) && (nHitTest <= HTSIZELAST))
+ StartTracking(nHitTest, point); // sizing edge hit
+}
+
+void CSizingControlBar::OnLButtonUp(UINT nFlags, CPoint point)
+{
+ if (m_bTracking)
+ StopTracking();
+
+ baseCSizingControlBar::OnLButtonUp(nFlags, point);
+}
+
+void CSizingControlBar::OnRButtonDown(UINT nFlags, CPoint point)
+{
+ if (m_bTracking)
+ StopTracking();
+
+ baseCSizingControlBar::OnRButtonDown(nFlags, point);
+}
+
+void CSizingControlBar::OnMouseMove(UINT nFlags, CPoint point)
+{
+ if (m_bTracking)
+ {
+ CPoint ptScreen = point;
+ ClientToScreen(&ptScreen);
+
+ OnTrackUpdateSize(ptScreen);
+ }
+
+ baseCSizingControlBar::OnMouseMove(nFlags, point);
+}
+
+void CSizingControlBar::OnCaptureChanged(CWnd *pWnd)
+{
+ if (m_bTracking && (pWnd != this))
+ StopTracking();
+
+ baseCSizingControlBar::OnCaptureChanged(pWnd);
+}
+
+void CSizingControlBar::OnNcCalcSize(BOOL bCalcValidRects,
+ NCCALCSIZE_PARAMS FAR* lpncsp)
+{
+ UNUSED_ALWAYS(bCalcValidRects);
+
+#ifndef _SCB_REPLACE_MINIFRAME
+ // Enable diagonal resizing for floating miniframe
+ if (IsFloating())
+ {
+ CFrameWnd* pFrame = GetParentFrame();
+ if (pFrame != NULL &&
+ pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)))
+ {
+ DWORD dwStyle = ::GetWindowLong(pFrame->m_hWnd, GWL_STYLE);
+ if ((dwStyle & MFS_4THICKFRAME) != 0)
+ {
+ pFrame->ModifyStyle(MFS_4THICKFRAME, 0); // clear
+ GetParent()->ModifyStyle(0, WS_CLIPCHILDREN);
+ }
+ }
+ }
+#endif _SCB_REPLACE_MINIFRAME
+
+ // compute the the client area
+ m_dwSCBStyle &= ~SCBS_EDGEALL;
+
+ // add resizing edges between bars on the same row
+ if (!IsFloating() && m_pDockBar != NULL)
+ {
+ CSCBArray arrSCBars;
+ int nThis;
+ GetRowSizingBars(arrSCBars, nThis);
+
+ BOOL bHorz = IsHorzDocked();
+ if (nThis > 0)
+ m_dwSCBStyle |= bHorz ? SCBS_EDGELEFT : SCBS_EDGETOP;
+
+ if (nThis < arrSCBars.GetUpperBound())
+ m_dwSCBStyle |= bHorz ? SCBS_EDGERIGHT : SCBS_EDGEBOTTOM;
+ }
+
+ NcCalcClient(&lpncsp->rgrc[0], m_nDockBarID);
+}
+
+void CSizingControlBar::NcCalcClient(LPRECT pRc, UINT nDockBarID)
+{
+ CRect rc(pRc);
+
+ rc.DeflateRect(3, 5, 3, 3);
+ if (nDockBarID != AFX_IDW_DOCKBAR_FLOAT)
+ rc.DeflateRect(2, 0, 2, 2);
+
+ switch(nDockBarID)
+ {
+ case AFX_IDW_DOCKBAR_TOP:
+ m_dwSCBStyle |= SCBS_EDGEBOTTOM;
+ break;
+ case AFX_IDW_DOCKBAR_BOTTOM:
+ m_dwSCBStyle |= SCBS_EDGETOP;
+ break;
+ case AFX_IDW_DOCKBAR_LEFT:
+ m_dwSCBStyle |= SCBS_EDGERIGHT;
+ break;
+ case AFX_IDW_DOCKBAR_RIGHT:
+ m_dwSCBStyle |= SCBS_EDGELEFT;
+ break;
+ }
+
+ // make room for edges only if they will be painted
+ if (m_dwSCBStyle & SCBS_SHOWEDGES)
+ rc.DeflateRect(
+ (m_dwSCBStyle & SCBS_EDGELEFT) ? m_cxEdge : 0,
+ (m_dwSCBStyle & SCBS_EDGETOP) ? m_cxEdge : 0,
+ (m_dwSCBStyle & SCBS_EDGERIGHT) ? m_cxEdge : 0,
+ (m_dwSCBStyle & SCBS_EDGEBOTTOM) ? m_cxEdge : 0);
+
+ *pRc = rc;
+}
+
+void CSizingControlBar::OnNcPaint()
+{
+ // get window DC that is clipped to the non-client area
+ CWindowDC dc(this); // the HDC will be released by the destructor
+
+ CRect rcClient, rcBar;
+ GetClientRect(rcClient);
+ ClientToScreen(rcClient);
+ GetWindowRect(rcBar);
+ rcClient.OffsetRect(-rcBar.TopLeft());
+ rcBar.OffsetRect(-rcBar.TopLeft());
+
+ CDC mdc;
+ mdc.CreateCompatibleDC(&dc);
+
+ CBitmap bm;
+ bm.CreateCompatibleBitmap(&dc, rcBar.Width(), rcBar.Height());
+ CBitmap* pOldBm = mdc.SelectObject(&bm);
+
+ // draw borders in non-client area
+ CRect rcDraw = rcBar;
+ DrawBorders(&mdc, rcDraw);
+
+ // erase the NC background
+//mpc-hc custom code start
+#ifdef _WIN64
+ mdc.FillRect(rcDraw, CBrush::FromHandle(
+ (HBRUSH) GetClassLong(m_hWnd, GCLP_HBRBACKGROUND)));
+//mpc-hc custom code end
+#else
+ mdc.FillRect(rcDraw, CBrush::FromHandle(
+ (HBRUSH) GetClassLong(m_hWnd, GCL_HBRBACKGROUND)));
+#endif
+
+ if (m_dwSCBStyle & SCBS_SHOWEDGES)
+ {
+ CRect rcEdge; // paint the sizing edges
+ for (int i = 0; i < 4; i++)
+ if (GetEdgeRect(rcBar, GetEdgeHTCode(i), rcEdge))
+ mdc.Draw3dRect(rcEdge, ::GetSysColor(COLOR_BTNHIGHLIGHT),
+ ::GetSysColor(COLOR_BTNSHADOW));
+ }
+
+ NcPaintGripper(&mdc, rcClient);
+
+ // client area is not our bussiness :)
+ dc.IntersectClipRect(rcBar);
+ dc.ExcludeClipRect(rcClient);
+
+ dc.BitBlt(0, 0, rcBar.Width(), rcBar.Height(), &mdc, 0, 0, SRCCOPY);
+
+ mdc.SelectObject(pOldBm);
+ bm.DeleteObject();
+ mdc.DeleteDC();
+}
+
+void CSizingControlBar::NcPaintGripper(CDC* pDC, CRect rcClient)
+{
+ UNUSED_ALWAYS(pDC);
+ UNUSED_ALWAYS(rcClient);
+}
+
+void CSizingControlBar::OnPaint()
+{
+ // overridden to skip border painting based on clientrect
+ CPaintDC dc(this);
+}
+
+LRESULT CSizingControlBar::OnNcHitTest(CPoint point)
+{
+ CRect rcBar, rcEdge;
+ GetWindowRect(rcBar);
+
+ if (!IsFloating())
+ for (int i = 0; i < 4; i++)
+ if (GetEdgeRect(rcBar, GetEdgeHTCode(i), rcEdge))
+ if (rcEdge.PtInRect(point))
+ return GetEdgeHTCode(i);
+
+ return HTCLIENT;
+}
+
+void CSizingControlBar::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
+{
+ baseCSizingControlBar::OnSettingChange(uFlags, lpszSection);
+
+ m_bDragShowContent = FALSE;
+ ::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0,
+ &m_bDragShowContent, 0); // update
+}
+
+void CSizingControlBar::OnSize(UINT nType, int cx, int cy)
+{
+ UNUSED_ALWAYS(nType);
+
+ if ((m_dwSCBStyle & SCBS_SIZECHILD) != 0)
+ {
+ // automatic child resizing - only one child is allowed
+ CWnd* pWnd = GetWindow(GW_CHILD);
+ if (pWnd != NULL)
+ {
+ pWnd->MoveWindow(0, 0, cx, cy);
+ ASSERT(pWnd->GetWindow(GW_HWNDNEXT) == NULL);
+ }
+ }
+}
+
+void CSizingControlBar::OnClose()
+{
+ // do nothing: protection against accidentally destruction by the
+ // child control (i.e. if user hits Esc in a child editctrl)
+}
+
+/////////////////////////////////////////////////////////////////////////
+// CSizingControlBar implementation helpers
+
+void CSizingControlBar::StartTracking(UINT nHitTest, CPoint point)
+{
+ SetCapture();
+
+ // make sure no updates are pending
+ if (!m_bDragShowContent)
+ RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
+
+ m_htEdge = nHitTest;
+ m_bTracking = TRUE;
+
+ BOOL bHorz = IsHorzDocked();
+ BOOL bHorzTracking = m_htEdge == HTLEFT || m_htEdge == HTRIGHT;
+
+ m_nTrackPosOld = bHorzTracking ? point.x : point.y;
+
+ CRect rcBar, rcEdge;
+ GetWindowRect(rcBar);
+ GetEdgeRect(rcBar, m_htEdge, rcEdge);
+ m_nTrackEdgeOfs = m_nTrackPosOld -
+ (bHorzTracking ? rcEdge.CenterPoint().x : rcEdge.CenterPoint().y);
+
+ CSCBArray arrSCBars;
+ int nThis;
+ GetRowSizingBars(arrSCBars, nThis);
+
+ m_nTrackPosMin = m_nTrackPosMax = m_nTrackPosOld;
+ if (!IsSideTracking())
+ {
+ // calc minwidth as the max minwidth of the sizing bars on row
+ int nMinWidth = bHorz ? m_szMinHorz.cy : m_szMinVert.cx;
+ for (int i = 0; i < arrSCBars.GetSize(); i++)
+ nMinWidth = max(nMinWidth, bHorz ?
+ arrSCBars[i]->m_szMinHorz.cy :
+ arrSCBars[i]->m_szMinVert.cx);
+ int nExcessWidth = (bHorz ? m_szHorz.cy : m_szVert.cx) - nMinWidth;
+
+ // the control bar cannot grow with more than the width of
+ // remaining client area of the mainframe
+ CRect rcT;
+ m_pDockSite->RepositionBars(0, 0xFFFF, AFX_IDW_PANE_FIRST,
+ reposQuery, &rcT, NULL, TRUE);
+ int nMaxWidth = bHorz ? rcT.Height() - 2 : rcT.Width() - 2;
+
+ BOOL bTopOrLeft = m_htEdge == HTTOP || m_htEdge == HTLEFT;
+
+ m_nTrackPosMin -= bTopOrLeft ? nMaxWidth : nExcessWidth;
+ m_nTrackPosMax += bTopOrLeft ? nExcessWidth : nMaxWidth;
+ }
+ else
+ {
+ // side tracking:
+ // max size is the actual size plus the amount the other
+ // sizing bars can be decreased until they reach their minsize
+ if (m_htEdge == HTBOTTOM || m_htEdge == HTRIGHT)
+ nThis++;
+
+ for (int i = 0; i < arrSCBars.GetSize(); i++)
+ {
+ CSizingControlBar* pBar = arrSCBars[i];
+
+ int nExcessWidth = bHorz ?
+ pBar->m_szHorz.cx - pBar->m_szMinHorz.cx :
+ pBar->m_szVert.cy - pBar->m_szMinVert.cy;
+
+ if (i < nThis)
+ m_nTrackPosMin -= nExcessWidth;
+ else
+ m_nTrackPosMax += nExcessWidth;
+ }
+ }
+
+ OnTrackInvertTracker(); // draw tracker
+}
+
+void CSizingControlBar::StopTracking()
+{
+ OnTrackInvertTracker(); // erase tracker
+
+ m_bTracking = FALSE;
+ ReleaseCapture();
+
+ m_pDockSite->DelayRecalcLayout();
+}
+
+void CSizingControlBar::OnTrackUpdateSize(CPoint& point)
+{
+ ASSERT(!IsFloating());
+
+ BOOL bHorzTrack = m_htEdge == HTLEFT || m_htEdge == HTRIGHT;
+
+ int nTrackPos = bHorzTrack ? point.x : point.y;
+ nTrackPos = max(m_nTrackPosMin, min(m_nTrackPosMax, nTrackPos));
+
+ int nDelta = nTrackPos - m_nTrackPosOld;
+
+ if (nDelta == 0)
+ return; // no pos change
+
+ OnTrackInvertTracker(); // erase tracker
+
+ m_nTrackPosOld = nTrackPos;
+
+ BOOL bHorz = IsHorzDocked();
+
+ CSize sizeNew = bHorz ? m_szHorz : m_szVert;
+ switch (m_htEdge)
+ {
+ case HTLEFT: sizeNew -= CSize(nDelta, 0); break;
+ case HTTOP: sizeNew -= CSize(0, nDelta); break;
+ case HTRIGHT: sizeNew += CSize(nDelta, 0); break;
+ case HTBOTTOM: sizeNew += CSize(0, nDelta); break;
+ }
+
+ CSCBArray arrSCBars;
+ int nThis;
+ GetRowSizingBars(arrSCBars, nThis);
+
+ if (!IsSideTracking())
+ for (int i = 0; i < arrSCBars.GetSize(); i++)
+ {
+ CSizingControlBar* pBar = arrSCBars[i];
+ // make same width (or height)
+ (bHorz ? pBar->m_szHorz.cy : pBar->m_szVert.cx) =
+ bHorz ? sizeNew.cy : sizeNew.cx;
+ }
+ else
+ {
+ int nGrowingBar = nThis;
+ BOOL bBefore = m_htEdge == HTTOP || m_htEdge == HTLEFT;
+ if (bBefore && nDelta > 0)
+ nGrowingBar--;
+ if (!bBefore && nDelta < 0)
+ nGrowingBar++;
+ if (nGrowingBar != nThis)
+ bBefore = !bBefore;
+
+ // nGrowing is growing
+ nDelta = abs(nDelta);
+ CSizingControlBar* pBar = arrSCBars[nGrowingBar];
+ (bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy) += nDelta;
+
+ // the others are shrinking
+ int nFirst = bBefore ? nGrowingBar - 1 : nGrowingBar + 1;
+ int nLimit = bBefore ? -1 : arrSCBars.GetSize();
+
+ for (int i = nFirst; nDelta != 0 && i != nLimit; i += (bBefore ? -1 : 1))
+ {
+ CSizingControlBar* pBar = arrSCBars[i];
+
+ int nDeltaT = min(nDelta,
+ (bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy) -
+ (bHorz ? pBar->m_szMinHorz.cx : pBar->m_szMinVert.cy));
+
+ (bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy) -= nDeltaT;
+ nDelta -= nDeltaT;
+ }
+ }
+
+ OnTrackInvertTracker(); // redraw tracker at new pos
+
+ if (m_bDragShowContent)
+ m_pDockSite->DelayRecalcLayout();
+}
+
+void CSizingControlBar::OnTrackInvertTracker()
+{
+ ASSERT(m_bTracking);
+
+ if (m_bDragShowContent)
+ return; // don't show tracker if DragFullWindows is on
+
+ BOOL bHorz = IsHorzDocked();
+ CRect rc, rcBar, rcDock, rcFrame;
+ GetWindowRect(rcBar);
+ m_pDockBar->GetWindowRect(rcDock);
+ m_pDockSite->GetWindowRect(rcFrame);
+ VERIFY(GetEdgeRect(rcBar, m_htEdge, rc));
+ if (!IsSideTracking())
+ rc = bHorz ?
+ CRect(rcDock.left + 1, rc.top, rcDock.right - 1, rc.bottom) :
+ CRect(rc.left, rcDock.top + 1, rc.right, rcDock.bottom - 1);
+
+ BOOL bHorzTracking = m_htEdge == HTLEFT || m_htEdge == HTRIGHT;
+ int nOfs = m_nTrackPosOld - m_nTrackEdgeOfs;
+ nOfs -= bHorzTracking ? rc.CenterPoint().x : rc.CenterPoint().y;
+ rc.OffsetRect(bHorzTracking ? nOfs : 0, bHorzTracking ? 0 : nOfs);
+ rc.OffsetRect(-rcFrame.TopLeft());
+
+ CDC *pDC = m_pDockSite->GetDCEx(NULL,
+ DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
+ CBrush* pBrush = CDC::GetHalftoneBrush();
+ CBrush* pBrushOld = pDC->SelectObject(pBrush);
+
+ pDC->PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), PATINVERT);
+
+ pDC->SelectObject(pBrushOld);
+ m_pDockSite->ReleaseDC(pDC);
+}
+
+BOOL CSizingControlBar::GetEdgeRect(CRect rcWnd, UINT nHitTest,
+ CRect& rcEdge)
+{
+ rcEdge = rcWnd;
+ if (m_dwSCBStyle & SCBS_SHOWEDGES)
+ rcEdge.DeflateRect(1, 1);
+ BOOL bHorz = IsHorzDocked();
+
+ switch (nHitTest)
+ {
+ case HTLEFT:
+ if (!(m_dwSCBStyle & SCBS_EDGELEFT)) return FALSE;
+ rcEdge.right = rcEdge.left + m_cxEdge;
+ rcEdge.DeflateRect(0, bHorz ? m_cxEdge: 0);
+ break;
+ case HTTOP:
+ if (!(m_dwSCBStyle & SCBS_EDGETOP)) return FALSE;
+ rcEdge.bottom = rcEdge.top + m_cxEdge;
+ rcEdge.DeflateRect(bHorz ? 0 : m_cxEdge, 0);
+ break;
+ case HTRIGHT:
+ if (!(m_dwSCBStyle & SCBS_EDGERIGHT)) return FALSE;
+ rcEdge.left = rcEdge.right - m_cxEdge;
+ rcEdge.DeflateRect(0, bHorz ? m_cxEdge: 0);
+ break;
+ case HTBOTTOM:
+ if (!(m_dwSCBStyle & SCBS_EDGEBOTTOM)) return FALSE;
+ rcEdge.top = rcEdge.bottom - m_cxEdge;
+ rcEdge.DeflateRect(bHorz ? 0 : m_cxEdge, 0);
+ break;
+ default:
+ ASSERT(FALSE); // invalid hit test code
+ }
+ return TRUE;
+}
+
+UINT CSizingControlBar::GetEdgeHTCode(int nEdge)
+{
+ if (nEdge == 0) return HTLEFT;
+ if (nEdge == 1) return HTTOP;
+ if (nEdge == 2) return HTRIGHT;
+ if (nEdge == 3) return HTBOTTOM;
+ ASSERT(FALSE); // invalid edge code
+ return HTNOWHERE;
+}
+
+void CSizingControlBar::GetRowInfo(int& nFirst, int& nLast, int& nThis)
+{
+ ASSERT_VALID(m_pDockBar); // verify bounds
+
+ nThis = m_pDockBar->FindBar(this);
+ ASSERT(nThis != -1);
+
+ int i, nBars = m_pDockBar->m_arrBars.GetSize();
+
+ // find the first and the last bar in row
+ for (nFirst = -1, i = nThis - 1; i >= 0 && nFirst == -1; i--)
+ if (m_pDockBar->m_arrBars[i] == NULL)
+ nFirst = i + 1;
+ for (nLast = -1, i = nThis + 1; i < nBars && nLast == -1; i++)
+ if (m_pDockBar->m_arrBars[i] == NULL)
+ nLast = i - 1;
+
+ ASSERT((nLast != -1) && (nFirst != -1));
+}
+
+void CSizingControlBar::GetRowSizingBars(CSCBArray& arrSCBars)
+{
+ int nThis; // dummy
+ GetRowSizingBars(arrSCBars, nThis);
+}
+
+void CSizingControlBar::GetRowSizingBars(CSCBArray& arrSCBars, int& nThis)
+{
+ arrSCBars.RemoveAll();
+
+ int nFirstT, nLastT, nThisT;
+ GetRowInfo(nFirstT, nLastT, nThisT);
+
+ nThis = -1;
+ for (int i = nFirstT; i <= nLastT; i++)
+ {
+ CSizingControlBar* pBar = static_cast<CSizingControlBar*> (m_pDockBar->m_arrBars[i]);
+ if (HIWORD(pBar) == 0) continue; // placeholder
+ if (!pBar->IsVisible()) continue;
+ if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
+ {
+ if (pBar == this)
+ nThis = arrSCBars.GetSize();
+
+ arrSCBars.Add(pBar);
+ }
+ }
+}
+
+BOOL CSizingControlBar::NegotiateSpace(int nLengthTotal, BOOL bHorz)
+{
+ ASSERT(bHorz == IsHorzDocked());
+
+ int nFirst, nLast, nThis;
+ GetRowInfo(nFirst, nLast, nThis);
+
+ int nLengthAvail = nLengthTotal;
+ int nLengthActual = 0;
+ int nLengthMin = 2;
+ int nWidthMax = 0;
+ CSizingControlBar* pBar;
+
+ int i;
+ for (i = nFirst; i <= nLast; i++)
+ {
+ pBar = static_cast<CSizingControlBar*> (m_pDockBar->m_arrBars[i]);
+ if (HIWORD(pBar) == 0) continue; // placeholder
+ if (!pBar->IsVisible()) continue;
+ BOOL bIsSizingBar =
+ pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar));
+
+ int nLengthBar; // minimum length of the bar
+ if (bIsSizingBar)
+ nLengthBar = bHorz ? pBar->m_szMinHorz.cx - 2 :
+ pBar->m_szMinVert.cy - 2;
+ else
+ {
+ CRect rcBar;
+ pBar->GetWindowRect(&rcBar);
+ nLengthBar = bHorz ? rcBar.Width() - 2 : rcBar.Height() - 2;
+ }
+
+ nLengthMin += nLengthBar;
+ if (nLengthMin > nLengthTotal)
+ {
+ // split the row after fixed bar
+ if (i < nThis)
+ {
+ m_pDockBar->m_arrBars.InsertAt(i + 1,
+ (CControlBar*) NULL);
+ return FALSE;
+ }
+
+ // only this sizebar remains on the row, adjust it to minsize
+ if (i == nThis)
+ {
+ if (bHorz)
+ m_szHorz.cx = m_szMinHorz.cx;
+ else
+ m_szVert.cy = m_szMinVert.cy;
+
+ return TRUE; // the dockbar will split the row for us
+ }
+
+ // we have enough bars - go negotiate with them
+ m_pDockBar->m_arrBars.InsertAt(i, (CControlBar*) NULL);
+ nLast = i - 1;
+ break;
+ }
+
+ if (bIsSizingBar)
+ {
+ nLengthActual += bHorz ? pBar->m_szHorz.cx - 2 :
+ pBar->m_szVert.cy - 2;
+ nWidthMax = max(nWidthMax, bHorz ? pBar->m_szHorz.cy :
+ pBar->m_szVert.cx);
+ }
+ else
+ nLengthAvail -= nLengthBar;
+ }
+
+ CSCBArray arrSCBars;
+ GetRowSizingBars(arrSCBars);
+ int nNumBars = arrSCBars.GetSize();
+ int nDelta = nLengthAvail - nLengthActual;
+
+ // return faster when there is only one sizing bar per row (this one)
+ if (nNumBars == 1)
+ {
+ ASSERT(arrSCBars[0] == this);
+
+ if (nDelta == 0)
+ return TRUE;
+
+ m_bKeepSize = FALSE;
+ (bHorz ? m_szHorz.cx : m_szVert.cy) += nDelta;
+
+ return TRUE;
+ }
+
+ // make all the bars the same width
+ for (i = 0; i < nNumBars; i++)
+ if (bHorz)
+ arrSCBars[i]->m_szHorz.cy = nWidthMax;
+ else
+ arrSCBars[i]->m_szVert.cx = nWidthMax;
+
+ // distribute the difference between the bars,
+ // but don't shrink them below their minsizes
+ while (nDelta != 0)
+ {
+ int nDeltaOld = nDelta;
+ for (i = 0; i < nNumBars; i++)
+ {
+ pBar = arrSCBars[i];
+ int nLMin = bHorz ?
+ pBar->m_szMinHorz.cx : pBar->m_szMinVert.cy;
+ int nL = bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy;
+
+ if ((nL == nLMin) && (nDelta < 0) || // already at min length
+ pBar->m_bKeepSize) // or wants to keep its size
+ continue;
+
+ // sign of nDelta
+ int nDelta2 = (nDelta == 0) ? 0 : ((nDelta < 0) ? -1 : 1);
+
+ (bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy) += nDelta2;
+ nDelta -= nDelta2;
+ if (nDelta == 0) break;
+ }
+ // clear m_bKeepSize flags
+ if ((nDeltaOld == nDelta) || (nDelta == 0))
+ for (i = 0; i < nNumBars; i++)
+ arrSCBars[i]->m_bKeepSize = FALSE;
+ }
+
+ return TRUE;
+}
+
+void CSizingControlBar::AlignControlBars()
+{
+ int nFirst, nLast, nThis;
+ GetRowInfo(nFirst, nLast, nThis);
+
+ BOOL bHorz = IsHorzDocked();
+ BOOL bNeedRecalc = FALSE;
+ int nAlign = bHorz ? -2 : 0;
+
+ CRect rc, rcDock;
+ m_pDockBar->GetWindowRect(&rcDock);
+
+ for (int i = nFirst; i <= nLast; i++)
+ {
+ CSizingControlBar* pBar = static_cast<CSizingControlBar*>(m_pDockBar->m_arrBars[i]);
+ if (HIWORD(pBar) == 0) continue; // placeholder
+ if (!pBar->IsVisible()) continue;
+
+ pBar->GetWindowRect(&rc);
+ rc.OffsetRect(-rcDock.TopLeft());
+
+ if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
+ rc = CRect(rc.TopLeft(),
+ bHorz ? pBar->m_szHorz : pBar->m_szVert);
+
+ if ((bHorz ? rc.left : rc.top) != nAlign)
+ {
+ if (!bHorz)
+ rc.OffsetRect(0, nAlign - rc.top - 2);
+ else if (m_nDockBarID == AFX_IDW_DOCKBAR_TOP)
+ rc.OffsetRect(nAlign - rc.left, -2);
+ else
+ rc.OffsetRect(nAlign - rc.left, 0);
+ pBar->MoveWindow(rc);
+ bNeedRecalc = TRUE;
+ }
+ nAlign += (bHorz ? rc.Width() : rc.Height()) - 2;
+ }
+
+ if (bNeedRecalc)
+ m_pDockSite->DelayRecalcLayout();
+}
+
+void CSizingControlBar::OnUpdateCmdUI(CFrameWnd* pTarget,
+ BOOL bDisableIfNoHndler)
+{
+ UNUSED_ALWAYS(bDisableIfNoHndler);
+ UNUSED_ALWAYS(pTarget);
+}
+
+void CSizingControlBar::LoadState(LPCTSTR lpszProfileName)
+{
+ ASSERT_VALID(this);
+ ASSERT(GetSafeHwnd()); // must be called after Create()
+
+#if defined(_SCB_REPLACE_MINIFRAME) && !defined(_SCB_MINIFRAME_CAPTION)
+ // compensate the caption miscalculation in CFrameWnd::SetDockState()
+ CDockState state;
+ state.LoadState(lpszProfileName);
+
+ UINT nID = GetDlgCtrlID();
+ for (int i = 0; i < state.m_arrBarInfo.GetSize(); i++)
+ {
+ CControlBarInfo* pInfo = (CControlBarInfo*)state.m_arrBarInfo[i];
+ ASSERT(pInfo != NULL);
+ if (!pInfo->m_bFloating)
+ continue;
+
+ // this is a floating dockbar - check the ID array
+ for (int j = 0; j < pInfo->m_arrBarID.GetSize(); j++)
+ if ((DWORD) pInfo->m_arrBarID[j] == nID)
+ {
+ // found this bar - offset origin and save settings
+ pInfo->m_pointPos.x++;
+ pInfo->m_pointPos.y +=
+ ::GetSystemMetrics(SM_CYSMCAPTION) + 1;
+ pInfo->SaveState(lpszProfileName, i);
+ }
+ }
+#endif //_SCB_REPLACE_MINIFRAME && !_SCB_MINIFRAME_CAPTION
+
+ CWinApp* pApp = AfxGetApp();
+
+ TCHAR szSection[256];
+ wsprintf(szSection, _T("%s-SCBar-%d"), lpszProfileName,
+ GetDlgCtrlID());
+
+ m_szHorz.cx = max(m_szMinHorz.cx, (int) pApp->GetProfileInt(
+ szSection, _T("sizeHorzCX"), m_szHorz.cx));
+ m_szHorz.cy = max(m_szMinHorz.cy, (int) pApp->GetProfileInt(
+ szSection, _T("sizeHorzCY"), m_szHorz.cy));
+
+ m_szVert.cx = max(m_szMinVert.cx, (int) pApp->GetProfileInt(
+ szSection, _T("sizeVertCX"), m_szVert.cx));
+ m_szVert.cy = max(m_szMinVert.cy, (int) pApp->GetProfileInt(
+ szSection, _T("sizeVertCY"), m_szVert.cy));
+
+ m_szFloat.cx = max(m_szMinFloat.cx, (int) pApp->GetProfileInt(
+ szSection, _T("sizeFloatCX"), m_szFloat.cx));
+ m_szFloat.cy = max(m_szMinFloat.cy, (int) pApp->GetProfileInt(
+ szSection, _T("sizeFloatCY"), m_szFloat.cy));
+}
+
+void CSizingControlBar::SaveState(LPCTSTR lpszProfileName)
+{
+ // place your SaveState or GlobalSaveState call in
+ // CMainFrame's OnClose() or DestroyWindow(), not in OnDestroy()
+ ASSERT_VALID(this);
+ ASSERT(GetSafeHwnd());
+
+ CWinApp* pApp = AfxGetApp();
+
+ TCHAR szSection[256];
+ wsprintf(szSection, _T("%s-SCBar-%d"), lpszProfileName,
+ GetDlgCtrlID());
+
+ pApp->WriteProfileInt(szSection, _T("sizeHorzCX"), m_szHorz.cx);
+ pApp->WriteProfileInt(szSection, _T("sizeHorzCY"), m_szHorz.cy);
+
+ pApp->WriteProfileInt(szSection, _T("sizeVertCX"), m_szVert.cx);
+ pApp->WriteProfileInt(szSection, _T("sizeVertCY"), m_szVert.cy);
+
+ pApp->WriteProfileInt(szSection, _T("sizeFloatCX"), m_szFloat.cx);
+ pApp->WriteProfileInt(szSection, _T("sizeFloatCY"), m_szFloat.cy);
+}
+
+void CSizingControlBar::GlobalLoadState(CFrameWnd* pFrame,
+ LPCTSTR lpszProfileName)
+{
+ POSITION pos = pFrame->m_listControlBars.GetHeadPosition();
+ while (pos != NULL)
+ {
+ CSizingControlBar* pBar = static_cast<CSizingControlBar*> (pFrame->m_listControlBars.GetNext(pos));
+ ASSERT(pBar != NULL);
+ if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
+ pBar->LoadState(lpszProfileName);
+ }
+}
+
+void CSizingControlBar::GlobalSaveState(CFrameWnd* pFrame,
+ LPCTSTR lpszProfileName)
+{
+ POSITION pos = pFrame->m_listControlBars.GetHeadPosition();
+ while (pos != NULL)
+ {
+ CSizingControlBar* pBar = static_cast<CSizingControlBar*> (pFrame->m_listControlBars.GetNext(pos));
+ ASSERT(pBar != NULL);
+ if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
+ pBar->SaveState(lpszProfileName);
+ }
+}
+
+#ifdef _SCB_REPLACE_MINIFRAME
+#ifndef _SCB_MINIFRAME_CAPTION
+/////////////////////////////////////////////////////////////////////////////
+// CSCBDockContext Drag Operations
+
+static void AdjustRectangle(CRect& rect, CPoint pt)
+{
+ int nXOffset = (pt.x < rect.left) ? (pt.x - rect.left) :
+ (pt.x > rect.right) ? (pt.x - rect.right) : 0;
+ int nYOffset = (pt.y < rect.top) ? (pt.y - rect.top) :
+ (pt.y > rect.bottom) ? (pt.y - rect.bottom) : 0;
+ rect.OffsetRect(nXOffset, nYOffset);
+}
+
+void CSCBDockContext::StartDrag(CPoint pt)
+{
+ ASSERT_VALID(m_pBar);
+ m_bDragging = TRUE;
+
+ InitLoop();
+
+ ASSERT((m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC) != 0);
+
+ // get true bar size (including borders)
+ CRect rect;
+ m_pBar->GetWindowRect(rect);
+ m_ptLast = pt;
+ CSize sizeHorz = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK);
+ CSize sizeVert = m_pBar->CalcDynamicLayout(0, LM_VERTDOCK);
+ CSize sizeFloat = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH);
+
+ m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
+ m_rectDragVert = CRect(rect.TopLeft(), sizeVert);
+
+ // calculate frame dragging rectangle
+ m_rectFrameDragHorz = CRect(rect.TopLeft(), sizeFloat);
+
+#ifdef _MAC
+ CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz,
+ WS_THICKFRAME, WS_EX_FORCESIZEBOX);
+#else
+ CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz, WS_THICKFRAME);
+#endif
+ m_rectFrameDragHorz.DeflateRect(2, 2);
+ m_rectFrameDragVert = m_rectFrameDragHorz;
+
+ // adjust rectangles so that point is inside
+ AdjustRectangle(m_rectDragHorz, pt);
+ AdjustRectangle(m_rectDragVert, pt);
+ AdjustRectangle(m_rectFrameDragHorz, pt);
+ AdjustRectangle(m_rectFrameDragVert, pt);
+
+ // initialize tracking state and enter tracking loop
+ m_dwOverDockStyle = CanDock();
+ Move(pt); // call it here to handle special keys
+ Track();
+}
+#endif //_SCB_MINIFRAME_CAPTION
+
+/////////////////////////////////////////////////////////////////////////////
+// CSCBMiniDockFrameWnd
+
+IMPLEMENT_DYNCREATE(CSCBMiniDockFrameWnd, baseCSCBMiniDockFrameWnd);
+
+BEGIN_MESSAGE_MAP(CSCBMiniDockFrameWnd, baseCSCBMiniDockFrameWnd)
+ //{{AFX_MSG_MAP(CSCBMiniDockFrameWnd)
+ ON_WM_NCLBUTTONDOWN()
+ ON_WM_GETMINMAXINFO()
+ ON_WM_WINDOWPOSCHANGING()
+ ON_WM_SIZE()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+BOOL CSCBMiniDockFrameWnd::Create(CWnd* pParent, DWORD dwBarStyle)
+{
+ // set m_bInRecalcLayout to avoid flashing during creation
+ // RecalcLayout will be called once something is docked
+ m_bInRecalcLayout = TRUE;
+
+ DWORD dwStyle = WS_POPUP|WS_CAPTION|WS_SYSMENU|MFS_MOVEFRAME|
+ MFS_4THICKFRAME|MFS_SYNCACTIVE|MFS_BLOCKSYSMENU|
+ FWS_SNAPTOBARS;
+
+ if (dwBarStyle & CBRS_SIZE_DYNAMIC)
+ dwStyle &= ~MFS_MOVEFRAME;
+
+ DWORD dwExStyle = 0;
+#ifdef _MAC
+ if (dwBarStyle & CBRS_SIZE_DYNAMIC)
+ dwExStyle |= WS_EX_FORCESIZEBOX;
+ else
+ dwStyle &= ~(MFS_MOVEFRAME|MFS_4THICKFRAME);
+#endif
+
+ if (!CMiniFrameWnd::CreateEx(dwExStyle,
+ NULL, "", dwStyle, rectDefault, pParent))
+ {
+ m_bInRecalcLayout = FALSE;
+ return FALSE;
+ }
+ dwStyle = dwBarStyle & (CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT) ?
+ CBRS_ALIGN_LEFT : CBRS_ALIGN_TOP;
+ dwStyle |= dwBarStyle & CBRS_FLOAT_MULTI;
+ CMenu* pSysMenu = GetSystemMenu(FALSE);
+ //pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
+ CString strHide;
+ if (strHide.LoadString(AFX_IDS_HIDE))
+ {
+ pSysMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);
+ pSysMenu->AppendMenu(MF_STRING|MF_ENABLED, SC_CLOSE, strHide);
+ }
+
+ // must initially create with parent frame as parent
+ if (!m_wndDockBar.Create(pParent, WS_CHILD | WS_VISIBLE | dwStyle,
+ AFX_IDW_DOCKBAR_FLOAT))
+ {
+ m_bInRecalcLayout = FALSE;
+ return FALSE;
+ }
+
+ // set parent to CMiniDockFrameWnd
+ m_wndDockBar.SetParent(this);
+ m_bInRecalcLayout = FALSE;
+
+ return TRUE;
+}
+
+void CSCBMiniDockFrameWnd::OnNcLButtonDown(UINT nHitTest, CPoint point)
+{
+ if (nHitTest == HTCAPTION || nHitTest == HTCLOSE)
+ {
+ baseCSCBMiniDockFrameWnd::OnNcLButtonDown(nHitTest, point);
+ return;
+ }
+
+ if (GetSizingControlBar() != NULL)
+ CMiniFrameWnd::OnNcLButtonDown(nHitTest, point);
+ else
+ baseCSCBMiniDockFrameWnd::OnNcLButtonDown(nHitTest, point);
+}
+
+CSizingControlBar* CSCBMiniDockFrameWnd::GetSizingControlBar()
+{
+ CWnd* pWnd = GetWindow(GW_CHILD); // get the dockbar
+ if (pWnd == NULL)
+ return NULL;
+
+ pWnd = pWnd->GetWindow(GW_CHILD); // get the controlbar
+ if (pWnd == NULL)
+ return NULL;
+
+ if (!pWnd->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
+ return NULL;
+
+ return static_cast<CSizingControlBar*> (pWnd);
+}
+
+void CSCBMiniDockFrameWnd::OnSize(UINT nType, int cx, int cy)
+{
+ CSizingControlBar* pBar = GetSizingControlBar();
+ if ((pBar != NULL) && (GetStyle() & MFS_4THICKFRAME) == 0
+ && pBar->IsVisible() &&
+ cx + 4 >= pBar->m_szMinFloat.cx &&
+ cy + 4 >= pBar->m_szMinFloat.cy)
+ pBar->m_szFloat = CSize(cx + 4, cy + 4);
+
+ baseCSCBMiniDockFrameWnd::OnSize(nType, cx, cy);
+}
+
+void CSCBMiniDockFrameWnd::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
+{
+ baseCSCBMiniDockFrameWnd::OnGetMinMaxInfo(lpMMI);
+
+ CSizingControlBar* pBar = GetSizingControlBar();
+ if (pBar != NULL)
+ {
+ CRect r(CPoint(0, 0), pBar->m_szMinFloat - CSize(4, 4));
+#ifndef _SCB_MINIFRAME_CAPTION
+ CMiniFrameWnd::CalcBorders(&r, WS_THICKFRAME);
+#else
+ CMiniFrameWnd::CalcBorders(&r, WS_THICKFRAME|WS_CAPTION);
+#endif //_SCB_MINIFRAME_CAPTION
+ lpMMI->ptMinTrackSize.x = r.Width();
+ lpMMI->ptMinTrackSize.y = r.Height();
+// mpc-hc custom code start
+ if(pBar->m_bFixedFloat)
+ {
+ lpMMI->ptMinTrackSize.x = pBar->m_szFixedFloat.cx;
+ lpMMI->ptMinTrackSize.y = pBar->m_szFixedFloat.cy;
+ lpMMI->ptMaxTrackSize.x = pBar->m_szFixedFloat.cx;
+ lpMMI->ptMaxTrackSize.y = pBar->m_szFixedFloat.cy;
+ }
+// mpc-hc custom code end
+ }
+}
+
+void CSCBMiniDockFrameWnd::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
+{
+ if ((GetStyle() & MFS_4THICKFRAME) != 0)
+ {
+ CSizingControlBar* pBar = GetSizingControlBar();
+ if (pBar != NULL)
+ {
+ lpwndpos->flags |= SWP_NOSIZE; // don't size this time
+ // prevents flicker
+ pBar->m_pDockBar->ModifyStyle(0, WS_CLIPCHILDREN);
+
+ // enable diagonal resizing
+ DWORD dwStyleRemove = MFS_4THICKFRAME;
+#ifndef _SCB_MINIFRAME_CAPTION
+ // remove caption
+ dwStyleRemove |= WS_SYSMENU|WS_CAPTION;
+#endif
+ ModifyStyle(dwStyleRemove, 0);
+
+ DelayRecalcLayout();
+ pBar->PostMessage(WM_NCPAINT);
+ }
+ }
+
+ CMiniFrameWnd::OnWindowPosChanging(lpwndpos);
+}
+
+#endif //_SCB_REPLACE_MINIFRAME
diff --git a/src/thirdparty/ui/sizecbar/sizecbar.h b/src/thirdparty/ui/sizecbar/sizecbar.h
new file mode 100644
index 000000000..924ff60a7
--- /dev/null
+++ b/src/thirdparty/ui/sizecbar/sizecbar.h
@@ -0,0 +1,249 @@
+/////////////////////////////////////////////////////////////////////////
+//
+// CSizingControlBar Version 2.45
+//
+// Created: Jan 24, 1998 Last Modified: April 16, 2010
+//
+// See the official site at www.datamekanix.com for documentation and
+// the latest news.
+//
+/////////////////////////////////////////////////////////////////////////
+// Copyright (C) 1998-2010 Cristi Posea. All rights reserved.
+//
+// This code is free for personal and commercial use, providing this
+// notice remains intact in the source files and all eventual changes are
+// clearly marked with comments.
+//
+// No warrantee of any kind, express or implied, is included with this
+// software; use at your own risk, responsibility for damages (if any) to
+// anyone resulting from the use of this software rests entirely with the
+// user.
+//
+// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
+// cristi@datamekanix.com .
+/////////////////////////////////////////////////////////////////////////
+
+#if !defined(__SIZECBAR_H__)
+#define __SIZECBAR_H__
+
+#include <afxpriv.h> // for CDockContext
+#include <afxtempl.h> // for CTypedPtrArray
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+
+#if defined(_SCB_MINIFRAME_CAPTION) && !defined(_SCB_REPLACE_MINIFRAME)
+ #error "_SCB_MINIFRAME_CAPTION requires _SCB_REPLACE_MINIFRAME"
+#endif
+
+/////////////////////////////////////////////////////////////////////////
+// CSCBDockBar dummy class for access to protected members
+
+class CSCBDockBar : public CDockBar
+{
+ friend class CSizingControlBar;
+};
+
+/////////////////////////////////////////////////////////////////////////
+// CSizingControlBar control bar styles
+
+#define SCBS_EDGELEFT 0x00000001
+#define SCBS_EDGERIGHT 0x00000002
+#define SCBS_EDGETOP 0x00000004
+#define SCBS_EDGEBOTTOM 0x00000008
+#define SCBS_EDGEALL 0x0000000F
+#define SCBS_SHOWEDGES 0x00000010
+#define SCBS_SIZECHILD 0x00000020
+
+/////////////////////////////////////////////////////////////////////////
+// CSizingControlBar control bar
+
+#ifndef baseCSizingControlBar
+#define baseCSizingControlBar CControlBar
+#endif
+
+class CSizingControlBar;
+typedef CTypedPtrArray <CPtrArray, CSizingControlBar*> CSCBArray;
+
+class CSizingControlBar : public baseCSizingControlBar
+{
+ DECLARE_DYNAMIC(CSizingControlBar);
+
+// Construction
+public:
+ CSizingControlBar();
+
+ virtual BOOL Create(LPCTSTR lpszWindowName, CWnd* pParentWnd,
+ CSize sizeDefault, BOOL bHasGripper,
+ UINT nID, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP);
+ virtual BOOL Create(LPCTSTR lpszWindowName, CWnd* pParentWnd,
+ UINT nID, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP);
+
+// Attributes
+public:
+ const BOOL IsFloating() const;
+ const BOOL IsHorzDocked() const;
+ const BOOL IsVertDocked() const;
+ const BOOL IsSideTracking() const;
+ const BOOL GetSCBStyle() const {return m_dwSCBStyle;}
+
+// Operations
+public:
+#if defined(_SCB_REPLACE_MINIFRAME) && !defined(_SCB_MINIFRAME_CAPTION)
+ void EnableDocking(DWORD dwDockStyle);
+#endif
+ virtual void LoadState(LPCTSTR lpszProfileName);
+ virtual void SaveState(LPCTSTR lpszProfileName);
+ static void GlobalLoadState(CFrameWnd* pFrame, LPCTSTR lpszProfileName);
+ static void GlobalSaveState(CFrameWnd* pFrame, LPCTSTR lpszProfileName);
+ void SetSCBStyle(DWORD dwSCBStyle)
+ {m_dwSCBStyle = (dwSCBStyle & ~SCBS_EDGEALL);}
+
+//mpc-hc custom code start
+ void SetHeight(const int nHeight)
+ {
+ m_szFloat.cy = m_szHorz.cy = m_szVert.cy = nHeight;
+ m_pDockSite->DelayRecalcLayout();
+ }
+//mpc-hc custom code end
+
+// Overridables
+ virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
+
+// Overrides
+public:
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CSizingControlBar)
+ public:
+ virtual CSize CalcFixedLayout(BOOL bStretch, BOOL bHorz);
+ virtual CSize CalcDynamicLayout(int nLength, DWORD dwMode);
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~CSizingControlBar();
+
+protected:
+ // implementation helpers
+ UINT GetEdgeHTCode(int nEdge);
+ BOOL GetEdgeRect(CRect rcWnd, UINT nHitTest, CRect& rcEdge);
+ virtual void StartTracking(UINT nHitTest, CPoint point);
+ virtual void StopTracking();
+ virtual void OnTrackUpdateSize(CPoint& point);
+ virtual void OnTrackInvertTracker();
+ virtual void NcPaintGripper(CDC* pDC, CRect rcClient);
+ virtual void NcCalcClient(LPRECT pRc, UINT nDockBarID);
+
+ virtual void AlignControlBars();
+ void GetRowInfo(int& nFirst, int& nLast, int& nThis);
+ void GetRowSizingBars(CSCBArray& arrSCBars);
+ void GetRowSizingBars(CSCBArray& arrSCBars, int& nThis);
+ BOOL NegotiateSpace(int nLengthTotal, BOOL bHorz);
+
+protected:
+ DWORD m_dwSCBStyle;
+ UINT m_htEdge;
+
+ CSize m_szHorz;
+ CSize m_szVert;
+ CSize m_szFloat;
+ CSize m_szMinHorz;
+ CSize m_szMinVert;
+ CSize m_szMinFloat;
+ int m_nTrackPosMin;
+ int m_nTrackPosMax;
+ int m_nTrackPosOld;
+ int m_nTrackEdgeOfs;
+ BOOL m_bTracking;
+ BOOL m_bKeepSize;
+ BOOL m_bParentSizing;
+ BOOL m_bDragShowContent;
+ UINT m_nDockBarID;
+ int m_cxEdge;
+
+//mpc-hc custom code start
+ BOOL m_bFixedFloat;
+ CSize m_szFixedFloat;
+//mpc-hc custom code end
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CSizingControlBar)
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnNcPaint();
+ afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp);
+ afx_msg LRESULT OnNcHitTest(CPoint point);
+ afx_msg void OnCaptureChanged(CWnd *pWnd);
+ afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
+ afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+ afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point);
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos);
+ afx_msg void OnPaint();
+ afx_msg void OnClose();
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ //}}AFX_MSG
+ afx_msg LRESULT OnSetText(WPARAM wParam, LPARAM lParam);
+
+ DECLARE_MESSAGE_MAP()
+
+#ifdef _SCB_REPLACE_MINIFRAME
+ friend class CSCBMiniDockFrameWnd;
+#endif //_SCB_REPLACE_MINIFRAME
+};
+
+#ifdef _SCB_REPLACE_MINIFRAME
+#ifndef _SCB_MINIFRAME_CAPTION
+/////////////////////////////////////////////////////////////////////////
+// CSCBDockContext dockcontext
+
+class CSCBDockContext : public CDockContext
+{
+public:
+// Construction
+ CSCBDockContext(CControlBar* pBar) : CDockContext(pBar) {}
+
+// Drag Operations
+ virtual void StartDrag(CPoint pt);
+};
+#endif //_SCB_MINIFRAME_CAPTION
+
+/////////////////////////////////////////////////////////////////////////
+// CSCBMiniDockFrameWnd miniframe
+
+#ifndef baseCSCBMiniDockFrameWnd
+#define baseCSCBMiniDockFrameWnd CMiniDockFrameWnd
+#endif
+
+class CSCBMiniDockFrameWnd : public baseCSCBMiniDockFrameWnd
+{
+ DECLARE_DYNCREATE(CSCBMiniDockFrameWnd)
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CSCBMiniDockFrameWnd)
+ public:
+ virtual BOOL Create(CWnd* pParent, DWORD dwBarStyle);
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ CSizingControlBar* GetSizingControlBar();
+
+ //{{AFX_MSG(CSCBMiniDockFrameWnd)
+ afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point);
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);
+ afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+#endif //_SCB_REPLACE_MINIFRAME
+
+#endif // !defined(__SIZECBAR_H__)
+
diff --git a/src/thirdparty/ui/sizecbar/sizecbar.vcproj b/src/thirdparty/ui/sizecbar/sizecbar.vcproj
new file mode 100644
index 000000000..1af0b17ce
--- /dev/null
+++ b/src/thirdparty/ui/sizecbar/sizecbar.vcproj
@@ -0,0 +1,328 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="sizecbar"
+ ProjectGUID="{61E6EB4D-2F1A-443B-94B0-E8200B26E99F}"
+ RootNamespace="sizecbar"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\debug.vsprops"
+ UseOfMFC="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\debug.vsprops"
+ UseOfMFC="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="_WIN64;_DEBUG;_LIB"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\release.vsprops"
+ UseOfMFC="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\common.vsprops;..\..\..\release.vsprops"
+ UseOfMFC="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="_WIN64;NDEBUG;_LIB"
+ EnableEnhancedInstructionSet="0"
+ DisableSpecificWarnings="4244"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
+ >
+ <File
+ RelativePath=".\scbarcf.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\scbarg.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\sizecbar.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc"
+ >
+ <File
+ RelativePath=".\scbarcf.h"
+ >
+ </File>
+ <File
+ RelativePath=".\scbarg.h"
+ >
+ </File>
+ <File
+ RelativePath=".\sizecbar.h"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ <Global
+ Name="DevPartner_IsInstrumented"
+ Value="0"
+ />
+ </Globals>
+</VisualStudioProject>
diff --git a/src/thirdparty/ui/sizecbar/sizecbar.vcxproj b/src/thirdparty/ui/sizecbar/sizecbar.vcxproj
new file mode 100644
index 000000000..8c56f5b5d
--- /dev/null
+++ b/src/thirdparty/ui/sizecbar/sizecbar.vcxproj
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{61E6EB4D-2F1A-443B-94B0-E8200B26E99F}</ProjectGuid>
+ <RootNamespace>sizecbar</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>Static</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>Static</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>Static</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>Static</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\debug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\common.props" />
+ <Import Project="..\..\..\debug.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Lib>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <PreprocessorDefinitions>_WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Lib>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Lib>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <PreprocessorDefinitions>_WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <DisableSpecificWarnings>4244</DisableSpecificWarnings>
+ </ClCompile>
+ <Lib>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="scbarcf.cpp" />
+ <ClCompile Include="scbarg.cpp" />
+ <ClCompile Include="sizecbar.cpp" />
+ <ClCompile Include="stdafx.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="scbarcf.h" />
+ <ClInclude Include="scbarg.h" />
+ <ClInclude Include="sizecbar.h" />
+ <ClInclude Include="stdafx.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+ <ProjectExtensions>
+ <VisualStudio>
+ <UserProperties DevPartner_IsInstrumented="0" />
+ </VisualStudio>
+ </ProjectExtensions>
+</Project> \ No newline at end of file
diff --git a/src/thirdparty/ui/sizecbar/sizecbar.vcxproj.filters b/src/thirdparty/ui/sizecbar/sizecbar.vcxproj.filters
new file mode 100644
index 000000000..e7a19866f
--- /dev/null
+++ b/src/thirdparty/ui/sizecbar/sizecbar.vcxproj.filters
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{8d9a4844-0f68-4c0d-a6f5-a20f411affaa}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{c249b3fd-b54b-4fe2-b48b-b2ecf391f42a}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="scbarcf.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="scbarg.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="sizecbar.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stdafx.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="scbarcf.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="scbarg.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="sizecbar.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="stdafx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/src/thirdparty/ui/sizecbar/stdafx.cpp b/src/thirdparty/ui/sizecbar/stdafx.cpp
new file mode 100644
index 000000000..a27b824da
--- /dev/null
+++ b/src/thirdparty/ui/sizecbar/stdafx.cpp
@@ -0,0 +1 @@
+#include "stdafx.h"
diff --git a/src/thirdparty/ui/sizecbar/stdafx.h b/src/thirdparty/ui/sizecbar/stdafx.h
new file mode 100644
index 000000000..cbdb994bb
--- /dev/null
+++ b/src/thirdparty/ui/sizecbar/stdafx.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+#endif
+
+#include <afx.h>
+#include <afxwin.h> // MFC core and standard components