Creating WinAPI windows and controls can be a pain and quite difficult/annoying at times. Most of the time, I find myself searching MSDN, DaniWeb, and StackOverflow. I hate having to use external libraries unless I absolutely have no other choice.
Below contains code for creating WinAPI windows, Controls, Sub-Classing, and EventHandling for each control. There is a sample working code below this article and an image of what the sample code produces.
There are only 4 files to include to your projects:
Form.hpp -- Form.cpp
Controls.hpp -- Controls.cpp
The code for these files are as follows:
Form.hpp:
#ifndef FORM_HPP_INCLUDED
#define FORM_HPP_INCLUDED
#include <windows.h>
#include <iostream>
class Form
{
public:
Form(std::string Title, std::string Class, WNDPROC WindowProcedure = nullptr, WNDCLASSEX WndClass = {0}, DWORD dwStyleEx = 0, DWORD dwStyle = WS_OVERLAPPEDWINDOW, POINT Location = {CW_USEDEFAULT, CW_USEDEFAULT}, int Width = CW_USEDEFAULT, int Height = CW_USEDEFAULT, HWND Parent = HWND_DESKTOP, HMENU Menu = nullptr);
Form(const Form &F) = delete;
Form(Form && F) = delete;
virtual ~Form();
private:
bool Message = false;
HWND WindowHandle = nullptr;
Form& operator = (const Form &F) = delete;
Form& operator = (Form && F) = delete;
static LRESULT __stdcall WindowProcedure(HWND Hwnd, UINT Msg, WPARAM wParam, LPARAM lParam);
protected:
MSG Messages = {nullptr};
virtual int Show() = 0;
virtual int MessageLoop();
virtual HWND Handle() const {return WindowHandle;}
virtual void SubClassWindow(HWND Window, WNDPROC SubClassProc);
virtual void UnSubClassWindow(HWND Window);
};
#endif // FORM_HPP_INCLUDED
Form.cpp:
#include "Form.hpp"
void Form::SubClassWindow(HWND Window, WNDPROC SubClassProc)
{
SetWindowLongPtr(Window, GWLP_USERDATA, static_cast<LONG_PTR>(SetWindowLongPtr(Window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SubClassProc))));
}
void Form::UnSubClassWindow(HWND Window)
{
SetWindowLongPtr(Window, GWLP_WNDPROC, GetWindowLongPtr(Window, GWLP_USERDATA));
}
int Form::MessageLoop()
{
if (!Message)
{
Message = true;
while(GetMessage(&Messages, nullptr, 0, 0))
{
TranslateMessage(&Messages);
DispatchMessage(&Messages);
}
return Messages.wParam;
}
return 0;
}
Form::~Form() {}
Form::Form(std::string Title, std::string Class, WNDPROC WindowProcedure, WNDCLASSEX WndClass, DWORD dwStyleEx, DWORD dwStyle, POINT Location, int Width, int Height, HWND Parent, HMENU Menu)
{
if (WindowProcedure == nullptr)
{
WindowProcedure = Form::WindowProcedure;
}
if (!WndClass.cbSize)
{
WndClass =
{
sizeof(WNDCLASSEX), CS_DBLCLKS, WindowProcedure,
0, 0, GetModuleHandle(nullptr), LoadIcon(nullptr, IDI_APPLICATION),
LoadCursor(nullptr, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_BACKGROUND),
nullptr, Class.c_str(), LoadIcon(nullptr, IDI_APPLICATION)
};
}
if(RegisterClassEx(&WndClass))
{
WindowHandle = CreateWindowEx(dwStyleEx, Class.c_str(), Title.c_str(), dwStyle, Location.x, Location.y, Width, Height, Parent, Menu, GetModuleHandle(nullptr), this);
}
}
LRESULT __stdcall Form::WindowProcedure(HWND Hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch(Msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(Hwnd, Msg, wParam, lParam);
}
return 0;
}
Controls.hpp:
#ifndef CONTROLS_HPP_INCLUDED
#define CONTROLS_HPP_INCLUDED
#include <windows.h>
#include <Commctrl.h>
#include <string>
#include <functional>
#include <array>
#include <vector>
class Control
{
private:
HMENU ID;
static SUBCLASSPROC GlobalSubClass;
HWND Handle, Parent;
std::string Class, Title;
DWORD dwExStyle, dwStyle;
POINT Location;
int Width, Height;
void Swap(Control &C);
std::array<std::function<void(HWND, UINT, WPARAM, LPARAM)>, 20> Functions;
public:
Control(const Control &C) = delete;
Control(Control && C);
Control(DWORD dwExStyle, std::string Class, std::string Title, DWORD dwStyle, POINT Location, int Width, int Height, HWND Parent, HINSTANCE Instance, void* LParam);
Control(DWORD dwExStyle, std::string Class, std::string Title, DWORD dwStyle, POINT Location, int Width, int Height, HWND Parent, HMENU ID, HINSTANCE Instance, void* LParam);
virtual ~Control();
virtual HMENU GetID() const;
virtual HWND GetHandle() const;
virtual HWND GetParent() const;
virtual std::string GetClass() const;
virtual int GetWidth() const;
virtual int GetHeight() const;
virtual POINT GetLocation() const;
virtual bool IsEnabled() const;
virtual bool IsVisible() const;
virtual bool GetTabStop() const;
virtual std::string GetText() const;
virtual void SetTabStop(bool Enabled);
virtual void SetEnabled(bool Enabled);
virtual void SetVisibility(bool Visible);
virtual void SetBounds(RECT Bounds);
virtual void SetText(const std::string &Text);
virtual void SetParent(HWND Parent);
virtual void SetLocation(POINT Location);
virtual void SetSize(int Width, int Height);
virtual void SetStyle(DWORD Style, bool RemoveStyle = false);
virtual void Dispose();
Control& operator = (const Control &C) = delete;
Control& operator = (Control && C);
static void SetGlobalSubClass(SUBCLASSPROC Procedure);
void SetEvent(std::size_t Index, std::function<void(HWND, UINT, WPARAM, LPARAM)> Func);
void ProcessEvent(std::size_t Index, HWND Hwnd, UINT Msg, WPARAM wParam, LPARAM lParam);
protected:
Control();
bool Initialized;
void UnInitialized();
static std::size_t IDs;
void SetParentHandle(HWND Parent);
static LRESULT __stdcall SubClass(HWND Window, UINT Msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
};
class Button : public Control
{
public:
Button();
Button(const Button &B) = delete;
Button(Button && B);
Button(std::string Title, POINT Location, int Width, int Height, HWND Parent);
virtual ~Button();
Button& operator = (const Button &B) = delete;
virtual Button& operator = (Button && B);
};
class Label : public Control
{
public:
Label();
Label(const Label &L) = delete;
Label(Label&& L);
Label(std::string Text, POINT Location, int Width, int Height, HWND Parent);
virtual ~Label();
Label& operator = (const Label &L) = delete;
virtual Label& operator = (Label&& L);
};
class CheckBox : public Control //BS_PUSHLIKE
{
public:
CheckBox();
CheckBox(const CheckBox &C) = delete;
CheckBox(CheckBox && C);
CheckBox(std::string Title, POINT Location, int Width, int Height, HWND Parent, bool Checked = false);
virtual ~CheckBox();
virtual bool IsChecked();
virtual void SetChecked(bool Checked);
CheckBox& operator = (const CheckBox &C) = delete;
virtual CheckBox& operator = (CheckBox && C);
};
class TextBox : public Control
{
public:
TextBox();
TextBox(const TextBox &T) = delete;
TextBox(TextBox && T);
TextBox(std::string Text, POINT Location, int Width, int Height, HWND Parent, bool MultiLine = false);
virtual ~TextBox();
virtual void SetReadOnly(bool ReadOnly);
virtual void SetPassword(bool Enabled, char PasswordChar = '*');
virtual std::uint32_t GetTextLength() const;
virtual void AppendText(const std::string &Text) const;
virtual void ShowScrollBar(bool Show, int wBar = SB_VERT);
TextBox& operator = (const TextBox &T) = delete;
virtual TextBox& operator = (TextBox && T);
};
class ListBox : public Control
{
public:
ListBox();
ListBox(const ListBox &L) = delete;
ListBox(ListBox && L);
ListBox(POINT Location, int Width, int Height, HWND Parent);
virtual ~ListBox();
virtual std::string GetText() = delete;
virtual int GetItemCount() const;
virtual int GetSelectedIndex() const;
virtual void SetSelectedIndex(int Index);
virtual void AddItem(const std::string &Item, int Index = -1);
virtual void RemoveItem(int Index);
virtual void Clear();
virtual int GetIndexOf(const std::string &Item);
virtual int GetIndexPartial(const std::string &Item);
virtual void SetColumnWidth(int Width);
virtual std::string GetItem(int Index) const;
ListBox& operator = (const ListBox &L) = delete;
virtual ListBox& operator = (ListBox && L);
};
class ComboBox : public Control
{
public:
enum DropDownStyle {STYLE_SIMPLE, STYLE_DROPDOWN, STYLE_DROPDOWN_LIST};
ComboBox();
ComboBox(const ComboBox &C) = delete;
ComboBox(ComboBox && C);
ComboBox(DropDownStyle Style, POINT Location, int Width, int Height, HWND Parent);
virtual ~ComboBox();
virtual std::string GetText() = delete;
virtual int GetItemCount() const;
virtual int GetSelectedIndex() const;
virtual void SetSelectedIndex(int Index);
virtual void AddItem(const std::string &Item, int Index = -1);
virtual void RemoveItem(int Index);
virtual void Clear();
virtual int GetIndexOf(const std::string &Item);
virtual int GetIndexPartial(const std::string &Item);
virtual void SetDropDownWidth(int Width);
virtual void SetDropDownStyle(DropDownStyle Style);
virtual std::string GetItem(int Index) const;
ComboBox& operator = (const ComboBox &C) = delete;
virtual ComboBox& operator = (ComboBox && C);
};
class PictureBox: public Control
{
public:
PictureBox();
PictureBox(const PictureBox &P) = delete;
PictureBox(PictureBox && P);
PictureBox(POINT Location, int Width, int Height, HWND Parent);
virtual ~PictureBox();
virtual std::string GetText() = delete;
virtual void SetImage(HBITMAP Img);
PictureBox& operator = (const PictureBox &P) = delete;
virtual PictureBox& operator = (PictureBox && P);
};
class MenuBar: public Control
{
private:
std::vector<HMENU> Menus;
public:
MenuBar();
MenuBar(const MenuBar &M) = delete;
MenuBar(MenuBar && M);
MenuBar(HWND Parent);
virtual ~MenuBar();
std::string GetText(HMENU Menu, int Position);
std::uint32_t GetMenuItemID(HMENU Menu, int Position);
HMENU FindMenuItem(std::string MenuName);
HMENU FindMenuItem(HMENU Parent, std::string MenuName);
void CreateSubMenu(HMENU Parent, std::string Name, DWORD Style);
void AddMenuItem(std::string Name, DWORD Style);
void AppendMenuItem(HMENU Parent, std::string Name, DWORD Style);
bool ToggleItemCheck(HMENU MenuItem, int Position);
bool IsItemChecked(HMENU MenuItem, int Position);
void Show();
MenuBar& operator = (const MenuBar &M) = delete;
virtual MenuBar& operator = (MenuBar && M);
};
class ToolBar: public Control
{
public:
ToolBar();
ToolBar(const ToolBar &T) = delete;
ToolBar(ToolBar && T);
ToolBar(POINT Location, int Width, int Height, HWND Parent);
virtual ~ToolBar();
virtual std::string GetText() = delete;
ToolBar& operator = (const ToolBar &T) = delete;
virtual ToolBar& operator = (ToolBar && T);
};
#endif // CONTROLS_HPP_INCLUDED
Controls.cpp:
#include "Controls.hpp"
std::size_t Control::IDs = 0;
SUBCLASSPROC Control::GlobalSubClass = nullptr;
void Control::Swap(Control &C)
{
using std::swap;
swap(ID, C.ID);
swap(Handle, C.Handle);
swap(Parent, C.Parent);
swap(Class, C.Class);
swap(Title, C.Title);
swap(dwExStyle, C.dwExStyle);
swap(dwStyle, C.dwStyle);
swap(Location, C.Location);
swap(Width, C.Width);
swap(Height, C.Height);
swap(Functions, C.Functions);
swap(Initialized, C.Initialized);
}
void Control::UnInitialized()
{
if (!Initialized)
{
throw std::runtime_error("\nError! Control Not Constructed!");
MessageBox(nullptr, "Control Not Constructed!", "Initialization Error!", MB_ICONERROR);
ExitProcess(0);
}
}
Control::~Control()
{
RemoveWindowSubclass(Handle, GlobalSubClass ? GlobalSubClass : SubClass, reinterpret_cast<UINT_PTR>(ID));
SetWindowSubclass(Handle, GlobalSubClass ? GlobalSubClass : SubClass, reinterpret_cast<UINT_PTR>(ID), 0);
}
Control::Control(Control && C) : ID(std::move(C.ID)), Handle(std::move(C.Handle)), Parent(std::move(C.Parent)), Class(std::move(C.Class)), Title(std::move(C.Title)), dwExStyle(std::move(C.dwExStyle)), dwStyle(std::move(C.dwStyle)), Location(std::move(C.Location)), Width(std::move(C.Width)), Height(std::move(C.Height)), Functions(std::move(C.Functions)), Initialized(std::move(C.Initialized))
{
RemoveWindowSubclass(Handle, GlobalSubClass ? GlobalSubClass : SubClass, reinterpret_cast<UINT_PTR>(ID));
SetWindowSubclass(Handle, GlobalSubClass ? GlobalSubClass : SubClass, reinterpret_cast<UINT_PTR>(ID), reinterpret_cast<DWORD_PTR>(this));
}
Control::Control() : ID(nullptr), Handle(nullptr), Parent(nullptr), Class(std::string()), Title(std::string()), dwExStyle(0), dwStyle(0), Location({0, 0}), Width(0), Height(0), Functions(), Initialized(false) {}
Control::Control(DWORD dwExStyle, std::string Class, std::string Title, DWORD dwStyle, POINT Location, int Width, int Height, HWND Parent, HINSTANCE Instance, void* LParam) : ID(nullptr), Handle(nullptr), Parent(Parent), Class(Class), Title(Title), dwExStyle(dwExStyle), dwStyle(dwStyle), Location(Location), Width(Width), Height(Height), Functions(), Initialized(true)
{
ID = reinterpret_cast<HMENU>(++IDs);
Handle = CreateWindowEx(dwExStyle, Class.c_str(), Title.c_str(), dwStyle, Location.x, Location.y, Width, Height, Parent, ID, Instance, LParam);
SetWindowSubclass(Handle, GlobalSubClass ? GlobalSubClass : SubClass, reinterpret_cast<UINT_PTR>(ID), reinterpret_cast<DWORD_PTR>(this));
}
Control::Control(DWORD dwExStyle, std::string Class, std::string Title, DWORD dwStyle, POINT Location, int Width, int Height, HWND Parent, HMENU ID, HINSTANCE Instance, void* LParam) : ID(ID), Handle(nullptr), Parent(Parent), Class(Class), Title(Title), dwExStyle(dwExStyle), dwStyle(dwStyle), Location(Location), Width(Width), Height(Height), Functions(), Initialized(true)
{
Handle = CreateWindowEx(dwExStyle, Class.c_str(), Title.c_str(), dwStyle, Location.x, Location.y, Width, Height, Parent, ID, Instance, LParam);
SetWindowSubclass(Handle, GlobalSubClass ? GlobalSubClass : SubClass, reinterpret_cast<UINT_PTR>(ID), reinterpret_cast<DWORD_PTR>(this));
}
HMENU Control::GetID() const
{
return ID;
}
HWND Control::GetHandle() const
{
return Handle;
}
HWND Control::GetParent() const
{
return Parent;
}
std::string Control::GetClass() const
{
return Class;
}
int Control::GetWidth() const
{
return Width;
}
int Control::GetHeight() const
{
return Height;
}
POINT Control::GetLocation() const
{
return Location;
}
bool Control::IsEnabled() const
{
return IsWindowEnabled(Handle);
}
bool Control::IsVisible() const
{
return IsWindowVisible(Handle);
}
bool Control::GetTabStop() const
{
return ((GetWindowLongPtr(Handle, GWL_STYLE) & WS_TABSTOP) != 0);
}
void Control::SetTabStop(bool Enabled)
{
SetWindowLongPtr(Handle, GWL_STYLE, GetWindowLongPtr(Handle, GWL_STYLE) | WS_TABSTOP);
}
void Control::SetEnabled(bool Enabled)
{
EnableWindow(Handle, Enabled);
}
void Control::SetVisibility(bool Visible)
{
ShowWindow(Handle, Visible ? SW_SHOW : SW_HIDE);
}
void Control::SetBounds(RECT Bounds)
{
MoveWindow(Handle, Bounds.left, Bounds.top, Bounds.right - Bounds.left, Bounds.bottom - Bounds.top, false);
}
void Control::SetParentHandle(HWND Parent)
{
this->Parent = Parent;
}
std::string Control::GetText() const
{
std::vector<TCHAR> Buffer(GetWindowTextLength(Control::GetHandle()) + 1);
GetWindowText(Control::GetHandle(), Buffer.data(), Buffer.size());
return std::string(Buffer.begin(), Buffer.end());
}
void Control::SetText(const std::string &Text)
{
UnInitialized();
this->Title = Text;
SetWindowText(Handle, Text.c_str());
}
void Control::SetParent(HWND Parent)
{
UnInitialized();
this->Parent = Parent;
::SetParent(Handle, Parent);
ShowWindow(Handle, SW_SHOW);
}
void Control::SetLocation(POINT Location)
{
UnInitialized();
this->Location = Location;
SetWindowPos(Handle, HWND_TOP, Location.x, Location.y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
}
void Control::SetSize(int Width, int Height)
{
UnInitialized();
this->Width = Width;
this->Height = Height;
SetWindowPos(Handle, HWND_TOP, 0, 0, Width, Height, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
}
void Control::SetStyle(DWORD Style, bool RemoveStyle)
{
if (RemoveStyle)
{
SetWindowLong(Handle, GWL_STYLE, GetWindowLong(Handle, GWL_STYLE) & ~Style);
}
else
{
SetWindowLong(Handle, GWL_STYLE, GetWindowLong(Handle, GWL_STYLE) | Style);
}
SetWindowPos(Handle, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
}
void Control::Dispose()
{
ID = nullptr;
Parent = nullptr;
for (int I = 0; I < 6; ++I)
{
Functions[I] = nullptr;
}
if (Handle != nullptr)
{
RemoveWindowSubclass(Handle, GlobalSubClass ? GlobalSubClass : SubClass, reinterpret_cast<UINT_PTR>(ID));
DestroyWindow(Handle);
Handle = nullptr;
}
}
Control& Control::operator = (Control && C)
{
C.Swap(*this);
RemoveWindowSubclass(Handle, GlobalSubClass ? GlobalSubClass : SubClass, reinterpret_cast<UINT_PTR>(ID));
SetWindowSubclass(Handle, GlobalSubClass ? GlobalSubClass : SubClass, reinterpret_cast<UINT_PTR>(ID), reinterpret_cast<DWORD_PTR>(this));
C.Dispose();
return *this;
}
void Control::SetGlobalSubClass(SUBCLASSPROC Procedure)
{
if (Control::GlobalSubClass == nullptr && Procedure != nullptr)
{
Control::GlobalSubClass = Procedure;
}
}
void Control::SetEvent(std::size_t Index, std::function<void(HWND, UINT, WPARAM, LPARAM)> Func)
{
if (Index < this->Functions.size() && Func != nullptr)
{
this->Functions[Index] = Func;
}
}
void Control::ProcessEvent(std::size_t Index, HWND Hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Index < this->Functions.size() && this->Functions[Index] != nullptr)
{
this->Functions[Index](Hwnd, Msg, wParam, lParam);
}
}
LRESULT __stdcall Control::SubClass(HWND Window, UINT Msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
//GET DYNAMIC ID.. GetWindowLong(HWnd, GWL_ID);
//GET CLASS NAME.. GetClassName(HWnd, out LPSTR, MaxCount);
//Control* Instance = reinterpret_cast<Control*>(dwRefData);
switch(Msg)
{
case WM_NCDESTROY:
{
RemoveWindowSubclass(Window, GlobalSubClass ? GlobalSubClass : SubClass, uIdSubclass);
return DefSubclassProc(Window, Msg, wParam, lParam);
}
default:
return DefSubclassProc(Window, Msg, wParam, lParam);
}
return 0;
}
Button::~Button() {}
Button::Button() : Control() {};
Button::Button(Button&& B) : Control(std::forward<Button&&>(B)) {}
Button::Button(std::string Title, POINT Location, int Width, int Height, HWND Parent) : Control(0, "Button", Title, WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, Location, Width, Height, Parent, nullptr, nullptr) {}
Button& Button::operator = (Button && B)
{
Control::operator = (std::forward<Button&&>(B));
return *this;
}
Label::~Label() {}
Label::Label() : Control() {};
Label::Label(Label&& L) : Control(std::forward<Label&&>(L)) {}
Label::Label(std::string Title, POINT Location, int Width, int Height, HWND Parent) : Control(0, "Static", Title, WS_CHILD | WS_VISIBLE, Location, Width, Height, Parent, nullptr, nullptr) {}
Label& Label::operator = (Label&& L)
{
Control::operator = (std::forward<Label&&>(L));
return *this;
}
CheckBox::~CheckBox() {}
CheckBox::CheckBox() : Control() {};
CheckBox::CheckBox(CheckBox&& C) : Control(std::forward<CheckBox&&>(C)) {}
CheckBox::CheckBox(std::string Title, POINT Location, int Width, int Height, HWND Parent, bool Checked) : Control(0, "Button", Title, WS_CHILD | BS_AUTOCHECKBOX | WS_VISIBLE, Location, Width, Height, Parent, nullptr, nullptr)
{
if (Checked)
{
CheckDlgButton(Control::GetHandle(), reinterpret_cast<std::size_t>(Control::GetID()), BST_CHECKED);
}
}
bool CheckBox::IsChecked()
{
return IsDlgButtonChecked(Control::GetHandle(), reinterpret_cast<std::size_t>(Control::GetID()));
}
void CheckBox::SetChecked(bool Checked)
{
CheckDlgButton(Control::GetHandle(), reinterpret_cast<std::size_t>(Control::GetID()), Checked ? BST_CHECKED : BST_UNCHECKED);
}
CheckBox& CheckBox::operator = (CheckBox && C)
{
Control::operator = (std::forward<CheckBox&&>(C));
return *this;
}
TextBox::~TextBox() {}
TextBox::TextBox() : Control() {};
TextBox::TextBox(TextBox && T) : Control(std::forward<TextBox&&>(T)) {}
TextBox::TextBox(std::string Text, POINT Location, int Width, int Height, HWND Parent, bool MultiLine) : Control(WS_EX_STATICEDGE, "Edit", Text, WS_CHILD | WS_VISIBLE | (MultiLine ? ES_MULTILINE | ES_AUTOVSCROLL : 0), Location, Width, Height, Parent, nullptr, nullptr) {}
void TextBox::SetReadOnly(bool ReadOnly)
{
SendMessage(Control::GetHandle(), EM_SETREADONLY, ReadOnly, 0);
}
void TextBox::SetPassword(bool Enabled, char PasswordChar)
{
SendMessage(Control::GetHandle(), EM_SETPASSWORDCHAR, Enabled ? PasswordChar : 0, 0);
}
std::uint32_t TextBox::GetTextLength() const
{
return GetWindowTextLength(Control::GetHandle());
}
void TextBox::ShowScrollBar(bool Show, int wBar)
{
::ShowScrollBar(Control::GetHandle(), wBar, true);
}
void TextBox::AppendText(const std::string &Text) const
{
SendMessage(Control::GetHandle(), EM_SETSEL, -1, -1);
SendMessage(Control::GetHandle(), EM_REPLACESEL, 0, reinterpret_cast<LPARAM>(Text.c_str()));
}
TextBox& TextBox::operator = (TextBox && T)
{
Control::operator = (std::forward<TextBox&&>(T));
return *this;
}
ListBox::~ListBox() {}
ListBox::ListBox() : Control() {};
ListBox::ListBox(ListBox && L) : Control(std::forward<ListBox&&>(L)) {}
ListBox::ListBox(POINT Location, int Width, int Height, HWND Parent) : Control(WS_EX_CLIENTEDGE, "Listbox", std::string(), WS_CHILD | WS_VISIBLE | LBS_NOTIFY, Location, Width, Height, Parent, nullptr, nullptr) {}
int ListBox::GetItemCount() const
{
return SendMessage(Control::GetHandle(), LB_GETCOUNT, 0, 0);
}
int ListBox::GetSelectedIndex() const
{
return SendMessage(Control::GetHandle(), LB_GETCURSEL, 0, 0);
}
void ListBox::SetSelectedIndex(int Index)
{
SendMessage(Control::GetHandle(), LB_SETCURSEL, Index, 0);
}
void ListBox::AddItem(const std::string &Item, int Index)
{
SendMessage(Control::GetHandle(), Index == 0 ? LB_ADDSTRING : LB_INSERTSTRING, Index, reinterpret_cast<LPARAM>(Item.c_str()));
}
void ListBox::RemoveItem(int Index)
{
SendMessage(Control::GetHandle(), LB_DELETESTRING, Index, 0);
}
void ListBox::Clear()
{
SendMessage(Control::GetHandle(), LB_RESETCONTENT, 0, 0);
}
int ListBox::GetIndexOf(const std::string &Item)
{
return SendMessage(Control::GetHandle(), LB_FINDSTRINGEXACT, -1, reinterpret_cast<LPARAM>(Item.c_str()));
}
int ListBox::GetIndexPartial(const std::string &Item)
{
return SendMessage(Control::GetHandle(), LB_FINDSTRING, -1, reinterpret_cast<LPARAM>(Item.c_str()));
}
void ListBox::SetColumnWidth(int Width)
{
SendMessage(Control::GetHandle(), LB_SETCOLUMNWIDTH, Width, 0);
}
std::string ListBox::GetItem(int Index) const
{
std::vector<char> Buffer(SendMessage(Control::GetHandle(), LB_GETTEXTLEN, Index, 0) + 1);
SendMessage(Control::GetHandle(), LB_GETTEXT, Index, reinterpret_cast<LPARAM>(Buffer.data()));
return std::string(Buffer.begin(), Buffer.end());
}
ListBox& ListBox::operator = (ListBox && L)
{
Control::operator = (std::forward<ListBox&&>(L));
return *this;
}
ComboBox::~ComboBox() {}
ComboBox::ComboBox() : Control() {};
ComboBox::ComboBox(ComboBox && L) : Control(std::forward<ComboBox&&>(L)) {}
ComboBox::ComboBox(DropDownStyle Style, POINT Location, int Width, int Height, HWND Parent) : Control(WS_EX_CLIENTEDGE, "ComboBox", std::string(), (Style == DropDownStyle::STYLE_SIMPLE ? CBS_SIMPLE : Style == DropDownStyle::STYLE_DROPDOWN ? CBS_DROPDOWN : CBS_DROPDOWNLIST) | WS_CHILD | WS_VISIBLE, Location, Width, Height, Parent, nullptr, nullptr) {}
int ComboBox::GetItemCount() const
{
return SendMessage(Control::GetHandle(), CB_GETCOUNT, 0, 0);
}
int ComboBox::GetSelectedIndex() const
{
return SendMessage(Control::GetHandle(), CB_GETCURSEL, 0, 0);
}
void ComboBox::SetSelectedIndex(int Index)
{
SendMessage(Control::GetHandle(), CB_SETCURSEL, Index, 0);
}
void ComboBox::AddItem(const std::string &Item, int Index)
{
SendMessage(Control::GetHandle(), Index == 0 ? CB_ADDSTRING : CB_INSERTSTRING, Index, reinterpret_cast<LPARAM>(Item.c_str()));
}
void ComboBox::RemoveItem(int Index)
{
SendMessage(Control::GetHandle(), CB_DELETESTRING, Index, 0);
}
void ComboBox::Clear()
{
SendMessage(Control::GetHandle(), CB_RESETCONTENT, 0, 0);
}
int ComboBox::GetIndexOf(const std::string &Item)
{
return SendMessage(Control::GetHandle(), CB_FINDSTRINGEXACT, -1, reinterpret_cast<LPARAM>(Item.c_str()));
}
int ComboBox::GetIndexPartial(const std::string &Item)
{
return SendMessage(Control::GetHandle(), CB_FINDSTRING, -1, reinterpret_cast<LPARAM>(Item.c_str()));
}
void ComboBox::SetDropDownWidth(int Width)
{
SendMessage(Control::GetHandle(), CB_SETDROPPEDWIDTH, Width, 0);
}
void ComboBox::SetDropDownStyle(DropDownStyle Style)
{
Control::SetStyle(CBS_SIMPLE | CBS_DROPDOWN | CBS_DROPDOWNLIST, true);
Control::SetStyle(Style == DropDownStyle::STYLE_SIMPLE ? CBS_SIMPLE : Style == DropDownStyle::STYLE_DROPDOWN ? CBS_DROPDOWN : CBS_DROPDOWNLIST);
}
std::string ComboBox::GetItem(int Index) const
{
std::vector<char> Buffer(SendMessage(Control::GetHandle(), CB_GETLBTEXTLEN, Index, 0) + 1);
SendMessage(Control::GetHandle(), CB_GETLBTEXT, Index, reinterpret_cast<LPARAM>(Buffer.data()));
return std::string(Buffer.begin(), Buffer.end());
}
ComboBox& ComboBox::operator = (ComboBox && C)
{
Control::operator = (std::forward<ComboBox&&>(C));
return *this;
}
PictureBox::~PictureBox() {}
PictureBox::PictureBox() : Control() {};
PictureBox::PictureBox(PictureBox && P) : Control(std::forward<PictureBox&&>(P)) {}
PictureBox::PictureBox(POINT Location, int Width, int Height, HWND Parent) : Control(WS_EX_CLIENTEDGE, "Static", std::string(), WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE | SS_BITMAP, Location, Width, Height, Parent, nullptr, nullptr) {}
void PictureBox::SetImage(HBITMAP Img)
{
SendMessage(Control::GetHandle(), STM_SETIMAGE, IMAGE_BITMAP, reinterpret_cast<LPARAM>(Img));
}
PictureBox& PictureBox::operator = (PictureBox && P)
{
Control::operator = (std::forward<PictureBox&&>(P));
return *this;
}
MenuBar::~MenuBar() {}
MenuBar::MenuBar() : Control(), Menus() {};
MenuBar::MenuBar(MenuBar&& M) : Control(std::forward<MenuBar&&>(M)), Menus(std::move(M.Menus)) {}
MenuBar::MenuBar(HWND Parent) : Control(), Menus()
{
Control::Initialized = false;
this->SetParentHandle(Parent);
Menus.push_back(CreateMenu());
}
std::string MenuBar::GetText(HMENU Menu, int Position)
{
TCHAR Buffer[1024] = {0};
MENUITEMINFO MenuInfo = {0};
MenuInfo.cbSize = sizeof(MenuInfo);
MenuInfo.fMask = MIIM_TYPE;
MenuInfo.fType = MFT_STRING;
MenuInfo.cch = sizeof(Buffer);
MenuInfo.dwTypeData = Buffer;
if (GetMenuItemInfo(Menu, Position, true, &MenuInfo))
{
return Buffer;
}
return std::string();
}
std::uint32_t MenuBar::GetMenuItemID(HMENU Menu, int Position)
{
return ::GetMenuItemID(Menu, Position);
}
HMENU MenuBar::FindMenuItem(std::string MenuName)
{
for (std::size_t I = 0; I < Menus.size(); ++I)
{
if (MenuName == GetText(Menus.front(), I))
{
return GetSubMenu(Menus.front(), I);
}
}
return nullptr;
}
HMENU MenuBar::FindMenuItem(HMENU Parent, std::string MenuName)
{
std::size_t Count = GetMenuItemCount(Parent);
for (std::size_t I = 0; I < Count; ++I)
{
if (MenuName == GetText(Parent, I))
{
return GetSubMenu(Parent, I);
}
}
return nullptr;
}
void MenuBar::CreateSubMenu(HMENU Parent, std::string Name, DWORD Style)
{
Menus.push_back(CreatePopupMenu());
AppendMenu(Parent, Style, reinterpret_cast<UINT_PTR>(Menus.back()), Name.c_str());
}
void MenuBar::AddMenuItem(std::string Name, DWORD Style)
{
Menus.push_back(CreateMenu());
MENUINFO MenuInfo = {0};
MenuInfo.cbSize = sizeof(MenuInfo);
MenuInfo.fMask = MIM_STYLE;
GetMenuInfo(Menus.back(), &MenuInfo);
MenuInfo.dwStyle |= MNS_NOTIFYBYPOS;
SetMenuInfo(Menus.back(), &MenuInfo);
AppendMenu(Menus.front(), Style, reinterpret_cast<UINT_PTR>(Menus.back()), Name.c_str());
}
void MenuBar::AppendMenuItem(HMENU Parent, std::string Name, DWORD Style)
{
static int ID = 0;
AppendMenu(Parent, Style, ++ID, Name.c_str());
}
bool MenuBar::ToggleItemCheck(HMENU MenuItem, int Position)
{
MENUITEMINFO MenuInfo = {0};
MenuInfo.cbSize = sizeof(MenuInfo);
MenuInfo.fMask = MIIM_STATE;
GetMenuItemInfo(MenuItem, Position, true, &MenuInfo);
MenuInfo.fState = (MenuInfo.fState & MF_CHECKED ? MenuInfo.fState & ~MF_CHECKED : MenuInfo.fState | MF_CHECKED);
SetMenuItemInfo(MenuItem, Position, true, &MenuInfo);
return MenuInfo.fState & MF_CHECKED;
}
bool MenuBar::IsItemChecked(HMENU MenuItem, int Position)
{
MENUITEMINFO MenuInfo = {0};
MenuInfo.cbSize = sizeof(MenuInfo);
MenuInfo.fMask = MIIM_STATE;
GetMenuItemInfo(MenuItem, Position, true, &MenuInfo);
return MenuInfo.fState & MF_CHECKED;
}
void MenuBar::Show()
{
SetMenu(Control::GetParent(), Menus.front());
}
MenuBar& MenuBar::operator = (MenuBar && M)
{
Control::operator = (std::forward<MenuBar&&>(M));
return *this;
}
ToolBar::~ToolBar() {}
ToolBar::ToolBar() : Control() {};
ToolBar::ToolBar(ToolBar && T) : Control(std::forward<ToolBar&&>(T)) {}
ToolBar::ToolBar(POINT Location, int Width, int Height, HWND Parent) : Control(0, TOOLBARCLASSNAME, std::string(), WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | CCS_ADJUSTABLE | CCS_NODIVIDER, Location, Width, Height, Parent, nullptr, nullptr) {}
ToolBar& ToolBar::operator = (ToolBar && T)
{
Control::operator = (std::forward<ToolBar&&>(T));
return *this;
}