#define event(eventname, ... ) std::function<void(__VA_ARGS__ )> eventname
//form Class
const char formpropname[] = "propertyform";
const char formclassprop[] = "classform";
const int formHotkey_Message=0;
class form
{
private:
static int FormCount;
HCURSOR hCursor=(HCURSOR)LoadCursor(GetModuleHandle(NULL),IDC_APPSTARTING);
string strCaption="Form ";
string strCursor="";
color clrTextColor=0;
color clrBackColor=0;
bool blnTransparent=false;
bool blnAutoSize=false;
bool blnTabStop=true;
bool blnTextWrap=false;
int intTop=0;
int intLeft=0;
int intWidth=50;
int intHeight=20;
int intBorder=0;
char altkey=0;
const unsigned int altmessage=0;
int intMouseHover=HOVER_DEFAULT;
HWND hwnd;
bool blnVisible=true;
bool blnEnable=true;
int intTextAlignment=0;
static void TrackMouseForm(HWND hwnd, long HoverTime=HOVER_DEFAULT)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_HOVER | TME_LEAVE; //Type of events to track & trigger.
tme.dwHoverTime = HoverTime; //How long the mouse has to be in the window to trigger a hover event.
tme.hwndTrack = hwnd;
TrackMouseEvent(&tme);
}
static LRESULT CALLBACK WndProcForm(HWND HandleWindow, UINT msg, WPARAM wParam, LPARAM lParam)
{
static POINT PreviousLocation, Location;
static bool Tracking = false;
static MouseButtons MBButtons;
static bool blControl=false;
static bool blShift=false;
static bool blResize=false;
static int xPos=0;
static int yPos=0;
static UINT_PTR timerid;
static bool blnDrag=false;
form *inst=NULL;
HBRUSH g_hbrBackground = NULL;
//Working with messages
switch(msg)
{
case WM_NCCREATE:
{
CREATESTRUCT *p = (CREATESTRUCT *)lParam;
inst = (form *)p->lpCreateParams;
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)form);
inst->hwnd = hwnd;
if (inst==NULL)
inst = (form *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
}
break;
case WM_CREATE:
{
if(WindowMain==NULL)
WindowMain=HandleWindow;
inst->Create(inst->intLeft, inst->intTop);
}
break;
case WM_COMMAND:
{
return DefWindowProc(HandleWindow, msg, wParam, lParam);
}
break;
case WM_CTLCOLORBTN:
{
return (LRESULT)CreateSolidBrush(COLOR_3DDKSHADOW);
}
break;
case WM_PAINT:
{
/*if (inst->Paint==NULL) break;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(inst->hwnd, &ps);
inst->Paint(inst->hwnd,hdc);
EndPaint(inst->hwnd, &ps);*/
}
break;
case WM_NCHITTEST:
return DefWindowProc(HandleWindow, msg, wParam, lParam);
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_XBUTTONUP:
{
SetFocus(HandleWindow);
xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);
//inst->MouseUp(MBButtons, blControl, blShift, xPos, yPos);
if(MBButtons==Left && blnDrag==true)
{
//inst->Drop();
}
}
break;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_XBUTTONDOWN:
{
//SetFocus(inst->hwnd);
xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);
blControl = ((wParam & MK_CONTROL) == MK_CONTROL);
blShift = ((wParam & MK_SHIFT) == MK_SHIFT);
if(wParam & MK_LBUTTON)
MBButtons=Left;
else if (wParam & MK_RBUTTON)
MBButtons=Right;
else if (wParam & MK_MBUTTON)
MBButtons=Middle;
else if (wParam & MK_XBUTTON1)
MBButtons=X1;
else if (wParam & MK_XBUTTON2)
MBButtons=X2;
//inst->MouseDown(MBButtons, blControl, blShift, xPos, yPos);
}
break;
case WM_MOUSEMOVE:
{
KillTimer(HandleWindow,timerid);
PreviousLocation = Location;
GetCursorPos(&Location);
xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);
//inst->MouseMove(MBButtons, blControl, blShift, xPos, yPos);
if (!Tracking)
{
//TrackMouseForm(HandleWindow,(long)inst->intMouseHover);
Tracking = true;
//inst->MouseEnter();
}
if(blnDrag==false && MBButtons==Left)
{
//inst->Drag();
blnDrag=true;
}
SetTimer(HandleWindow,timerid,150,NULL);
}
break;
case WM_MOUSEHOVER:
{
//inst->MouseHover();
}
break;
case WM_MOUSELEAVE:
{
// KillTimer(inst->hwnd,timerid);
//inst->MouseLeave();
Tracking = false;
}
break;
case WM_MOVE:
{
blResize=false;
xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);
// inst->Move(xPos,yPos);
}
break;
case WM_TIMER:
{
if (wParam ==timerid)
{
PreviousLocation = Location;
GetCursorPos(&Location);
if ((Location.x = PreviousLocation.x) && (Location.y = PreviousLocation.y))
{
KillTimer(HandleWindow,timerid);
//inst->MouseStoped();
}
}
}
break;
case WM_SIZE:
{
//inst->Resize();
}
break;
case WM_SHOWWINDOW:
{
/*if(inst->blnVisible==true)
{
inst->Visible();
}
else
{
inst->Hide();
}*/
}
break;
case WM_KILLFOCUS:
{
//inst->KillFocus();
}
break;
case WM_SETFOCUS:
{
//inst->GetFocus();
}
break;
case WM_EXITSIZEMOVE:
{
xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);
if(blResize==true)
{
//inst->ResizeStoped();
}
else
{
//inst->Stoped(xPos,yPos);
}
}
break;
case WM_MOUSEWHEEL:
{
xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);
int zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
//inst->MouseWhell(zDelta,MBButtons, blControl, blShift, xPos, yPos);
}
break;
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
case WM_XBUTTONDBLCLK:
{
// SetFocus(inst->hwnd);
xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);
blControl = ((wParam & MK_CONTROL) == MK_CONTROL);
blShift = ((wParam & MK_SHIFT) == MK_SHIFT);
if((wParam & MK_LBUTTON)!= false)
MBButtons=Left;
else if (wParam & MK_RBUTTON)
MBButtons=Right;
else if (wParam & MK_MBUTTON)
MBButtons=Middle;
else if (wParam & MK_XBUTTON1)
MBButtons=X1;
else if (wParam & MK_XBUTTON2)
MBButtons=X2;
//inst->MouseDoubleClick(MBButtons, blControl, blShift, xPos, yPos);
}
break;
case WM_KEYDOWN:
{
//inst->KeyDown(wParam,lParam);
}
break;
case WM_KEYUP:
{
//inst->KeyUp(wParam,lParam);
}
break;
case WM_CLOSE:
DestroyWindow(HandleWindow);
break;
case WM_DESTROY:
--FormCount;
if(FormCount==0)
End();
break;
}
//If oldproc is NULL then use DefWindowProc - but shouldn't be!
return DefWindowProc(HandleWindow, msg, wParam, lParam);
}
public:
//the Control events:
static event(Create,(int x, int y));
event(Paint,(HWND hwndWindow, HDC hdcWindow))=NULL;
event(ResizeStoped)=[](){;};
event(Resize)=[](){;};
event(Stoped,(int x, int y))=[](int x, int y){;};
event(Move,(int x, int y))=[](int x, int y){;};
event(Visible)=[](){;};
event(Hide)=[](){;};
event(GetFocus)=[](){;};
event(KillFocus)=[](){;};
event(Destroy)=[](){;};
event(Drag)=[](){;};
event(Drop)=[](){;};
//The Mouse events:
event(MouseEnter)=[](){;};
event(MouseLeave)=[](){;};
event(MouseHover)=[](){;};
event(MouseDown,(MouseButtons Button,bool control, bool shift, int x, int y))=[](int Button, bool control, bool shift,int x, int y){;};
event(MouseUp,(MouseButtons Button,bool control, bool shift, int x, int y))=[](int Button, bool control, bool shift,int x, int y){;};
event(MouseMove,(MouseButtons Button,bool control, bool shift, int x, int y))=[](int Button, bool control, bool shift,int x, int y){;};
event(MouseStoped)=[](){;};
event(MouseWhell,(int Whell, MouseButtons Button,bool control, bool shift, int x, int y))=[](int Whell, int Button, bool alt, bool shift,int x, int y){;};
event(MouseClick)=[](){;};
event(MouseDoubleClick,(MouseButtons Button,bool control, bool shift, int x, int y))=[](int Button, bool control, bool shift,int x, int y){;};
//KeyBoard events:
event(KeyDown,(int Key,int repeat))=[](int Key,int repeat){;};
event(KeyUp,(int Key,int repeat))=[](int Key,int repeat){;};
~form()
{
--FormCount;
DestroyCursor(hCursor);
DestroyWindow(hwnd);
hwnd = 0;
}
void setTextAlignment(int textalignment)
{
intTextAlignment=textalignment;
LONG_PTR new_style=0;
if(textalignment==0)
new_style = SS_LEFTNOWORDWRAP;
else if( textalignment == 1 )
new_style = SS_CENTER;
else if(textalignment==2)
new_style =SS_RIGHT;
else if(textalignment==3)
new_style =SS_RIGHTJUST;
LONG_PTR s = GetWindowLongPtr( hwnd, GWL_STYLE );
s = ( s & ~( SS_LEFT | SS_CENTER | SS_RIGHT | SS_LEFTNOWORDWRAP ) ) | new_style;
SetWindowLongPtr( hwnd, GWL_STYLE, s );
SetWindowPos(hwnd, 0, 0, 0, 0, 0,
SWP_NOZORDER| SWP_NOSIZE | SWP_NOMOVE|SWP_NOACTIVATE |SWP_NOCOPYBITS | SWP_DRAWFRAME);
}
int getTextAlignment()
{
return intTextAlignment;
}
form( const form &forminstance)
{
setHeight(forminstance.intHeight);
//setLeft(forminstance.intLeft);
//setTop(forminstance.intTop);
setWidth(forminstance.intWidth);
setTextAlignment(forminstance.intTextAlignment);
setBorder(forminstance.intBorder);
intMouseHover=forminstance.intMouseHover;
setAutoSize(forminstance.blnAutoSize);
setEnable(forminstance.blnEnable);
setTabStop(forminstance.blnTabStop);
setTextWrap(forminstance.blnTextWrap);
setTransparent(forminstance.blnTransparent);
setVisible(forminstance.blnVisible);
setBackColor(forminstance.clrBackColor);
setTextColor(forminstance.clrTextColor);
strCaption=forminstance.strCaption;
hCursor=forminstance.hCursor;
SetClassLong(hwnd, // window handle
GCL_HCURSOR, // change cursor
(LONG) hCursor);
HFONT a=(HFONT)SendMessage(forminstance.hwnd, WM_GETFONT, 0, 0);
setFont(a);
}
void operator=( const form &forminstance)
{
setHeight(forminstance.intHeight);
//setLeft(forminstance.intLeft);
//setTop(forminstance.intTop);
setWidth(forminstance.intWidth);
setTextAlignment(forminstance.intTextAlignment);
setBorder(forminstance.intBorder);
intMouseHover=forminstance.intMouseHover;
setAutoSize(forminstance.blnAutoSize);
setEnable(forminstance.blnEnable);
setTabStop(forminstance.blnTabStop);
setTextWrap(forminstance.blnTextWrap);
setTransparent(forminstance.blnTransparent);
setVisible(forminstance.blnVisible);
setBackColor(forminstance.clrBackColor);
setTextColor(forminstance.clrTextColor);
strCaption=forminstance.strCaption;
hCursor=forminstance.hCursor;
SetClassLong(hwnd, // window handle
GCL_HCURSOR, // change cursor
(LONG) hCursor);
HFONT a=(HFONT)SendMessage(forminstance.hwnd, WM_GETFONT, 0, 0);
setFont(a);
}
form(std::function<void(int,int)> create=NULL)
{
++FormCount;
strCaption=strCaption + to_string(FormCount);
Create=create;
setParent(HWND_DESKTOP);
}
operator HWND()
{
return hwnd;
}
operator HDC()
{
return GetDC(hwnd);
}
HDC hdc()
{
return GetDC(hwnd);
}
HWND hWnd()
{
return hwnd;
}
void setParent(HWND parent=GetDesktopWindow())
{
WNDCLASSEX FormClass;
char classname[]="form";
HINSTANCE mod = (HINSTANCE)GetModuleHandle(NULL);
FormClass.cbSize = sizeof(WNDCLASSEX);
FormClass.style = 0;
FormClass.lpfnWndProc = WndProcForm;
FormClass.cbClsExtra = 0;
FormClass.cbWndExtra = 0;
FormClass.hInstance = mod;
FormClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
FormClass.hCursor = LoadCursor(NULL, IDC_ARROW);
FormClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
FormClass.lpszMenuName = NULL;
FormClass.lpszClassName = classname;
FormClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// register the new window class
RegisterClassEx(&FormClass);
hwnd = CreateWindowEx(WS_EX_TRANSPARENT , classname, strCaption.c_str(), WS_OVERLAPPEDWINDOW | WS_TABSTOP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, parent, NULL, mod, this);
if (hwnd == NULL)
MessageBox(NULL, "Can't create the control", "error", MB_OK);
ShowWindow(hwnd, SW_NORMAL);
UpdateWindow(hwnd);
clrBackColor= GetBkColor(GetDC(parent));
clrTextColor = GetTextColor(GetDC(parent));
RECT a;
GetClientRect(hwnd,&a);
intTop=a.top;
intLeft=a.left;
intWidth=a.right-a.left;
intHeight=a.bottom-a.top;
}
void setTextWrap(bool wrap)
{
if(wrap!=blnTextWrap)
{
blnTextWrap=wrap;
long s;
if(wrap==false)
{
s = GetWindowLongPtr(hwnd,GWL_STYLE);
s = s | (SS_LEFTNOWORDWRAP);
}
else
{
s = GetWindowLongPtr(hwnd,GWL_STYLE);
s = s & ~(SS_LEFTNOWORDWRAP);
}
SetWindowLongPtr(hwnd,GWL_STYLE,(LONG_PTR)s);
}
}
bool getTextWrap()
{
return blnTextWrap;
}
void setTabStop(bool tabstop)
{
if (blnTabStop!=tabstop)
{
blnTabStop=tabstop;
long s;
if (tabstop==false)
{
s = GetWindowLongPtr(hwnd,GWL_STYLE);
s = s & ~(WS_TABSTOP);
}
else
{
s = GetWindowLongPtr(hwnd,GWL_STYLE);
s = s | (WS_TABSTOP);
}
SetWindowLongPtr(hwnd,GWL_STYLE,(LONG_PTR)s);
}
}
bool getTabStop()
{
return blnTabStop;
}
void setMouseHover(int time)
{
intMouseHover=time;
}
int getMouseHover()
{
return intMouseHover;
}
void setMouseCursor()
{
hCursor = (HCURSOR)LoadCursor(NULL,IDC_ARROW);
SetClassLong(hwnd, // window handle
GCL_HCURSOR, // change cursor
(LONG) hCursor);
}
void setMouseCursor(long cursor)
{
hCursor = (HCURSOR)LoadCursor(NULL,(LPCSTR)cursor);
SetClassLong(hwnd, // window handle
GCL_HCURSOR, // change cursor
(LONG) hCursor);
}
HCURSOR getMouseCursor()
{
return hCursor;
}
void setMouseCursor(string cursor)
{
strCursor=cursor;
hCursor = (HCURSOR)LoadCursor((HINSTANCE)GetModuleHandle(NULL),(LPCSTR)cursor.c_str());
SetClassLong(hwnd, // window handle
GCL_HCURSOR, // change cursor
(LONG) hCursor);
}
int getTop()
{
return intTop;
}
void setTop(int top)
{
intTop=top;
SetWindowPos(hwnd, 0,intLeft , intTop, 0, 0,
SWP_NOZORDER| SWP_NOSIZE|SWP_NOACTIVATE|
SWP_DRAWFRAME | SWP_FRAMECHANGED|SWP_NOCOPYBITS);
}
void Focus()
{
SetFocus(hwnd);
}
int getLeft()
{
return intLeft;
}
void setLeft(int left)
{
intLeft=left;
SetWindowPos(hwnd, 0,intLeft , intTop, intWidth, intHeight,
SWP_NOZORDER| SWP_NOSIZE|SWP_NOACTIVATE|
SWP_DRAWFRAME | SWP_FRAMECHANGED|SWP_NOCOPYBITS);
}
int getWidth()
{
return intWidth;
}
void setWidth(int width)
{
if (blnAutoSize==false)
{
intWidth=width;
SetWindowPos(hwnd, 0,intLeft , intTop, intWidth, intHeight,
SWP_NOZORDER|SWP_NOACTIVATE|
SWP_DRAWFRAME | SWP_FRAMECHANGED|SWP_NOCOPYBITS);
}
}
int getHeight()
{
return intHeight;
}
void setHeight(int height)
{
if (blnAutoSize==false)
{
intHeight=height;
SetWindowPos(hwnd, 0,intLeft , intTop, intWidth, intHeight,
SWP_NOZORDER|SWP_NOACTIVATE|
SWP_DRAWFRAME | SWP_FRAMECHANGED|SWP_NOCOPYBITS);
}
}
bool getTransparent()
{
return blnTransparent;
}
void setTransparent(bool transparent)
{
blnTransparent = transparent;
InvalidateRect(hwnd,NULL,false);
}
bool getAutoSize()
{
return blnAutoSize;
}
HFONT getFont()
{
return (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
}
void setFont(HFONT font)
{
SendMessage(hwnd, WM_SETFONT,(WPARAM) font, true);
}
void setEnable(bool enable)
{
blnEnable=enable;
EnableWindow(hwnd,enable);
}
bool getEnable()
{
return blnEnable;
}
void setVisible(bool visible)
{
blnVisible=visible;
if (visible==true)
{
ShowWindow(hwnd,SW_SHOW);
}
else
{
ShowWindow(hwnd,SW_HIDE);
}
}
bool getVisible()
{
return blnVisible;
}
void setAutoSize(bool autosize)
{
blnAutoSize=autosize;
if (autosize==true)
{
//Getting the DC Font amd select it
HDC hdc = GetDC(hwnd);
HFONT hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
HFONT hOldFont = (HFONT)SelectObject(hdc, hFont);
//Getting the
RECT c = { 0, 0, 0, 0 };
//Getting the text rectangle from actual caption
char a[256];
GetWindowText(this->hwnd,a,256);
DrawText(hdc, a, strlen(a), &c, DT_CALCRECT | DT_EXPANDTABS);
//add 2 to the size
TEXTMETRIC v;
GetTextMetrics (hdc,&v);
c.right=c.right+(v.tmAveCharWidth / 2);
c.bottom=c.bottom+(v.tmAveCharWidth / 2);
//Clean the Font DC
ReleaseDC(hwnd,hdc);
DeleteFont(hOldFont);
DeleteFont(hFont);
//Getting the actual styles
LONG s=GetWindowLongPtr(hwnd,GWL_EXSTYLE);
LONG g=GetWindowLongPtr(hwnd,GWL_STYLE);
//change the rectangle size for borders
AdjustWindowRectEx (&c,g,FALSE,s );
//Update the control
if((intWidth!=c.right-intLeft) ||(intHeight!=c.bottom-intTop))
{
intWidth=c.right-intLeft;
intHeight=c.bottom-intTop;
SetWindowPos(hwnd, 0, 0, 0, c.right, c.bottom,
SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOCOPYBITS);
}
}
}
void setBorder(int border)
{
if (intBorder!=border)
{
long s=0;
if(border==0)
{
if (intBorder==1)
{
s = GetWindowLongPtr(hwnd,GWL_EXSTYLE);
s = s & ~(WS_EX_CLIENTEDGE);
SetWindowLongPtr(hwnd,GWL_EXSTYLE,(LONG_PTR)s);
}
else if (intBorder==2)
{
s = GetWindowLongPtr(hwnd,GWL_STYLE);
s = s & ~(WS_BORDER);
SetWindowLongPtr(hwnd,GWL_STYLE,(LONG_PTR)s);
}
else if(intBorder==3)
{
s = GetWindowLongPtr(hwnd,GWL_EXSTYLE);
s = s & ~(WS_EX_STATICEDGE);
SetWindowLongPtr(hwnd,GWL_EXSTYLE,(LONG_PTR)s);
}
}
else if(border==1)
{
s = GetWindowLongPtr(hwnd,GWL_EXSTYLE) | WS_EX_CLIENTEDGE;
SetWindowLongPtr(hwnd,GWL_EXSTYLE,(LONG_PTR)s);
}
else if(border==2)
{
s = GetWindowLongPtr(hwnd,GWL_STYLE) | WS_BORDER;
SetWindowLongPtr(hwnd,GWL_STYLE,(LONG_PTR)s);
}
else if(border==3)
{
s = GetWindowLongPtr(hwnd,GWL_EXSTYLE) | WS_EX_STATICEDGE;
SetWindowLongPtr(hwnd,GWL_EXSTYLE,(LONG_PTR)s);
}
intBorder=border;
//the SetWindowPos() is for update the control
SetWindowPos(hwnd, 0, 0, 0, 0, 0,
SWP_NOZORDER| SWP_NOSIZE | SWP_NOMOVE|SWP_NOACTIVATE |SWP_NOCOPYBITS | SWP_DRAWFRAME);
}
}
int getBorder()
{
return intBorder;
}
string getText()
{
return strCaption;
}
void setText(string text)
{
if (text!=strCaption)
{
char* chrText = (char*)text.c_str();
strCaption=text;
altkey=GettingAltKey(strCaption);
SetWindowText(hwnd, chrText);
if (blnAutoSize==true)
{
setAutoSize(true);
}
else
{
//SetWindowPos(hwnd, 0, 0, 0, 0, 0,
// SWP_NOZORDER| SWP_NOSIZE | SWP_NOMOVE|SWP_NOACTIVATE |SWP_NOCOPYBITS | SWP_DRAWFRAME);
InvalidateRect(hwnd,NULL,false);
}
SendMessage(hwnd, WM_UPDATEUISTATE, MAKEWPARAM(UIS_INITIALIZE, 0), 0);
}
}
color getBackColor()
{
return clrBackColor;
}
void setBackColor(color backcolor)
{
clrBackColor=backcolor;
InvalidateRect(hwnd,NULL,false);
}
color getTextColor()
{
return clrTextColor;
}
void setTextColor(color textcolor)
{
clrTextColor=textcolor;
InvalidateRect(hwnd,NULL,false);
}
void Disposed()
{
DestroyCursor(hCursor);
DestroyWindow(hwnd);
hwnd = 0;
}
};
int form::FormCount=0;
event(form::Create,(int x, int y))=[](int x, int y){;};