Somehow I've had the wrong include directory in the project files all this time, and thus was missing a file as well. Oops.
Somehow I've had the wrong include directory in the project files all this time, and thus was missing a file as well. Oops.

--- a/src/in_2sf/in_2sf.vcxproj
+++ b/src/in_2sf/in_2sf.vcxproj
@@ -50,7 +50,7 @@
       <WarningLevel>Level4</WarningLevel>
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_2SF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;HAVE_LIBZ;_DEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4065;4100;4127;4146;4189;4201;4244;4245;4512;4706;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>
@@ -67,7 +67,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_2SF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;HAVE_LIBZ;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4065;4100;4127;4146;4189;4201;4244;4245;4512;4706;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>

--- a/src/in_gsf/in_gsf.vcxproj
+++ b/src/in_gsf/in_gsf.vcxproj
@@ -50,7 +50,7 @@
       <WarningLevel>Level4</WarningLevel>
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_GSF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;_DEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4100;4127;4189;4244;4291;4310;4512;4800;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>
@@ -67,7 +67,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_GSF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4100;4127;4189;4244;4291;4310;4512;4800;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>

--- a/src/in_ncsf/in_ncsf.vcxproj
+++ b/src/in_ncsf/in_ncsf.vcxproj
@@ -50,7 +50,7 @@
       <WarningLevel>Level4</WarningLevel>
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_NCSF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;_DEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>
@@ -67,7 +67,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_NCSF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>

--- a/src/in_snsf/in_snsf.vcxproj
+++ b/src/in_snsf/in_snsf.vcxproj
@@ -50,7 +50,7 @@
       <WarningLevel>Level4</WarningLevel>
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_SNSF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;_DEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4100;4127;4244;4245;4310;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>
@@ -67,7 +67,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;IN_SNSF_EXPORTS;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\in_xsf_framework;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4100;4127;4244;4245;4310;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>

--- /dev/null
+++ b/src/in_xsf_framework/DialogBuilder.h
@@ -1,1 +1,678 @@
-
+/*
+ * Windows Dynamic Dialog Builder framework
+ * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
+ * Last modification on 2013-04-23
+ */
+
+#ifndef DIALOG_BUILDER_H
+#define DIALOG_BUILDER_H
+
+#include <string>
+#include <memory>
+#include <vector>
+#include <algorithm>
+#include <stdexcept>
+#include <cstdint>
+#include "windowsh_wrapper.h"
+#include "UtfConverter.h"
+
+template<typename T> struct Point
+{
+	T x, y;
+
+	Point() : x(), y() { }
+	Point(T X, T Y) : x(X), y(Y) { }
+};
+
+template<typename T> struct Size
+{
+	T width, height;
+
+	Size() : width(), height() { }
+	Size(T Width, T Height) : width(Width), height(Height) { }
+};
+
+template<typename T> struct Rect
+{
+	Point<T> position;
+	Size<T> size;
+
+	Rect() : position(), size() { }
+	Rect(const Point<T> &Position, const Size<T> &Sz) : position(Position), size(Sz) { }
+	Rect(T X, T Y, T Width, T Height) : position(X, Y), size(Width, Height) { }
+};
+
+class RelativePosition
+{
+public:
+	Point<short> relativePosition;
+	enum BaseType
+	{
+		TO_PARENT,
+		TO_SIBLING
+	} type;
+	enum PositionType
+	{
+		FROM_TOP,
+		FROM_BOTTOM,
+		FROM_LEFT,
+		FROM_RIGHT,
+		FROM_TOPLEFT,
+		FROM_BOTTOMLEFT,
+		FROM_TOPRIGHT,
+		FROM_BOTTOMRIGHT
+	} positionType;
+
+	RelativePosition(const Point<short> &RelPosition, BaseType Type, PositionType PosType) : relativePosition(RelPosition), type(Type), positionType(PosType) { }
+	virtual ~RelativePosition() { }
+	virtual RelativePosition *Clone() const = 0;
+	Point<short> CalculatePosition(const Rect<short> &child, const Rect<short> &other);
+};
+
+class RelativePositionToParent : public RelativePosition
+{
+public:
+	RelativePositionToParent(const Point<short> &RelPosition, PositionType PosType) : RelativePosition(RelPosition, TO_PARENT, PosType) { }
+	RelativePositionToParent *Clone() const { return new RelativePositionToParent(this->relativePosition, this->positionType); }
+};
+
+class RelativePositionToSibling : public RelativePosition
+{
+public:
+	short siblingsBack;
+
+	RelativePositionToSibling(const Point<short> &RelPosition, PositionType PosType, short SiblingsBack = 1) : RelativePosition(RelPosition, TO_SIBLING, PosType), siblingsBack(SiblingsBack) { }
+	RelativePositionToSibling *Clone() const { return new RelativePositionToSibling(this->relativePosition, this->positionType, this->siblingsBack); }
+};
+
+enum DialogControlType
+{
+	NO_CONTROL,
+	GROUP_CONTROL,
+	EDITBOX_CONTROL,
+	LABEL_CONTROL,
+	CHECKBOX_CONTROL,
+	BUTTON_CONTROL,
+	LISTBOX_CONTROL,
+	COMBOBOX_CONTROL
+};
+
+class DialogTemplate;
+
+class DialogBuilder
+{
+protected:
+	friend class DialogTemplate;
+	std::wstring title, fontName;
+	uint32_t style, exstyle;
+	uint16_t fontSizeInPts;
+	Size<short> size;
+	bool resetControls;
+public:
+	DialogBuilder() : title(L""), fontName(L""), style(0), exstyle(0), fontSizeInPts(0), size(), resetControls(false) { }
+	DialogBuilder &WithTitle(const std::wstring &Title) { this->title = Title; return *this; }
+	DialogBuilder &WithFont(const std::wstring &FontName, uint16_t FontSizeInPts) { this->fontName = FontName; this->fontSizeInPts = FontSizeInPts; return *this; }
+	DialogBuilder &WithSize(short Width, short Height) { this->size.width = Width; this->size.height = Height; return *this; }
+	DialogBuilder &WithSize(const Size<short> &Sz) { this->size = Sz; return *this; }
+	DialogBuilder &ResetControls(bool Reset = true) { this->resetControls = Reset; return *this; }
+	DialogBuilder &IsOverlapped() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_OVERLAPPED; return *this; }
+	DialogBuilder &IsPopup() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_POPUP; return *this; }
+	DialogBuilder &IsChild() { this->style &= ~(WS_OVERLAPPED | WS_POPUP | WS_CHILD); this->style |= WS_CHILD; return *this; }
+	DialogBuilder &WithBorder(bool Border = true) { if (Border) this->style |= WS_BORDER; else this->style &= ~WS_BORDER; return *this; }
+	DialogBuilder &WithDialogFrame(bool DialogFrame = true) { if (DialogFrame) this->style |= WS_DLGFRAME; else this->style &= ~WS_DLGFRAME; return *this; }
+	DialogBuilder &WithVerticalScrollbar(bool VerticalScrollbar = true) { if (VerticalScrollbar) this->style |= WS_VSCROLL; else this->style &= ~WS_VSCROLL; return *this; }
+	DialogBuilder &WithHorizontalScrollbar(bool HorizontalScrollbar = true) { if (HorizontalScrollbar) this->style |= WS_HSCROLL; else this->style &= ~WS_HSCROLL; return *this; }
+	DialogBuilder &WithSystemMenu(bool SystemMenu = true) { if (SystemMenu) this->style |= WS_SYSMENU; else this->style &= ~WS_SYSMENU; return *this; }
+	DialogBuilder &WithSizingBorder(bool SizingBorder = true) { if (SizingBorder) this->style |= WS_THICKFRAME; else this->style &= ~WS_THICKFRAME; return *this; }
+	DialogBuilder &WithMinimizeBox(bool MinimizeBox = true) { if (MinimizeBox) this->style |= WS_MINIMIZEBOX; else this->style &= ~WS_MINIMIZEBOX; return *this; }
+	DialogBuilder &WithMaximizeBox(bool MaximizeBox = true) { if (MaximizeBox) this->style |= WS_MAXIMIZEBOX; else this->style &= ~WS_MAXIMIZEBOX; return *this; }
+	DialogBuilder &WithDialogModalFrame(bool DialogModalFrame = true) { if (DialogModalFrame) this->exstyle |= WS_EX_DLGMODALFRAME; else this->exstyle &= ~WS_EX_DLGMODALFRAME; return *this; }
+#if WINVER >= 0x0400
+	DialogBuilder &WithRaisedEdge(bool RaisedEdge = true) { if (RaisedEdge) this->exstyle |= WS_EX_WINDOWEDGE; else this->exstyle &= ~WS_EX_WINDOWEDGE; return *this; }
+	DialogBuilder &WithSunkenEdge(bool SunkenEdge = true) { if (SunkenEdge) this->exstyle |= WS_EX_CLIENTEDGE; else this->exstyle &= ~WS_EX_CLIENTEDGE; return *this; }
+	DialogBuilder &WithContextHelp(bool ContextHelp = true) { if (ContextHelp) this->exstyle |= WS_EX_CONTEXTHELP; else this->exstyle &= ~WS_EX_CONTEXTHELP; return *this; }
+	DialogBuilder &IsControlWindow(bool ControlWindow = true) { if (ControlWindow) this->style |= DS_CONTROL; else this->style &= ~DS_CONTROL; return *this; }
+	DialogBuilder &IsCentered(bool Centered = true) { if (Centered) this->style |= DS_CENTER; else this->style &= ~DS_CENTER; return *this; }
+#endif
+};
+
+template<class T> class DialogControlBuilder
+{
+protected:
+	friend class DialogTemplate;
+	DialogControlType controlType;
+	uint32_t style, exstyle;
+	Rect<short> rect;
+	short id;
+	int index;
+	std::unique_ptr<RelativePosition> relativePosition;
+
+	T &me() { return dynamic_cast<T &>(*this); }
+public:
+	DialogControlBuilder(DialogControlType Type = NO_CONTROL) : controlType(Type), style(0), exstyle(0), rect(), id(-1), index(-1), relativePosition() { }
+	virtual ~DialogControlBuilder() { }
+	T &WithPosition(short X, short Y) { this->rect.position.x = X; this->rect.position.y = Y; return this->me(); }
+	T &WithPosition(const Point<short> &Position) { this->rect.position = Position; return this->me(); }
+	T &WithRelativePositionToParent(RelativePosition::PositionType PosType, const Point<short> &RelativePosition)
+	{
+		this->relativePosition.reset(new RelativePositionToParent(RelativePosition, PosType));
+		return this->me();
+	}
+	T &WithRelativePositionToSibling(RelativePosition::PositionType PosType, const Point<short> &RelativePosition, short SiblingsBack = 1)
+	{
+		this->relativePosition.reset(new RelativePositionToSibling(RelativePosition, PosType, SiblingsBack));
+		return this->me();
+	}
+	T &WithSize(short Width, short Height) { this->rect.size.width = Width; this->rect.size.height = Height; return this->me(); }
+	T &WithSize(const Size<short> &Sz) { this->rect.size = Sz; return this->me(); }
+	T &WithID(short ID) { this->id = ID; return this->me(); }
+	T &AtIndex(int Index) { this->index = Index; return this->me(); }
+	T &IsDisabled(bool Disabled = true) { if (Disabled) this->style |= WS_DISABLED; else this->style &= ~WS_DISABLED; return this->me(); }
+	T &WithBorder(bool ThinBorder = true) { if (ThinBorder) this->style |= WS_BORDER; else this->style &= ~WS_BORDER; return this->me(); }
+	T &WithVerticalScrollbar(bool VerticalScrollbar = true) { if (VerticalScrollbar) this->style |= WS_VSCROLL; else this->style &= ~WS_VSCROLL; return this->me(); }
+	T &WithHorizontalScrollbar(bool HorizontalScrollbar = true) { if (HorizontalScrollbar) this->style |= WS_HSCROLL; else this->style &= ~WS_HSCROLL; return this->me(); }
+	T &WithTabStop(bool TabStop = true) { if (TabStop) this->style |= WS_TABSTOP; else this->style &= ~WS_TABSTOP; return this->me(); }
+#if WINVER >= 0x0400
+	T &WithRaisedEdge(bool RaisedEdge = true) { if (RaisedEdge) this->exstyle |= WS_EX_WINDOWEDGE; else this->exstyle &= ~WS_EX_WINDOWEDGE; return this->me(); }
+	T &WithSunkenEdge(bool SunkenEdge = true) { if (SunkenEdge) this->exstyle |= WS_EX_CLIENTEDGE; else this->exstyle &= ~WS_EX_CLIENTEDGE; return this->me(); }
+#endif
+};
+
+class DialogGroupBuilder : public DialogControlBuilder<DialogGroupBuilder>
+{
+protected:
+	friend class DialogTemplate;
+	std::wstring groupName;
+public:
+	DialogGroupBuilder(const std::wstring &newGroupName) : DialogControlBuilder(GROUP_CONTROL), groupName(newGroupName) { }
+};
+
+template<class T> class DialogInGroupBuilder : public DialogControlBuilder<T>
+{
+protected:
+	friend class DialogTemplate;
+	std::wstring groupName;
+public:
+	DialogInGroupBuilder(DialogControlType Type) : DialogControlBuilder<T>(Type), groupName(L"") { }
+	T &InGroup(const std::wstring &GroupName) { this->groupName = GroupName; return this->me(); }
+};
+
+class DialogEditBoxBuilder : public DialogInGroupBuilder<DialogEditBoxBuilder>
+{
+protected:
+	friend class DialogTemplate;
+public:
+	DialogEditBoxBuilder() : DialogInGroupBuilder(EDITBOX_CONTROL) { }
+	DialogEditBoxBuilder &IsLeftJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_LEFT; return this->me(); }
+	DialogEditBoxBuilder &IsCenterJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_CENTER; return this->me(); }
+	DialogEditBoxBuilder &IsRightJustified() { this->style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); this->style |= ES_RIGHT; return this->me(); }
+	DialogEditBoxBuilder &IsMultiline(bool Multiline = true) { if (Multiline) this->style |= ES_MULTILINE; else this->style &= ~ES_MULTILINE; return this->me(); }
+	DialogEditBoxBuilder &WithAllUppercase(bool AllUppercase = true) { if (AllUppercase) this->style |= ES_UPPERCASE; else this->style &= ~ES_UPPERCASE; return this->me(); }
+	DialogEditBoxBuilder &WithAllLowercase(bool AllLowercase = true) { if (AllLowercase) this->style |= ES_LOWERCASE; else this->style &= ~ES_LOWERCASE; return this->me(); }
+	DialogEditBoxBuilder &IsPasswordInput(bool PasswordInput = true) { if (PasswordInput) this->style |= ES_PASSWORD; else this->style &= ~ES_PASSWORD; return this->me(); }
+	DialogEditBoxBuilder &WithAutoVScroll(bool AutoVScroll = true) { if (AutoVScroll) this->style |= ES_AUTOVSCROLL; else this->style &= ~ES_AUTOVSCROLL; return this->me(); }
+	DialogEditBoxBuilder &WithAutoHScroll(bool AutoHScroll = true) { if (AutoHScroll) this->style |= ES_AUTOHSCROLL; else this->style &= ~ES_AUTOHSCROLL; return this->me(); }
+	DialogEditBoxBuilder &WithDontHideSelection(bool DontHideSelection = true) { if (DontHideSelection) this->style |= ES_NOHIDESEL; else this->style &= ~ES_NOHIDESEL; return this->me(); }
+	DialogEditBoxBuilder &IsReadOnly(bool ReadOnly = true) { if (ReadOnly) this->style |= ES_READONLY; else this->style &= ~ES_READONLY; return this->me(); }
+	DialogEditBoxBuilder &WithWantReturn(bool WantReturn = true) { if (WantReturn) this->style |= ES_WANTRETURN; else this->style &= ~ES_WANTRETURN; return this->me(); }
+};
+
+template<class T> class DialogControlWithLabelBuilder : public DialogInGroupBuilder<T>
+{
+protected:
+	friend class DialogTemplate;
+	std::wstring label;
+public:
+	DialogControlWithLabelBuilder(DialogControlType Type, const std::wstring &Label) : DialogInGroupBuilder<T>(Type), label(Label) { }
+};
+
+class DialogLabelBuilder : public DialogControlWithLabelBuilder<DialogLabelBuilder>
+{
+protected:
+	friend class DialogTemplate;
+public:
+	DialogLabelBuilder(const std::wstring &Label) : DialogControlWithLabelBuilder(LABEL_CONTROL, Label) { }
+	DialogLabelBuilder &IsLeftJustified(bool WithWordWrap = false)
+	{
+		this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP);
+		if (WithWordWrap)
+			this->style |= SS_LEFTNOWORDWRAP;
+		else
+			this->style |= SS_LEFT;
+		return this->me();
+	}
+	DialogLabelBuilder &IsCenterJustified() { this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP); this->style |= SS_CENTER; return this->me(); }
+	DialogLabelBuilder &IsRightJustified() { this->style &= ~(SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP); this->style |= SS_RIGHT; return this->me(); }
+	DialogLabelBuilder &WithAmpsNotTranslated(bool AmpsNotTranslated = true) { if (AmpsNotTranslated) this->style |= SS_NOPREFIX; else this->style &= ~SS_NOPREFIX; return this->me(); }
+#if WINVER >= 0x0400
+	DialogLabelBuilder &WithNotify(bool Notify = true) { if (Notify) this->style |= SS_NOTIFY; else this->style &= ~SS_NOTIFY; return this->me(); }
+#endif
+};
+
+template<class T> class DialogButtonBaseBuilder : public DialogControlWithLabelBuilder<T>
+{
+protected:
+	friend class DialogTemplate;
+public:
+	DialogButtonBaseBuilder(DialogControlType Type, const std::wstring &Label) : DialogControlWithLabelBuilder<T>(Type, Label) { }
+#if WINVER >= 0x0400
+	T &IsLeftJustified(bool LeftJustified = true)
+	{
+		if (LeftJustified)
+		{
+			this->style |= BS_LEFT;
+			this->style &= ~BS_RIGHT;
+		}
+		else
+			this->style &= ~BS_LEFT;
+		return this->me();
+	}
+	T &IsRightJustified(bool RightJustified = true)
+	{
+		if (RightJustified)
+		{
+			this->style |= BS_RIGHT;
+			this->style &= ~BS_LEFT;
+		}
+		else
+			this->style &= ~BS_RIGHT;
+		return this->me();
+	}
+	T &IsCenterJustified(bool CenterJustified = true) { if (CenterJustified) this->style |= BS_CENTER; else this->style &= ~BS_CENTER; return this->me(); }
+	T &WithVerticalTop(bool VerticalTop = true)
+	{
+		if (VerticalTop)
+		{
+			this->style |= BS_TOP;
+			this->style &= ~BS_BOTTOM;
+		}
+		else
+			this->style &= ~BS_TOP;
+		return this->me();
+	}
+	T &WithVerticalBottom(bool VerticalBottom = true)
+	{
+		if (VerticalBottom)
+		{
+			this->style |= BS_BOTTOM;
+			this->style &= ~BS_TOP;
+		}
+		else
+			this->style &= ~BS_BOTTOM;
+		return this->me();
+	}
+	T &WithVerticalCenter(bool VerticalCenter = true) { if (VerticalCenter) this->style |= BS_VCENTER; else this->style &= ~BS_VCENTER; return this->me(); }
+	T &IsMultiline(bool Multiline = true) { if (Multiline) this->style |= BS_MULTILINE; else this->style &= ~BS_MULTILINE; return this->me(); }
+	T &WithNotify(bool Notify = true) { if (Notify) this->style |= BS_NOTIFY; else this->style &= ~BS_NOTIFY; return this->me(); }
+	T &IsFlat(bool Flat = true) { if (Flat) this->style |= BS_FLAT; else this->style &= ~BS_FLAT; return this->me(); }
+#endif
+};
+
+class DialogButtonBuilder : public DialogButtonBaseBuilder<DialogButtonBuilder>
+{
+protected:
+	friend class DialogTemplate;
+public:
+	DialogButtonBuilder(const std::wstring &Label) : DialogButtonBaseBuilder(BUTTON_CONTROL, Label) { }
+	DialogButtonBuilder &IsDefault(bool Default = true) { if (Default) this->style |= BS_DEFPUSHBUTTON; else this->style &= ~BS_DEFPUSHBUTTON; return this->me(); }
+};
+
+class DialogCheckBoxBuilder : public DialogButtonBaseBuilder<DialogCheckBoxBuilder>
+{
+protected:
+	friend class DialogTemplate;
+public:
+	DialogCheckBoxBuilder(const std::wstring &Label) : DialogButtonBaseBuilder(CHECKBOX_CONTROL, Label) { this->style |= BS_AUTOCHECKBOX; }
+	DialogCheckBoxBuilder &WithTextOnLeft(bool TextOnLeft = true) { if (TextOnLeft) this->style |= BS_LEFTTEXT; else this->style &= ~BS_LEFTTEXT; return this->me(); }
+	DialogCheckBoxBuilder &LikePushButton(bool PushButton = true) { if (PushButton) this->style |= BS_PUSHLIKE; else this->style &= ~BS_PUSHLIKE; return this->me(); }
+};
+
+class DialogListBoxBuilder : public DialogInGroupBuilder<DialogListBoxBuilder>
+{
+protected:
+	friend class DialogTemplate;
+public:
+	DialogListBoxBuilder() : DialogInGroupBuilder(LISTBOX_CONTROL) { }
+	DialogListBoxBuilder &WithNotify(bool Notify = true) { if (Notify) this->style |= LBS_NOTIFY; else this->style &= ~LBS_NOTIFY; return this->me(); }
+	DialogListBoxBuilder &WithSort(bool Sort = true) { if (Sort) this->style |= LBS_SORT; else this->style &= ~LBS_SORT; return this->me(); }
+	DialogListBoxBuilder &WithMultipleSelect(bool MultipleSelect = true) { if (MultipleSelect) this->style |= LBS_MULTIPLESEL; else this->style &= ~LBS_MULTIPLESEL; return this->me(); }
+	DialogListBoxBuilder &WithExactHeight(bool ExactHeight = true) { if (ExactHeight) this->style |= LBS_NOINTEGRALHEIGHT; else this->style &= ~LBS_NOINTEGRALHEIGHT; return this->me(); }
+	DialogListBoxBuilder &WithMultipleColumns(bool MultipleColumns = true) { if (MultipleColumns) this->style |= LBS_MULTICOLUMN; else this->style &= ~LBS_MULTICOLUMN; return this->me(); }
+	DialogListBoxBuilder &WithExtendedSelect(bool ExtendedSelect = true) { if (ExtendedSelect) this->style |= LBS_EXTENDEDSEL; else this->style &= ~LBS_EXTENDEDSEL; return this->me(); }
+	DialogListBoxBuilder &WithDisabledNoScroll(bool DisabledNoScroll = true) { if (DisabledNoScroll) this->style |= LBS_DISABLENOSCROLL; else this->style &= ~LBS_DISABLENOSCROLL; return this->me(); }
+#if WINVER >= 0x0400
+	DialogListBoxBuilder &WithNoSelect(bool NoSelect = true) { if (NoSelect) this->style |= LBS_NOSEL; else this->style &= ~LBS_NOSEL; return this->me(); }
+#endif
+};
+
+class DialogComboBoxBuilder : public DialogInGroupBuilder<DialogComboBoxBuilder>
+{
+protected:
+	friend class DialogTemplate;
+public:
+	DialogComboBoxBuilder() : DialogInGroupBuilder(COMBOBOX_CONTROL) { }
+	DialogComboBoxBuilder &IsSimple() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_SIMPLE; return this->me(); }
+	DialogComboBoxBuilder &IsDropDown() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_DROPDOWN; return this->me(); }
+	DialogComboBoxBuilder &IsDropDownList() { this->style &= ~(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST); this->style |= CBS_DROPDOWNLIST; return this->me(); }
+	DialogComboBoxBuilder &WithAutoHScroll(bool AutoHScroll = true) { if (AutoHScroll) this->style |= CBS_AUTOHSCROLL; else this->style &= ~CBS_AUTOHSCROLL; return this->me(); }
+	DialogComboBoxBuilder &WithSort(bool Sort = true) { if (Sort) this->style |= CBS_SORT; else this->style &= ~CBS_SORT; return this->me(); }
+	DialogComboBoxBuilder &WithExactHeight(bool ExactHeight = true) { if (ExactHeight) this->style |= CBS_NOINTEGRALHEIGHT; else this->style &= ~CBS_NOINTEGRALHEIGHT; return this->me(); }
+	DialogComboBoxBuilder &WithDisabledNoScroll(bool DisabledNoScroll = true) { if (DisabledNoScroll) this->style |= CBS_DISABLENOSCROLL; else this->style &= ~CBS_DISABLENOSCROLL; return this->me(); }
+#if WINVER >= 0x0400
+	DialogComboBoxBuilder &WithAllLowercase(bool AllLowercase = true) { if (AllLowercase) this->style |= CBS_LOWERCASE; else this->style &= ~CBS_LOWERCASE; return this->me(); }
+	DialogComboBoxBuilder &WithAllUppercase(bool AllUppercase = true) { if (AllUppercase) this->style |= CBS_UPPERCASE; else this->style &= ~CBS_UPPERCASE; return this->me(); }
+#endif
+};
+
+class DialogTemplate
+{
+	class DialogControl;
+
+	typedef std::vector<std::unique_ptr<DialogControl>> Controls;
+
+	class DialogControl
+	{
+	protected:
+		DialogControlType controlType;
+		uint32_t style, exstyle;
+		Rect<short> rect;
+		short id;
+		std::unique_ptr<RelativePosition> relativePosition;
+
+		friend class DialogTemplate;
+		DialogControl() : controlType(NO_CONTROL), style(0), exstyle(0), rect(), id(-1), relativePosition() { }
+		DialogControl(const DialogControl &control) : controlType(control.controlType), style(control.style), exstyle(control.exstyle), rect(control.rect), id(control.id),
+			relativePosition(control.relativePosition ? control.relativePosition->Clone() : nullptr) { }
+		DialogControl &operator=(const DialogControl &control)
+		{
+			this->controlType = control.controlType;
+			this->style = control.style;
+			this->exstyle = control.exstyle;
+			this->rect = control.rect;
+			this->id = control.id;
+			if (control.relativePosition)
+				this->relativePosition.reset(control.relativePosition->Clone());
+			else
+				this->relativePosition.reset();
+
+			return *this;
+		}
+	public:
+		virtual ~DialogControl() { }
+		template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder)
+		{
+			auto control = std::unique_ptr<Control>(new Control());
+
+			control->controlType = builder.controlType;
+			control->style = builder.style;
+			control->exstyle = builder.exstyle;
+			control->rect = builder.rect;
+			control->id = builder.id;
+			if (builder.relativePosition)
+				control->relativePosition.reset(builder.relativePosition->Clone());
+
+			return control;
+		}
+		virtual uint16_t GetControlCount() const { return 1; }
+		virtual short GetControlHeight() const { return this->rect.size.height; }
+		virtual std::vector<uint8_t> GenerateControlTemplate() const = 0;
+		virtual DialogControl *Clone() const = 0;
+	};
+
+	class DialogGroup : public DialogControl
+	{
+	protected:
+		DialogTemplate::Controls controls;
+		std::wstring groupName;
+
+		friend class DialogTemplate;
+		friend class DialogControl;
+		DialogGroup() : DialogControl(), controls(), groupName(L"") { }
+		DialogGroup(const DialogGroup &control) : DialogControl(control), controls(), groupName(control.groupName)
+		{
+			std::for_each(control.controls.begin(), control.controls.end(), [&](const std::unique_ptr<DialogControl> &control) { this->controls.push_back(std::unique_ptr<DialogControl>(control->Clone())); });
+		}
+		DialogGroup &operator=(const DialogGroup &control)
+		{
+			DialogControl::operator=(control);
+
+			this->controls.clear();
+			std::for_each(control.controls.begin(), control.controls.end(), [&](const std::unique_ptr<DialogControl> &control) { this->controls.push_back(std::unique_ptr<DialogControl>(control->Clone())); });
+
+			this->groupName = control.groupName;
+
+			return *this;
+		}
+	public:
+		static std::unique_ptr<DialogGroup> CreateControl(const DialogControlBuilder<DialogGroupBuilder> &builder)
+		{
+			auto control = DialogControl::CreateControl<DialogGroup>(builder);
+
+			control->groupName = dynamic_cast<const DialogGroupBuilder &>(builder).groupName;
+
+			return control;
+		}
+		void CalculatePositions(bool doRightAndBottom = false);
+		void CalculateSize();
+		uint16_t GetControlCount() const;
+		std::vector<uint8_t> GenerateControlTemplate() const;
+		DialogGroup *Clone() const { return new DialogGroup(*this); }
+	};
+
+	class DialogControlWithoutLabel : public DialogControl
+	{
+	protected:
+		uint16_t type;
+
+		friend class DialogTemplate;
+		friend class DialogControl;
+		DialogControlWithoutLabel() : DialogControl(), type(0) { }
+		DialogControlWithoutLabel(const DialogControlWithoutLabel &control) : DialogControl(control), type(control.type) { }
+		DialogControlWithoutLabel &operator=(const DialogControlWithoutLabel &control)
+		{
+			DialogControl::operator=(control);
+
+			this->type = control.type;
+
+			return *this;
+		}
+	public:
+		template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type)
+		{
+			auto control = DialogControl::CreateControl<Control>(builder);
+
+			control->type = Type;
+
+			return control;
+		}
+		virtual std::vector<uint8_t> GenerateControlTemplate() const;
+		virtual DialogControlWithoutLabel *Clone() const { return new DialogControlWithoutLabel(*this); }
+	};
+
+	class DialogControlWithLabel : public DialogControl
+	{
+	protected:
+		uint16_t type;
+		std::wstring label;
+
+		friend class DialogTemplate;
+		friend class DialogControl;
+		DialogControlWithLabel() : DialogControl(), type(0), label(L"") { }
+		DialogControlWithLabel(const DialogControlWithLabel &control) : DialogControl(control), type(control.type), label(control.label) { }
+		DialogControlWithLabel &operator=(const DialogControlWithLabel &control)
+		{
+			DialogControl::operator=(control);
+
+			this->type = control.type;
+			this->label = control.label;
+
+			return *this;
+		}
+	public:
+		template<typename Control, typename Builder> static std::unique_ptr<Control> CreateControl(const DialogControlBuilder<Builder> &builder, uint16_t Type)
+		{
+			auto control = DialogControl::CreateControl<Control>(builder);
+
+			control->type = Type;
+			control->label = dynamic_cast<const DialogControlWithLabelBuilder<Builder> &>(builder).label;
+
+			return control;
+		}
+		virtual std::vector<uint8_t> GenerateControlTemplate() const;
+		virtual DialogControlWithLabel *Clone() const { return new DialogControlWithLabel(*this); }
+	};
+
+	class DialogEditBox : public DialogControlWithoutLabel
+	{
+	protected:
+		friend class DialogTemplate;
+		friend class DialogControl;
+		DialogEditBox() : DialogControlWithoutLabel() { }
+	public:
+		static std::unique_ptr<DialogEditBox> CreateControl(const DialogControlBuilder<DialogEditBoxBuilder> &builder)
+		{
+			return DialogControlWithoutLabel::CreateControl<DialogEditBox>(builder, 0x0081);
+		}
+	};
+
+	class DialogLabel : public DialogControlWithLabel
+	{
+	protected:
+		friend class DialogTemplate;
+		friend class DialogControl;
+		DialogLabel() : DialogControlWithLabel() { }
+	public:
+		static std::unique_ptr<DialogLabel> CreateControl(const DialogControlBuilder<DialogLabelBuilder> &builder)
+		{
+			return DialogControlWithLabel::CreateControl<DialogLabel>(builder, 0x0082);
+		}
+	};
+
+	class DialogButton : public DialogControlWithLabel
+	{
+	protected:
+		friend class DialogTemplate;
+		friend class DialogControl;
+		DialogButton() : DialogControlWithLabel() { }
+	public:
+		template<typename Builder> static std::unique_ptr<DialogButton> CreateControl(const DialogControlBuilder<Builder> &builder)
+		{
+			return DialogControlWithLabel::CreateControl<DialogButton>(builder, 0x0080);
+		}
+	};
+
+	class DialogListBox : public DialogControlWithoutLabel
+	{
+	protected:
+		friend class DialogTemplate;
+		friend class DialogControl;
+		DialogListBox() : DialogControlWithoutLabel() { }
+	public:
+		static std::unique_ptr<DialogListBox> CreateControl(const DialogControlBuilder<DialogListBoxBuilder> &builder)
+		{
+			return DialogControlWithoutLabel::CreateControl<DialogListBox>(builder, 0x0083);
+		}
+	};
+
+	class DialogComboBox : public DialogControlWithoutLabel
+	{
+	protected:
+		friend class DialogTemplate;
+		friend class DialogControl;
+		DialogComboBox() : DialogControlWithoutLabel() { }
+	public:
+		static std::unique_ptr<DialogComboBox> CreateControl(const DialogControlBuilder<DialogComboBoxBuilder> &builder)
+		{
+			return DialogControlWithoutLabel::CreateControl<DialogComboBox>(builder, 0x0085);
+		}
+		short GetControlHeight() const { return (this->style & CBS_SIMPLE && !(this->style & CBS_DROPDOWNLIST)) ? this->rect.size.height : 14; }
+	};
+
+	std::wstring title;
+	uint32_t style, exstyle;
+	std::wstring fontName;
+	uint16_t fontSizeInPts;
+	Size<short> size;
+	DialogTemplate::Controls controls;
+	std::vector<uint8_t> templateData;
+
+	template<typename Builder> void AddControlToGroup(std::unique_ptr<DialogControl> &&control, const DialogControlBuilder<Builder> &builder)
+	{
+		const auto &groupBuilder = dynamic_cast<const DialogInGroupBuilder<Builder> &>(builder);
+		if (groupBuilder.groupName.empty())
+		{
+			if (builder.index == -1)
+				this->controls.push_back(std::move(control));
+			else
+				this->controls.insert(this->controls.begin() + builder.index, std::move(control));
+		}
+		else
+		{
+			for (auto curr = this->controls.begin(), end = this->controls.end(); curr != end; ++curr)
+			{
+				if ((*curr)->controlType != GROUP_CONTROL)
+					continue;
+				DialogGroup *group = dynamic_cast<DialogGroup *>(curr->get());
+				if (group->groupName == groupBuilder.groupName)
+				{
+					if (builder.index == -1)
+						group->controls.push_back(std::move(control));
+					else
+						group->controls.insert(group->controls.begin() + builder.index, std::move(control));
+					return;
+				}
+			}
+			throw std::runtime_error("Group " + UtfConverter::ToUtf8(groupBuilder.groupName) + " was not found.");
+		}
+	}
+	uint16_t GetTotalControlCount() const;
+	bool CalculateControlPosition(short index, bool doRightAndBottom = false);
+	void CalculateSize();
+public:
+	DialogTemplate() : title(L""), style(0), exstyle(0), fontName(L""), fontSizeInPts(0), size(), controls(), templateData() { }
+	DialogTemplate(const DialogBuilder &builder) : title(builder.title), style(builder.style), exstyle(builder.exstyle), fontName(builder.fontName), fontSizeInPts(builder.fontSizeInPts),
+		size(builder.size), controls(), templateData() { }
+	DialogTemplate(const DialogTemplate &dlg) : title(dlg.title), style(dlg.style), exstyle(dlg.style), fontName(dlg.fontName), fontSizeInPts(dlg.fontSizeInPts), size(dlg.size),
+		controls(), templateData()
+	{
+		std::for_each(dlg.controls.begin(), dlg.controls.end(), [&](const std::unique_ptr<DialogControl> &control) { this->controls.push_back(std::unique_ptr<DialogControl>(control->Clone())); });
+	}
+	DialogTemplate &operator=(const DialogBuilder &builder)
+	{
+		this->title = builder.title;
+		this->style = builder.style;
+		this->exstyle = builder.exstyle;
+		this->fontName = builder.fontName;
+		this->fontSizeInPts = builder.fontSizeInPts;
+		this->size = builder.size;
+		if (builder.resetControls)
+			this->controls.clear();
+
+		return *this;
+	}
+	DialogTemplate &operator=(const DialogTemplate &dlg)
+	{
+		this->title = dlg.title;
+		this->style = dlg.style;
+		this->exstyle = dlg.exstyle;
+		this->fontName = dlg.fontName;
+		this->fontSizeInPts = dlg.fontSizeInPts;
+		this->size = dlg.size;
+		this->controls.clear();
+		std::for_each(dlg.controls.begin(), dlg.controls.end(), [&](const std::unique_ptr<DialogControl> &control) { this->controls.push_back(std::unique_ptr<DialogControl>(control->Clone())); });
+
+		return *this;
+	}
+	void AddGroupControl(const DialogControlBuilder<DialogGroupBuilder> &builder);
+	void AddEditBoxControl(const DialogControlBuilder<DialogEditBoxBuilder> &builder);
+	void AddLabelControl(const DialogControlBuilder<DialogLabelBuilder> &builder);
+	void AddCheckBoxControl(const DialogControlBuilder<DialogCheckBoxBuilder> &builder);
+	void AddButtonControl(const DialogControlBuilder<DialogButtonBuilder> &builder);
+	void AddListBoxControl(const DialogControlBuilder<DialogListBoxBuilder> &builder);
+	void AddComboBoxControl(const DialogControlBuilder<DialogComboBoxBuilder> &builder);
+	void AutoSize();
+	const DLGTEMPLATE *GenerateTemplate();
+};
+
+#endif
+

--- a/src/in_xsf_framework/in_xsf_framework.vcxproj
+++ b/src/in_xsf_framework/in_xsf_framework.vcxproj
@@ -45,7 +45,7 @@
       <WarningLevel>Level4</WarningLevel>
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;UNICODE_INPUT_PLUGIN;_DEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4127;4244;4512;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>
@@ -60,7 +60,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;WINAMP_PLUGIN;UNICODE_INPUT_PLUGIN;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>G:\Code\my_xsf\src;$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(zlibRootDir)\include;$(WinampSDKDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4127;4244;4512;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>