2 #define _USE_MATH_DEFINES
16 #define M_PI 3.14159265358979323846
24 typedef std::map<HWND, gui *> mgui_t;
25 typedef std::vector<gui *> children_t;
39 asyncReadComplete = WM_APP + 1,
41 tcpServerReadComplete,
61 bool set(
int id, HWND h)
70 std::cout <<
"App tried to show two modal windows\n";
71 SetFocus(myModalHandle);
101 SetFocus(myModalHandle);
120 : myfClickPropogate(
false), myfMouseTracking(
false)
127 draw([](PAINTSTRUCT &ps) {});
128 resize([](
int w,
int h) {});
129 scrollH([](
int c) {});
130 scrollV([](
int c) {});
134 mouseMove([](
sMouse &m) {});
135 mouseWheel([](
int dist) {});
137 timer([](
int id) {});
138 slid([](
int pos) {});
140 drop([](
const std::vector<std::string> &files) {});
142 tcpServerAccept([] {});
146 datePick([](
int id, LPNMDATETIMECHANGE date) {});
151 myClickFunctionApp();
152 return !myfClickPropogate;
156 myClickRightFunction();
164 myClickDoubleFunction();
166 void onDraw(PAINTSTRUCT &ps)
170 void onResize(
int w,
int h)
172 myResizeFunction(w, h);
174 void onScrollH(
int code)
176 myScrollHFunction(code);
178 void onScrollV(
int code)
180 myScrollVFunction(code);
182 void onMenuCommand(
int id)
184 if (0 >
id ||
id >= (
int)myVectorMenuFunction.size())
186 myVectorMenuFunction[id](myVectorMenuTitle[id]);
188 void onKeydown(
int keycode)
190 myKeydownFunction(keycode);
192 void onMouseMove(WPARAM wParam, LPARAM lParam)
195 m.x = LOWORD(lParam);
196 m.y = HIWORD(lParam);
199 m.left = (wParam == MK_LBUTTON);
200 m.shift = (wParam == MK_SHIFT);
202 myMouseMoveFunction(m);
206 myMouseEnterFunction();
208 void onMouseWheel(
int dist)
210 myMouseWheelFunction(dist);
214 myMouseLeaveFunction();
223 auto it = mapControlFunction().find(std::make_pair(
id, CBN_SELCHANGE));
224 if (it == mapControlFunction().end())
232 auto it = mapControlFunction().find(std::make_pair(
id, EN_CHANGE));
233 if (it == mapControlFunction().end())
238 void onSlid(
unsigned short id)
240 mySlidFunction((
int)
id);
242 void onDropStart(HDROP hDrop)
244 myDropStartFunction(hDrop);
246 void onDrop(
const std::vector<std::string> &files)
248 myDropFunction(files);
250 void onAsyncReadComplete(
int id)
252 myAsyncReadCompleteFunction(
id);
254 void onTcpServerAccept()
256 myTcpServerAcceptFunction();
258 void onTcpServerReadComplete()
260 myTcpServerReadCompleteFunction();
264 return myQuitAppFunction();
268 LPNMDATETIMECHANGE date)
270 myDatePickFunction(idFrom, date);
281 std::function<
void(
void)> f,
282 bool propogate =
false)
284 myClickFunctionApp = f;
285 myfClickPropogate = propogate;
302 myfClickPropogate = f;
305 void clickRight(std::function<
void(
void)> f)
307 myClickRightFunction = f;
310 void clickDouble(std::function<
void(
void)> f)
312 myClickDoubleFunction = f;
315 void draw(std::function<
void(PAINTSTRUCT &ps)> f)
319 void resize(std::function<
void(
int w,
int h)> f)
321 myResizeFunction = f;
323 void scrollH(std::function<
void(
int code)> f)
325 myScrollHFunction = f;
327 void scrollV(std::function<
void(
int code)> f)
329 myScrollVFunction = f;
337 std::function<
void(
const std::string &title)> f,
338 const std::string &title)
340 int id = (int)myVectorMenuFunction.size();
341 myVectorMenuFunction.push_back(f);
342 myVectorMenuTitle.push_back(title);
347 std::function<
void(
void)> f)
349 mapControlFunction().insert(
350 std::make_pair(std::make_pair(
id, CBN_SELCHANGE), f));
357 std::function<
void(
void)> f)
359 mapControlFunction().insert(
360 std::make_pair(std::make_pair(
id, EN_CHANGE), f));
365 myKeydownFunction = f;
367 void mouseEnter(std::function<
void(
void)> f)
369 myMouseEnterFunction = f;
371 void mouseMove(std::function<
void(sMouse &m)> f)
373 myMouseMoveFunction = f;
375 void mouseWheel(std::function<
void(
int dist)> f)
377 myMouseWheelFunction = f;
379 void mouseUp(std::function<
void(
void)> f)
381 myMouseUpFunction = f;
383 void mouseLeave(std::function<
void(
void)> f)
385 myMouseLeaveFunction = f;
387 void timer(std::function<
void(
int id)> f)
391 void slid(std::function<
void(
int pos)> f)
398 myDropStartFunction = f;
401 void drop(std::function<
void(
const std::vector<std::string> &files)> f)
410 myAsyncReadCompleteFunction = f;
412 void tcpServerAccept(std::function<
void(
void)> f)
414 myTcpServerAcceptFunction = f;
419 myTcpServerReadCompleteFunction = f;
426 myQuitAppFunction = f;
454 void datePick(std::function<
void(
int, LPNMDATETIMECHANGE)> f)
456 myDatePickFunction = f;
460 bool myfClickPropogate;
461 bool myfMouseTracking;
464 std::function<void(
void)> myClickFunctionApp;
465 std::function<void(
void)> myClickRightFunction;
466 std::function<void(
void)> myClickDoubleFunction;
467 std::function<void(PAINTSTRUCT &ps)> myDrawFunction;
468 std::function<void(
int w,
int h)> myResizeFunction;
469 std::function<void(
int code)> myScrollHFunction;
470 std::function<void(
int code)> myScrollVFunction;
471 std::vector<std::function<void(
const std::string &title)>> myVectorMenuFunction;
472 std::vector<std::string> myVectorMenuTitle;
473 std::function<void(
int keycode)> myKeydownFunction;
474 std::function<void(
sMouse &m)> myMouseMoveFunction;
475 std::function<void(
void)> myMouseEnterFunction;
476 std::function<void(
int dist)> myMouseWheelFunction;
477 std::function<void(
int id)> myTimerFunction;
478 std::function<void(
void)> myMouseUpFunction;
479 std::function<void(
void)> myMouseLeaveFunction;
480 std::function<void(
int pos)> mySlidFunction;
481 std::function<void(HDROP hDrop)> myDropStartFunction;
482 std::function<void(
const std::vector<std::string> &files)> myDropFunction;
483 std::function<void(
int id)> myAsyncReadCompleteFunction;
484 std::function<void(
void)> myTcpServerAcceptFunction;
485 std::function<void(
void)> myTcpServerReadCompleteFunction;
486 std::function<bool(
void)> myQuitAppFunction;
487 std::function<void(
int, LPNMDATETIMECHANGE)> myDatePickFunction;
490 std::function<void(
void)> myClickFunWex;
494 std::map<std::pair<int, unsigned short>, std::function<void(
void)>> &
497 static std::map<std::pair<int, unsigned short>, std::function<void(
void)>>
498 myMapControlFunction;
499 return myMapControlFunction;
535 : myHDC(ps.hdc), myPenThick(1), myFill(false)
541 hPenOld = SelectObject(myHDC, hPen);
545 ZeroMemory(&myLogfont,
sizeof(LOGFONT));
546 myLogfont.lfWeight = FW_NORMAL;
547 strcpy(myLogfont.lfFaceName,
"Tahoma");
548 myLogfont.lfHeight = 20;
549 hFont = CreateFontIndirect(&myLogfont);
550 hFont = (HFONT)SelectObject(myHDC, hFont);
555 HGDIOBJ pen = SelectObject(myHDC, hPenOld);
574 HGDIOBJ old = SelectObject(myHDC, hPen);
576 SetTextColor(myHDC, c);
577 HBRUSH brush = CreateSolidBrush(c);
578 old = SelectObject(myHDC, brush);
588 void bgcolor(
int r,
int g,
int b)
615 SetPixel(myHDC, x, y, myColor);
620 void line(
const std::vector<int> &v)
633 void polyLine(POINT *pp,
int n)
642 line({(int)p1.x, (
int)p1.y,
643 (int)p2.x, (
int)p2.y});
679 v[0], v[1], v[0] + v[2], v[1] + v[3]);
692 oldBrush = SelectObject(myHDC, GetStockObject(NULL_BRUSH));
693 Polygon(myHDC, (
const POINT *)&(v[0]), v.size() / 2);
695 SelectObject(myHDC, oldBrush);
697 void polygon(
const std::vector<cxy> v)
702 vi.push_back((
int)xy.x);
703 vi.push_back((
int)xy.y);
720 int x,
int y,
double r,
721 double sa,
double ea)
723 int xl = round(x - r);
724 int yt = round(y - r);
725 int xr = round(x + r);
726 int yb = round(y + r);
727 int xs = round(x + r * cos(sa * M_PI / 180));
728 int ys = round(y - r * sin(sa * M_PI / 180));
729 int xe = round(x + r * cos(ea * M_PI / 180));
730 int ye = round(y - r * sin(ea * M_PI / 180));
733 xl, yt, xr, yb, xs, ys, xe, ye);
745 oldBrush = SelectObject(myHDC, GetStockObject(NULL_BRUSH));
752 SelectObject(myHDC, oldBrush);
764 const std::string &t,
765 const std::vector<int> &v)
767 if (myLogfont.lfEscapement)
779 switch ((
int)v.size())
792 rect.right = v[0] + v[2];
793 rect.bottom = v[1] + v[3];
806 const std::string &t,
811 {(int)xy.x, (
int)xy.y});
814 const std::string &t,
816 const cxy &widthHeight)
820 {(int)topleft.x, (
int)topleft.y,
821 (int)widthHeight.x, (
int)widthHeight.y});
825 const cxy &widthHeight)
828 {(int)topleft.x, (
int)topleft.y,
829 (int)widthHeight.x, (
int)widthHeight.y});
833 const std::string &t,
834 const std::vector<int> &v)
836 int ws = textWidthPixels(t);
837 int pad = (v[2] - ws) / 2;
840 std::vector<int> vc = v;
850 myLogfont.lfEscapement = 2700;
852 myLogfont.lfEscapement = 0;
853 myLogfont.lfOrientation = myLogfont.lfEscapement;
854 HANDLE hFont = CreateFontIndirect(&myLogfont);
855 hFont = (HFONT)SelectObject(myHDC, hFont);
864 myLogfont.lfHeight = h;
865 HANDLE hFont = CreateFontIndirect(&myLogfont);
866 hFont = (HFONT)SelectObject(myHDC, hFont);
872 strcpy(myLogfont.lfFaceName, fn.c_str());
873 HANDLE hFont = CreateFontIndirect(&myLogfont);
874 hFont = (HFONT)SelectObject(myHDC, hFont);
877 int textWidthPixels(
const std::string &t)
880 GetTextExtentPoint32A(
908 : myParent(NULL), myBGColor(0xC8C8C8), myBGBrush(CreateSolidBrush(myBGColor)), myTextColor(0),
915 WS_OVERLAPPEDWINDOW, WS_EX_CONTROLPARENT,
923 events().resize([
this](
int w,
int h)
933 GetStockObject(DEFAULT_GUI_FONT),
934 sizeof(myLogFont), &myLogFont);
937 myLogFont.lfHeight = 18;
939 myFont = CreateFontIndirectA(&myLogFont);
949 const char *window_class =
"windex",
950 unsigned long style = WS_CHILD,
951 unsigned long exstyle = WS_EX_CONTROLPARENT) : myParent(parent),
955 myCursorID(IDC_ARROW)
961 Create(parent->
handle(), window_class, style, exstyle, myID);
967 text(
"???" + std::to_string(myID));
973 parent->
font(myLogFont, myFont);
985 DestroyWindow(myHandle);
987 myDeleteList->push_back(myHandle);
1028 DeleteObject(myBGBrush);
1029 myBGBrush = CreateSolidBrush(color);
1036 myfnobgerase =
true;
1045 bool isEnabled()
const
1053 myLogFont.lfHeight = h;
1057 void fontName(
const std::string &name)
1059 strcpy(myLogFont.lfFaceName, name.c_str());
1069 void icon(
const std::string &iconfilename)
1071 HICON hIcon = ExtractIconA(
1073 iconfilename.c_str(),
1080 SendMessage(myHandle, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
1081 SendMessage(myHandle, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
1082 SendMessage(GetWindow(myHandle, GW_OWNER), WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
1083 SendMessage(GetWindow(myHandle, GW_OWNER), WM_SETICON, ICON_BIG, (LPARAM)hIcon);
1085 void cursor(
char *cursorID)
1087 myCursorID = cursorID;
1105 void text(
const std::string &text)
1108 SetWindowText(myHandle, myText.c_str());
1111 std::string text()
const
1122 myfScrollHoriz = fHoriz;
1127 extra = WS_HSCROLL | WS_VSCROLL;
1133 GetWindowLongPtr(myHandle, GWL_STYLE) | extra);
1139 events().scrollH([
this](
int code)
1142 si.cbSize =
sizeof(si);
1143 si.fMask = SIF_POS | SIF_TRACKPOS | SIF_PAGE;
1144 if (!GetScrollInfo(myHandle, SB_HORZ, &si))
1147 int oldPos = scrollMove(si, code);
1150 SetScrollInfo(myHandle, SB_HORZ, &si, TRUE);
1151 GetScrollInfo(myHandle, SB_CTL, &si);
1154 GetClientRect(myHandle, &rect);
1155 int xs = oldPos - si.nPos;
1161 UpdateWindow( myHandle );
1167 events().scrollV([
this](
int code)
1170 si.cbSize =
sizeof(si);
1171 si.fMask = SIF_POS | SIF_TRACKPOS | SIF_PAGE;
1172 if (!GetScrollInfo(myHandle, SB_VERT, &si))
1175 int oldPos = scrollMove(si, code);
1178 SetScrollInfo(myHandle, SB_VERT, &si, TRUE);
1179 GetScrollInfo(myHandle, SB_VERT, &si);
1181 GetClientRect(myHandle, &rect);
1182 int ys = oldPos - si.nPos;
1222 GetClientRect(myHandle, &r);
1223 int xmax = width - r.right;
1226 int ymax = height - (r.bottom - r.top) + 60;
1230 si.cbSize =
sizeof(si);
1231 si.fMask = SIF_RANGE | SIF_PAGE;
1234 si.nPage = ymax / 10;
1235 SetScrollInfo(myHandle, SB_VERT, &si, TRUE);
1239 si.nPage = xmax / 10;
1240 SetScrollInfo(myHandle, SB_HORZ, &si, TRUE);
1252 if (!ScreenToClient(myHandle, &p))
1259 m.left = (GetKeyState(VK_LBUTTON) < 0);
1260 m.right = (GetKeyState(VK_RBUTTON) < 0);
1261 m.shift = (GetKeyState(VK_SHIFT) < 0);
1277 while (GetMessage(&msg, NULL, 0, 0))
1286 if (!IsDialogMessage(myHandle, &msg))
1288 TranslateMessage(&msg);
1289 DispatchMessage(&msg);
1298 void tooltip(
const std::string &text,
int width = 0)
1300 TOOLINFO toolInfo = {0};
1301 toolInfo.cbSize =
sizeof(toolInfo);
1302 toolInfo.hwnd = myHandle;
1303 toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
1304 toolInfo.uId = (UINT_PTR)myHandle;
1305 toolInfo.lpszText = (
char *)text.c_str();
1311 myToolTip = CreateWindowEx(0, TOOLTIPS_CLASS, NULL,
1312 WS_POPUP | TTS_ALWAYSTIP | TTS_BALLOON,
1313 CW_USEDEFAULT, CW_USEDEFAULT,
1314 CW_USEDEFAULT, CW_USEDEFAULT,
1315 myHandle, NULL, NULL, NULL);
1316 SendMessage(myToolTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
1322 SendMessage(myToolTip, TTM_UPDATETIPTEXT, 0, (LPARAM)&toolInfo);
1327 SendMessage(myToolTip, TTM_SETMAXTIPWIDTH, 0, width);
1330 bool isWindowMessageWaiting()
1337 PM_NOREMOVE | PM_NOYIELD);
1340 virtual LRESULT WindowMessageHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1344 if (hwnd == myHandle)
1360 if (!myEvents.onQuitApp())
1366 DestroyWindow(myHandle);
1396 GetWindowRect(hwnd, &rc);
1397 FillRect((HDC)wParam, &rc, myBGBrush);
1404 BeginPaint(myHandle, &ps);
1406 FillRect(ps.hdc, &ps.rcPaint, myBGBrush);
1409 EndPaint(myHandle, &ps);
1413 case WM_CTLCOLORSTATIC:
1418 GetBoundsRect(GetDC(myHandle), &r, 0);
1419 FillRect(GetDC(myHandle), &r, myBGBrush);
1420 SetBkMode((HDC)wParam, TRANSPARENT);
1422 return (INT_PTR)GetStockObject(NULL_BRUSH);
1427 NMHDR *pnmhdr =
reinterpret_cast<NMHDR *
>(lParam);
1428 if (pnmhdr->code == DTN_DATETIMECHANGE)
1430 myEvents.onDatePicked(
1432 (LPNMDATETIMECHANGE)(lParam));
1437 case WM_LBUTTONDOWN:
1441 if (myEvents.onLeftdown())
1446 if (myParent->WindowMessageHandler(
1448 uMsg, wParam, lParam))
1453 case WM_RBUTTONDOWN:
1454 myEvents.onRightDown();
1459 myEvents.onMouseUp();
1462 case WM_LBUTTONDBLCLK:
1463 std::cout <<
"WM_LBUTTONDBLCLK\n";
1464 myEvents.onDoubleClick();
1468 myEvents.onMouseMove(wParam, lParam);
1473 int d = HIWORD(wParam);
1476 myEvents.onMouseWheel(d);
1481 myEvents.onMouseLeave();
1485 myEvents.onResize(LOWORD(lParam), HIWORD(lParam));
1490 trackbarMessageHandler((HWND)lParam);
1492 myEvents.onScrollH(LOWORD(wParam));
1496 std::cout <<
"VSCROLL\n";
1498 trackbarMessageHandler((HWND)lParam);
1500 myEvents.onScrollV(LOWORD(wParam));
1507 auto wp_hi = HIWORD(wParam);
1510 events().onMenuCommand(wParam);
1514 if (wp_hi == CBN_SELCHANGE || wp_hi == LBN_SELCHANGE)
1516 return events().onSelect(LOWORD(wParam));
1519 if (wp_hi == EN_CHANGE)
1521 return events().onChange(LOWORD(wParam));
1527 events().onTimer((
int)wParam);
1531 events().onDropStart((HDROP)wParam);
1535 return DLGC_WANTARROWS;
1538 events().onKeydown((
int)wParam);
1544 SetCursor(LoadCursor(NULL, (LPCSTR)myCursorID));
1549 case eventMsgID::asyncReadComplete:
1550 events().onAsyncReadComplete(wParam);
1553 case eventMsgID::tcpServerAccept:
1554 events().onTcpServerAccept();
1557 case eventMsgID::tcpServerReadComplete:
1558 events().onTcpServerReadComplete();
1566 if (w->WindowMessageHandler(hwnd, uMsg, wParam, lParam))
1581 int cmd = SW_SHOWDEFAULT;
1585 ShowWindow(myHandle, cmd);
1617 while (GetMessage(&msg, NULL, 0, 0))
1619 if (!IsDialogMessage(myHandle, &msg))
1621 TranslateMessage(&msg);
1622 DispatchMessage(&msg);
1626 switch (msg.message)
1629 std::cout << myText <<
" WM_CLOSE";
1633 std::cout << myText <<
" WM_DESTROY";
1655 DestroyWindow(myHandle);
1657 myDeleteList->push_back(myHandle);
1670 InvalidateRect(myHandle, NULL,
true);
1671 UpdateWindow(myHandle);
1680 void move(
const std::vector<int> &r)
1684 MoveWindow(myHandle,
1685 r[0], r[1], r[2], r[3],
false);
1694 GetWindowRect(myHandle, &rect);
1695 MoveWindow(myHandle,
1696 rect.left, rect.top, w, h,
1706 GetClientRect(myHandle, &rect);
1707 MoveWindow(myHandle,
1708 x, y, rect.right - rect.left, rect.bottom - rect.top,
1711 void move(
int x,
int y,
int w,
int h)
1713 MoveWindow(myHandle,
1722 GetClientRect(myHandle, &r);
1723 std::vector<int> ret{
1724 r.right - r.left, r.bottom - r.top};
1727 std::vector<int> lefttop()
1730 GetWindowRect(myParent->
handle(), &rp);
1732 GetWindowRect(myHandle, &r);
1735 static std::vector<int> ret(2);
1736 ret[0] = r.left - rp.left;
1737 ret[1] = r.top - rp.top;
1756 myDeleteList =
list;
1762 myLogFont = logfont;
1770 w->setfont(myLogFont, myFont);
1772 void setAsyncReadCompleteMsgID(
int id)
1780 eventhandler myEvents;
1786 std::vector<HWND> *myDeleteList;
1796 bool myfScrollHoriz;
1807 const char *window_class,
1808 DWORD style, DWORD exstyle = 0,
1811 myHandle = CreateWindowEx(
1818 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
1821 reinterpret_cast<HMENU
>(
id),
1827 throw std::runtime_error(
1828 "Create Window failed");
1840 logfont = myLogFont;
1847 DeleteObject(myFont);
1848 myFont = CreateFontIndirectA(&myLogFont);
1851 virtual void draw(PAINTSTRUCT &ps)
1856 int color = 0x000000;
1864 SelectObject(ps.hdc, myFont);
1867 auto hbrBkgnd = CreateSolidBrush(myBGColor);
1872 DeleteObject(hbrBkgnd);
1882 myEvents.onDraw(ps);
1892 static int lastID = 0;
1896 int scrollMove(SCROLLINFO &si,
int code)
1898 int oldPos = si.nPos;
1913 si.nPos -= si.nPage;
1918 si.nPos += si.nPage;
1923 si.nPos = si.nTrackPos;
1930 void trackbarMessageHandler(HWND hwnd)
1932 std::cout <<
"trackbarMessageHandler\n";
1938 if (c->handle() == hwnd)
1944 (WPARAM)0, (LPARAM)0));
1999 DragAcceptFiles(myHandle,
true);
2002 myEvents.dropStart([
this](HDROP hDrop)
2004 int count = DragQueryFileA(hDrop, 0xFFFFFFFF, NULL, 0);
2008 std::vector<std::string> files;
2009 char fname[MAX_PATH];
2010 for (
int k = 0; k < count; k++)
2012 DragQueryFileA(hDrop, k, fname, MAX_PATH);
2013 files.push_back(fname);
2016 myEvents.onDrop(files);
2018 DragFinish(hDrop); });
2033 void move(
const std::vector<int> &r)
2041 myRect.right = r[0] + r[2];
2042 myRect.bottom = r[1] + r[3];
2045 MoveWindow(myHandle,
2046 r[0] + 5, r[1] + 2, 60, 25,
false);
2048 virtual void draw(PAINTSTRUCT &ps)
2051 HDC hdc = GetDC(myParent->handle());
2057 ReleaseDC(myParent->handle(), hdc);
2063 SelectObject(ps.hdc, myFont);
2081 :
panel(parent), myColCount(2), myfWidthsSpecified(
false), myfColFirst(
false)
2105 myfWidthsSpecified =
true;
2130 void draw(PAINTSTRUCT &ps)
2135 GetClientRect(myHandle, &r);
2136 if (!myfWidthsSpecified)
2139 int colwidth = (r.right - r.left) / myColCount;
2141 for (
int k = 0; k < myColCount; k++)
2143 myWidths.push_back(colwidth);
2150 int rowCount = (
myChild.size() + 1) / myColCount;
2153 rowheight = (r.bottom - r.top) / rowCount;
2167 w->move(x, rowcount * rowheight);
2170 x += myWidths[colcount];
2172 if (colcount >= myColCount)
2184 w->move(x, rowcount * rowheight);
2187 if (rowcount >= (
int)
myChild.size() / myColCount)
2190 x += myWidths[colcount];
2199 std::vector<int> myWidths;
2200 bool myfWidthsSpecified;
2209 :
gui(parent), myBitmap(NULL)
2211 myBGColor = 0xC8C8C8;
2219 myBitmap = (HBITMAP)LoadImage(
2220 NULL, name.c_str(), IMAGE_BITMAP,
2221 0, 0, LR_LOADFROMFILE);
2243 auto h = GetModuleHandleA(NULL);
2246 myBitmap = LoadBitmap(
2265 int color = 0x000000;
2275 SelectObject(ps.hdc, myFont);
2278 auto hbrBkgnd = CreateSolidBrush(myBGColor);
2283 DeleteObject(hbrBkgnd);
2292 DT_SINGLELINE | DT_CENTER | DT_VCENTER);
2304 HDC hLocalDC = CreateCompatibleDC(ps.hdc);
2306 GetObject(
reinterpret_cast<HGDIOBJ
>(myBitmap),
sizeof(BITMAP),
2307 reinterpret_cast<LPVOID
>(&qBitmap));
2308 HBITMAP hOldBmp = (HBITMAP)SelectObject(hLocalDC, myBitmap);
2310 ps.hdc, 0, 0, qBitmap.bmWidth, qBitmap.bmHeight,
2311 hLocalDC, 0, 0, SRCCOPY);
2312 SelectObject(hLocalDC, hOldBmp);
2390 :
gui(parent), myValue(
false)
2393 group().back().push_back(
this);
2394 myGroup = group().size() - 1;
2402 for (
auto b : group()[myGroup])
2424 auto this_it = std::find(
2425 group()[myGroup].begin(),
2426 group()[myGroup].end(),
2429 if (this_it == group()[myGroup].end())
2430 throw std::runtime_error(
"wex::radiobutton::first error in group");
2433 if (this_it == group()[myGroup].begin())
2437 std::vector<radiobutton *> g;
2438 group().push_back(g);
2443 it != group()[myGroup].end();
2446 group().back().push_back(*it);
2450 group()[myGroup].erase(
2452 group()[myGroup].end());
2455 for (
auto b : group().back())
2456 b->myGroup = group().size() - 1;
2479 for (
auto b : group()[myGroup])
2485 if (off < (
int)group()[myGroup].
size())
2496 for (
auto b : group()[myGroup])
2506 virtual void draw(PAINTSTRUCT &ps)
2508 SelectObject(ps.hdc, myFont);
2509 int color = 0x000000;
2530 S.circle(10, 10, 5);
2534 SelectObject(ps.hdc, GetStockObject(BLACK_BRUSH));
2535 Ellipse(ps.hdc, 5, 5, 15, 15);
2544 std::vector<std::vector<radiobutton *>> &group()
2546 static std::vector<std::vector<radiobutton *>> theGroups;
2547 static bool fGroupInit =
false;
2552 std::vector<radiobutton *> g;
2553 theGroups.push_back(g);
2575 :
gui(parent), myType(eType::check), myValue(
false)
2589 myType = eType::plus;
2591 myType = eType::check;
2593 void check(
bool f =
true)
2601 virtual void draw(PAINTSTRUCT &ps)
2607 int cbg = r.bottom - r.top - 10;
2612 S.textHeight(myLogFont.lfHeight);
2613 S.textFontName(myLogFont.lfFaceName);
2614 S.text(myText, {r.left, r.top, r.right, r.bottom});
2615 S.rectangle({0, 0, cbg, cbg});
2624 S.line({2, cbg / 2, cbg / 2 - 1, cbg - 2});
2625 S.line({cbg / 2, cbg - 3, cbg - 4, 3});
2629 S.line({2, cbg / 2, cbg - 2, cbg / 2});
2631 S.line({1 + cbg / 2, 2, 1 + cbg / 2, cbg - 2});
2636 void clickFunction(std::function<
void(
void)> f)
2638 myClickFunction = f;
2643 std::function<void(
void)> myClickFunction;
2652 const std::string &msg)
2662 const std::string &msg,
2663 const std::string &title,
2731 :
gui(parent,
"Edit",
2732 WS_CHILD | ES_LEFT | WS_BORDER | WS_VISIBLE,
2739 std::cout <<
"editbox notification " << ntf <<
"\n";
2740 if (ntf == EN_KILLFOCUS)
2742 std::cout <<
"done\n";
2745 void text(
const std::string &t)
2761 return std::string(buf);
2769 (WPARAM)f, (LPARAM)0);
2778 :
gui(parent,
"Edit",
2779 WS_CHILD | ES_LEFT | WS_BORDER | WS_VISIBLE | ES_MULTILINE | ES_WANTRETURN,
2803 return std::string(buf);
2811 :
gui(parent,
"Combobox",
2812 CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_OVERLAPPED | WS_VISIBLE)
2816 void move(
int x,
int y,
int w,
int h)
2828 (WPARAM)0, (LPARAM)20);
2839 void add(
const std::string &s)
2853 (WPARAM)0, (LPARAM)0);
2863 (WPARAM)i, (LPARAM)0);
2873 (WPARAM)-1, (LPARAM)s.c_str());
2881 (WPARAM)0, (LPARAM)0);
2888 return std::string(
"");
2900 return std::string(buf);
2908 (WPARAM)0, (LPARAM)0);
2928 :
gui(parent,
"listbox",
2929 LBS_NOTIFY | WS_VSCROLL | WS_BORDER |
2930 WS_CHILD | WS_OVERLAPPED | WS_VISIBLE)
2934 void move(
int x,
int y,
int w,
int h)
2939 (UINT)LB_SETCOLUMNWIDTH,
2944 void add(
const std::string &s)
2958 (WPARAM)0, (LPARAM)0);
2968 (WPARAM)i, (LPARAM)0);
2978 (WPARAM)i, (LPARAM)0);
2988 (WPARAM)-1, (LPARAM)s.c_str());
2998 (WPARAM)0, (LPARAM)0);
3006 return std::string(
"");
3013 return std::string(buf);
3021 (WPARAM)0, (LPARAM)0);
3045 static windex theInstance;
3054 static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
3059 if (uMsg == WM_GETDLGCODE)
3060 return w->second->WindowMessageHandler(hwnd, uMsg, wParam, lParam);
3062 if (w->second->WindowMessageHandler(hwnd, uMsg, wParam, lParam))
3067 return DefWindowProc(hwnd, uMsg, wParam, lParam);
3089 std::vector<HWND> myDeleteList;
3096 wc.lpfnWndProc = &windex::WindowProc;
3097 wc.hInstance = NULL;
3098 wc.lpszClassName =
"windex";
3099 wc.hbrBackground = CreateSolidBrush(0xc8c8c8);
3100 wc.style = CS_DBLCLKS;
3108 for (
auto h : myDeleteList)
3110 auto i =
myGui.find(h);
3111 if (i !=
myGui.end())
3114 myDeleteList.clear();
3153 : myM(CreatePopupMenu()), myParent(parent)
3171 const std::string &title,
3172 const std::function<
void(
const std::string &)> &f = [](
const std::string &title) {})
3177 myParent.events().menuCommand(f, title),
3186 const std::string &title,
3192 (UINT_PTR)submenu.handle(),
3195 void appendSeparator()
3230 unsigned int uCheck;
3232 uCheck = MF_BYPOSITION | MF_CHECKED;
3234 uCheck = MF_BYPOSITION | MF_UNCHECKED;
3235 return MF_CHECKED == CheckMenuItem(
3243 return GetMenuItemCount(myM);
3256 : myParent(parent), myM(CreateMenu())
3259 SetMenu(parent.
handle(), myM);
3266 const std::string &title,
3272 (UINT_PTR)m.handle(),
3274 DrawMenuBar(myParent.handle());
3305 : myGUI(g), myID(id)
3326 #include "widgets.h"
3344 template <
class W,
class P>
3404 :
panel(parent), myTabWidth(50)
3416 const std::string &tabname,
3421 GetClientRect(myHandle, &rect);
3422 panel.
move(0, 31, rect.right - rect.left, rect.bottom - rect.top - 30);
3424 button &btn = maker::make<button>(*
this);
3426 btn.
move(myButton.size() * myTabWidth,
3428 myButton.push_back(&btn);
3429 myPanel.push_back(&
panel);
3430 int tabIndex = myButton.size() - 1;
3434 myTabChangingFn(tabIndex);
3436 myTabChangeFn(tabIndex); });
3441 std::cout <<
"select " << i <<
"\n";
3443 if (0 > i || i >= (
int)myButton.size())
3446 for (
auto b : myButton)
3448 b->bgcolor(0xC8C8C8);
3451 for (
auto p : myPanel)
3454 myButton[i]->bgcolor(0xFFFFFF);
3475 myTabChangingFn = f;
3487 std::vector<button *> myButton;
3488 std::vector<gui *> myPanel;
3491 std::function<void(
int tabIndex)> myTabChangingFn;
3492 std::function<void(
int tabIndex)> myTabChangeFn;
3529 :
layout(parent), myFirst(
true)
3589 memset(&pdlg, 0,
sizeof(PRINTDLG));
3590 pdlg.lStructSize =
sizeof(PRINTDLG);
3592 pdlg.Flags = PD_RETURNDC;
3603 memset(&di, 0,
sizeof(DOCINFO));
3605 di.cbSize =
sizeof(DOCINFO);
3606 di.lpszDocName = title.c_str();
3637 const std::string &s)
3642 s.c_str(), s.length());
3658 const std::string &command,
3660 bool fBlock =
false)
3663 PROCESS_INFORMATION pi;
3665 ZeroMemory(&si,
sizeof(si));
3667 ZeroMemory(&pi,
sizeof(pi));
3670 si.wShowWindow = SW_SHOWNOACTIVATE | SW_MINIMIZE;
3671 si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USEPOSITION;
3675 if (!CreateProcessA(
3677 (LPSTR)command.c_str(),
3688 int syserrno = GetLastError();
3691 error =
"Cannot find executable file";
3696 FORMAT_MESSAGE_ALLOCATE_BUFFER |
3697 FORMAT_MESSAGE_FROM_SYSTEM |
3698 FORMAT_MESSAGE_IGNORE_INSERTS,
3701 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
3705 LocalFree(lpMsgBuf);
3709 WaitForSingleObject(pi.hProcess, 10000);
3712 CloseHandle(pi.hProcess);
3713 CloseHandle(pi.hThread);
2D point or vector
Definition: cxy.h:10
A widget that user can click to toggle a true/false value.
Definition: wex.h:2566
void plus(bool f=true)
set type to plus, useful to indicate expanded or collapsed property categories
Definition: wex.h:2586
A widget where user can choose from a dropdown list of strings.
Definition: wex.h:2808
void clear()
Clear all options.
Definition: wex.h:2848
std::string text(int i)
get text by index
Definition: wex.h:2892
int selectedIndex()
get index of selected item
Definition: wex.h:2876
void itemHeight(int h)
set item height in drop doown list
Definition: wex.h:2823
void add(const std::string &s)
Add an option.
Definition: wex.h:2839
void select(const std::string &s)
Select by string.
Definition: wex.h:2868
void select(int i)
Select by index.
Definition: wex.h:2858
void move(int x, int y, int w, int h)
Override move to ensure height is sufficient to allow dropdown to apprear.
Definition: wex.h:2816
int count()
get count of items
Definition: wex.h:2903
std::string selectedText()
get text of selected item
Definition: wex.h:2884
A widget where users can drop files dragged from windows explorer.
Definition: wex.h:1991
A widget where user can enter a single line string.
Definition: wex.h:2728
void readonly(bool f=true)
disable ( or enable ) user editing
Definition: wex.h:2764
void notification(WORD ntf)
editbox generated a notification - nop
Definition: wex.h:2737
std::string text()
get text in textbox
Definition: wex.h:2753
A class where application code can register functions to be called when an event occurs.
Definition: wex.h:117
void drop(std::function< void(const std::vector< std::string > &files)> f)
register function to call when files dropped by user have been extracted. App code use this!
Definition: wex.h:401
void clickWex(std::function< void(void)> f)
register a function to do some housekeeping when clicked, before calling handler registered by applic...
Definition: wex.h:295
void datePick(std::function< void(int, LPNMDATETIMECHANGE)> f)
Register function to call when a date is picked.
Definition: wex.h:454
void quitApp(std::function< bool(void)> f)
register function to call when application is about to quit The function should return true to allow ...
Definition: wex.h:424
void asyncReadComplete(std::function< void(int id)> f)
register function to call when an asynchronous read completes.
Definition: wex.h:408
void keydown(std::function< void(int keydown)> f)
register function to call when key pressed. Function is passed key code.
Definition: wex.h:363
void clickPropogate(bool f=true)
specify that click event should propogate to parent window after currently registered click event han...
Definition: wex.h:300
void dropStart(std::function< void(HDROP hDrop)> f)
register function to call when user drops files. App code should NOT call this!
Definition: wex.h:396
int menuCommand(std::function< void(const std::string &title)> f, const std::string &title)
Register function to run when menu item clicked.
Definition: wex.h:336
void tcpRead(std::function< void(void)> f)
register function to call when tcp read accurs
Definition: wex.h:417
void change(int id, std::function< void(void)> f)
register function to call when control changes
Definition: wex.h:355
void click(std::function< void(void)> f, bool propogate=false)
register click event handler
Definition: wex.h:280
Displaying a title and a box.
Definition: wex.h:2024
void move(const std::vector< int > &r)
Set size and location of group box.
Definition: wex.h:2033
The base class for all windex gui elements.
Definition: wex.h:900
void update()
force widget to redraw completely
Definition: wex.h:1668
void child(gui *w)
register child on this window
Definition: wex.h:991
unsigned int myAsyncReadCompleteMsgID
handle to tooltip control for this gui element
Definition: wex.h:1794
std::vector< int > size()
Size of window client area.
Definition: wex.h:1719
void tooltip(const std::string &text, int width=0)
Add tooltip that pops up helpfully when mouse cursor hovers over widget.
Definition: wex.h:1298
void showModal(gui &appWindow)
Show this window and suspend all other windows interactions until this is closed.
Definition: wex.h:1599
void scrollRange(int width, int height)
Set the scrolling range.
Definition: wex.h:1211
void Create(HWND parent, const char *window_class, DWORD style, DWORD exstyle=0, int id=0)
Create the managed window.
Definition: wex.h:1805
void endModal()
Stop modal interaction and close window.
Definition: wex.h:1651
eventhandler & events()
Get event handler.
Definition: wex.h:1742
void delete_list(std::vector< HWND > *list)
set delete list for when gui is detroyed
Definition: wex.h:1754
void move(const std::vector< int > &r)
Move the window.
Definition: wex.h:1680
void setfont(LOGFONT &logfont, HFONT &font)
change font for this and all child windows
Definition: wex.h:1760
void size(int w, int h)
Change size without moving top left corner.
Definition: wex.h:1691
void icon(const std::string &iconfilename)
Change icon.
Definition: wex.h:1069
void fontHeight(int h)
Change font height for this and all child windows.
Definition: wex.h:1051
gui * find(int id)
find child window with specified id
Definition: wex.h:1008
bool myfEnabled
true if not disabled
Definition: wex.h:1791
void createNewFont()
Replace font used by this and child windows from logfont.
Definition: wex.h:1845
gui(gui *parent, const char *window_class="windex", unsigned long style=WS_CHILD, unsigned long exstyle=WS_EX_CONTROLPARENT)
Construct child of a parent.
Definition: wex.h:947
std::vector< gui * > myChild
gui elements to be displayed in this window
Definition: wex.h:1789
HWND handle()
get window handle
Definition: wex.h:1748
void textColor(int c)
Set text color.
Definition: wex.h:1101
children_t & children()
get vector of children
Definition: wex.h:997
void enable(bool f=true)
Enable/Disable, default enable.
Definition: wex.h:1039
bool myfModal
true if element is being shown as modal
Definition: wex.h:1790
void move(int x, int y)
Change position without changing size.
Definition: wex.h:1703
sMouse getMouseStatus()
Get mouse status.
Definition: wex.h:1247
void bgcolor(int color)
Change background color.
Definition: wex.h:1025
virtual void show(bool f=true)
Show window and all children.
Definition: wex.h:1579
int NewID()
Create new, unique ID for gui element.
Definition: wex.h:1890
void run()
Run the windows message loop.
Definition: wex.h:1274
gui()
Construct top level window with no parent.
Definition: wex.h:907
void scroll(bool fHoriz=true)
Add scrollbars.
Definition: wex.h:1120
void font(LOGFONT &logfont, HFONT &font)
get font details
Definition: wex.h:1838
A widget that displays a string.
Definition: wex.h:2676
A panel which arranges the widgets it contains in a grid.
Definition: wex.h:2078
void grid(int cols)
Specify number of cols to use for layout.
Definition: wex.h:2095
void colWidths(const std::vector< int > &vw)
Specify column widths.
Definition: wex.h:2102
void colfirst(bool f=true)
Specify that widgets should be added to fill columns first.
Definition: wex.h:2126
A widget where user can choose from a list of strings.
Definition: wex.h:2925
std::string selectedText()
get text of selected item
Definition: wex.h:3002
void clear()
Clear all options.
Definition: wex.h:2953
void deleteItem(int i)
Delete by index.
Definition: wex.h:2973
void move(int x, int y, int w, int h)
Override move to ensure column width is sufficient.
Definition: wex.h:2934
int selectedIndex()
get index of selected item
Definition: wex.h:2993
void select(int i)
Select by index.
Definition: wex.h:2963
void add(const std::string &s)
Add an option.
Definition: wex.h:2944
void select(const std::string &s)
Select by string.
Definition: wex.h:2983
int count()
get count of items
Definition: wex.h:3016
A class for making windex objects.
Definition: wex.h:3338
static W & make(P &parent)
Construct widget.
Definition: wex.h:3345
static gui & make()
Construct a top level window ( first call constructs application window )
Definition: wex.h:3353
bool set(int id, HWND h)
Set modal running.
Definition: wex.h:61
bool canClose(int id)
Can a window be closed.
Definition: wex.h:87
static modalMgr & get()
get reference to singleton modal manager
Definition: wex.h:48
A popup with a message.
Definition: wex.h:2648
msgbox(const std::string &msg)
CTOR for simple message box with OK button.
Definition: wex.h:2651
int myReturn
Button id clicked by user.
Definition: wex.h:2671
msgbox(gui &parent, const std::string &msg, const std::string &title, unsigned int type)
CTOR for message box with title and configurable buttons.
Definition: wex.h:2660
A mutiline editbox.
Definition: wex.h:2775
std::string text()
get text in textbox
Definition: wex.h:2795
void text(const std::string &t)
Set text.
Definition: wex.h:2787
A child window that can contain widgets.
Definition: wex.h:1952
Print a text document.
Definition: wex.h:3578
~printDoc()
Finalize and send to printer.
Definition: wex.h:3611
printDoc(const std::string &title="printDoc")
CTOR.
Definition: wex.h:3583
void text(int x, int y, const std::string &s)
Add some text.
Definition: wex.h:3635
bool isOpen()
True if CTOR was successful.
Definition: wex.h:3617
A class that offers application code methods to draw on a window.
Definition: wex.h:529
void penThick(int t)
Set pen thickness in pixels.
Definition: wex.h:601
void textFontName(const std::string &fn)
set text font name
Definition: wex.h:870
void arc(int x, int y, double r, double sa, double ea)
Draw Arc of circle.
Definition: wex.h:719
void textHeight(int h)
Set text height.
Definition: wex.h:862
void text(const std::string &t, const std::vector< int > &v)
Draw text.
Definition: wex.h:763
void textVertical(bool f=true)
Enable / disable drawing text in vertical orientation Note: rotated text will NOT be clipped.
Definition: wex.h:847
void bgcolor(int c)
set background color
Definition: wex.h:582
void transparent(bool f=true)
enable/disable transparent background
Definition: wex.h:593
void line(const std::vector< int > &v)
Draw line between two points.
Definition: wex.h:620
void polygon(const std::vector< int > &v)
Draw Polygon.
Definition: wex.h:687
void circle(int x0, int y0, double r)
Draw circle.
Definition: wex.h:740
void fill(bool f=true)
Set filling option.
Definition: wex.h:608
shapes(PAINTSTRUCT &ps)
Constructor.
Definition: wex.h:534
void rectangle(const std::vector< int > &v)
Draw rectangle.
Definition: wex.h:648
void pixel(int x, int y)
Color a pixel.
Definition: wex.h:613
void color(int r, int g, int b)
Set color for drawings.
Definition: wex.h:563
A widget where user can select which panel to display by clicking a tab button.
Definition: wex.h:3401
void select(int i)
select panel to displayed
Definition: wex.h:3439
void tabChanging(std::function< void(int tabIndex)> f)
register function to call when tab is about to change This is only called when user changes the tab,...
Definition: wex.h:3473
void add(const std::string &tabname, gui &panel)
add panel that can be displayed
Definition: wex.h:3415
int select() const
zero-based index of panel currently selected
Definition: wex.h:3460
void tabChanged(std::function< void(int tabIndex)> f)
register function to call when tab has changed This is only called when user changes the tab,...
Definition: wex.h:3481
void tabWidth(int w)
set width of tab buttons
Definition: wex.h:3465
Generate events at regularly timed intervals.
Definition: wex.h:3292
timer(gui &g, int intervalmsecs, int id=1)
CTOR.
Definition: wex.h:3304
A class containing a database of the current gui elements.
Definition: wex.h:3033
gui * Add(gui *g)
Add new gui element.
Definition: wex.h:3071
static windex & get()
get reference to windex gui framework ( singleton )
Definition: wex.h:3043
mgui_t myGui
map of existing gui elements
Definition: wex.h:3087
static int startProcess(const std::string &command, std::string &error, bool fBlock=false)
Start a command in its own process.
Definition: wex.h:3657
A structure containing the mouse status for event handlers.
Definition: wex.h:29