/**========================================================================== Copyright (C) 2018 Nick Currie, Copyleft. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ==========================================================================**/ #include #include /*============================================================================ Licensed under the MIT License . Copyright (c) 2013-2018 Niels Lohmann . See MIT license text in nlohmann_json.h ============================================================================*/ #include "src/json.h" //#include "src/json_old.h" //============================================================================ //============================================================================================================================================ // Pre-define headers. //============================================================================================================================================ LRESULT CALLBACK MainProc(HWND, UINT, WPARAM, LPARAM); //============================================================================================================================================ #define _NULL_RECT {0,0,0,0} //------------------------------------------- const long transparency = 0x000000; // use full black as the window transparency "colour". static const std::string emptystring = ""; static const std::string undefined = "Undefined"; static const std::string unknown = "Unknown"; //============================================================================================================================================ class WindowClass { HWND _hwnd = nullptr; HDC _hdc = nullptr; PAINTSTRUCT _ps; HDC _buffHDC = nullptr; HBITMAP _buffCCB; HBITMAP _buffBMP; union { uint32_t Clicks; POINT Click; }; public: // Variables WINDOWINFO info = {sizeof(WINDOWINFO), _NULL_RECT, _NULL_RECT, 0,0,0,0,0,0,0}; // Functions inline int32_t clickx(void) { return Click.x; } inline int32_t clicky(void) { return Click.y; } inline void click(uint32_t thisXY) {Click.x = int16_t(thisXY & 0xFFFF); Click.y = int16_t((thisXY >> 16) & 0xFFFF); } inline HWND hwnd() {return _hwnd;} inline void sethwnd(HWND hwnd) {_hwnd = hwnd;} inline HDC hdc() {return _hdc;} inline void getDC() {_hdc = GetDC(_hwnd);} inline void sethdc(HDC hdc) {_hdc = hdc;} inline void releaseDC() {ReleaseDC(_hwnd, _hdc); _hdc = nullptr;} inline void buffrect(RECT* thisRect) { Rectangle(_buffHDC, thisRect->left, thisRect->top, thisRect->right, thisRect->bottom); } inline void beginpaint() {_hdc = BeginPaint(_hwnd, &_ps);} inline void endpaint() {EndPaint(_hwnd, &_ps); ReleaseDC(_hwnd,_hdc); _hdc = nullptr;} inline void createcompatibledc() {_buffHDC = CreateCompatibleDC(_hdc);} // create the offscreen DC; inline HDC buffHDC() {return _buffHDC;} inline void createcompatiblebitmap() { _buffCCB = CreateCompatibleBitmap(_hdc, cwidth(), cheight()); } // create bitmap with the window DC;) inline void selectbitmap() {_buffBMP = (HBITMAP)SelectObject(_buffHDC, _buffCCB);} // put the bitmap in the DC inline void deleteCCB() {DeleteObject(_buffCCB);} inline void deletecompatibledc() {DeleteDC(_buffHDC);} inline void createbuffer() { _buffHDC = CreateCompatibleDC(_hdc); _buffCCB = CreateCompatibleBitmap(_hdc, wwidth(), wheight()); _buffBMP = (HBITMAP)SelectObject(_buffHDC, _buffCCB); } inline void bitblt() { BitBlt(_hdc, 0, 0, cwidth(), cheight(), _buffHDC, 0, 0, SRCCOPY); } inline void deletebuffer() { _buffBMP = (HBITMAP)SelectObject(_buffHDC, _buffCCB); DeleteObject(_buffCCB); DeleteDC(_buffHDC); } inline long cwidth() {return info.rcClient.right - info.rcClient.left;} inline long cheight() {return info.rcClient.bottom - info.rcClient.top;} inline long wwidth() {return info.rcWindow.right - info.rcWindow.left;} inline long wheight() {return info.rcWindow.bottom - info.rcWindow.top;} inline bool getwindowinfo() {return GetWindowInfo(_hwnd, &info);} inline void invalidateclientrect(bool xx = true) { GetClientRect(_hwnd, &info.rcClient); InvalidateRect(_hwnd, &info.rcClient, xx); } } Main; //============================================================================================================================================ // Inlines. //============================================================================================================================================ template inline std::string NumToStr(T number) { std::ostringstream ss; ss << number; return ss.str(); } //============================================================================================================================================ // Main Window Procedures. //============================================================================================================================================ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int32_t iCmdShow) { static TCHAR szAppName[] = TEXT("ThisProgram"); WNDCLASS wndclass = {CS_HREDRAW | CS_VREDRAW, MainProc, 0, 0, hInstance, LoadIcon(nullptr, IDI_APPLICATION), LoadCursor(nullptr, IDC_ARROW), (HBRUSH) CreateSolidBrush(transparency), nullptr, szAppName}; if (!RegisterClass(&wndclass)) { MessageBox(nullptr, TEXT("Program requires Windows NT or later!"), szAppName, MB_ICONERROR); return 0; } if (hPrevInstance != nullptr) { MessageBox(nullptr, TEXT("Odd previous instance behaviour detected"), szCmdLine, MB_ICONERROR); return 0; } Main.sethwnd(CreateWindowEx(WS_EX_LAYERED, szAppName, TEXT(szAppName), DS_3DLOOK | DS_MODALFRAME | WS_POPUP | WS_CLIPCHILDREN, 20, 20, 90, 90, nullptr, nullptr, hInstance, nullptr)); ShowWindow(Main.hwnd(), iCmdShow); UpdateWindow(Main.hwnd()); MSG msg = {}; while(GetMessage(&msg, nullptr, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } //============================================================================================================================================ LRESULT CALLBACK MainProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { Main.getwindowinfo(); switch(Message) { case WM_CREATE: { SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); SetLayeredWindowAttributes(hwnd, transparency, (255 * 100)/100, LWA_ALPHA | LWA_COLORKEY); } break; case WM_ERASEBKGND: { return(LRESULT)true; } break; case WM_LBUTTONDOWN: { SetCapture(hwnd); Main.click(lParam); } break; case WM_LBUTTONUP: { ReleaseCapture(); } break; case WM_MOUSEMOVE: { if (GetCapture() == hwnd) //Check if this window has mouse input { //Get the window's position. Main.getwindowinfo(); //Get the current mouse coordinates POINT Mouse; Mouse.x = int16_t(LOWORD(lParam)); Mouse.y = int16_t(HIWORD(lParam)); //Calculate the new window coordinates int32_t xWindow = Main.info.rcWindow.left + Mouse.x - Main.clickx(); int32_t yWindow = Main.info.rcWindow.top + Mouse.y - Main.clicky(); //Set the window's new screen position(don't resize or change z-order) SetWindowPos(hwnd, nullptr, xWindow, yWindow, 0, 0, SWP_NOSIZE|SWP_NOZORDER); } } break; case WM_PAINT: { SetWindowPos(hwnd, nullptr, 0, 0, 300, 300, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE); Main.getwindowinfo(); Main.beginpaint(); Main.createbuffer(); // <- create the offscreen DC SelectObject(Main.buffHDC(), GetStockObject(DC_PEN)); SelectObject(Main.buffHDC(), GetStockObject(DC_BRUSH)); // "Blank" buffered window with transparent colour. SetDCPenColor(Main.buffHDC(), transparency); SetDCBrushColor(Main.buffHDC(), transparency); Rectangle(Main.buffHDC(), 0, 0, 300, 300); // Draw surrounding border. SetDCPenColor(Main.buffHDC(), 0x00808080); SetDCBrushColor(Main.buffHDC(), 0x00808080); RoundRect(Main.buffHDC(), 0, 0, 300, 300, 60, 60); Main.bitblt(); // copy contents of buffered window to window. Main.deletebuffer(); // tidy up after buffering window draw. Main.endpaint(); } break; case WM_SIZE: { Main.invalidateclientrect(true); } break; case WM_SETFOCUS: { SetLayeredWindowAttributes(hwnd, transparency, 255, LWA_ALPHA | LWA_COLORKEY); Main.invalidateclientrect(); } break; case WM_SYSKEYDOWN: { if ((lParam && 0x1000000) && (wParam == 0x51)) // Alt-Q { PostMessage(Main.hwnd(), WM_CLOSE, 0, 0); } } break; case WM_KILLFOCUS: { SetLayeredWindowAttributes(hwnd, transparency, (255 * 0.5), LWA_ALPHA | LWA_COLORKEY); Main.invalidateclientrect(); } break; case WM_COMMAND: { } break; case WM_DESTROY: { PostQuitMessage(0); } break; case WM_CLOSE: { DestroyWindow(hwnd); } break; default: return true; } return DefWindowProc(hwnd, Message, wParam, lParam); } //============================================================================================================================================