#include struct Shadow : public Ctrl { void Paint(HDC hdc); virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { HWND hwnd = GetHWND(); if(message == WM_CREATE) SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_TRANSPARENT); if(message == WM_PAINT) { if(IsVisible() && hwnd) { PAINTSTRUCT ps; HDC dc = BeginPaint(hwnd, &ps); Paint(dc); EndPaint(hwnd, &ps); } return 0L; } return Ctrl::WindowProc(message, wParam, lParam); } }; struct SRGBA { byte r, g, b, a; }; struct DrawDirect { SRGBA *pixel; Point pos; Size size; HBITMAP hbmp, hbmOld; HDC hdc, dcMem; operator SRGBA*() { return pixel; } SRGBA *operator[](int i) { return pixel + size.cx * i; } DrawDirect(HDC hdc, int x, int y, int cx, int cy); ~DrawDirect(); }; DrawDirect::DrawDirect(HDC _hdc, int x, int y, int cx, int cy) { hdc = _hdc; pos = Point(x, y); size = Size(cx, cy); Buffer bibuffer(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256); BITMAPINFOHEADER *hi = (BITMAPINFOHEADER *) ~bibuffer;; BITMAPINFO *bi = (BITMAPINFO *)hi; memset(bi, 0, sizeof(BITMAPINFOHEADER)); hi->biSize = sizeof(BITMAPINFOHEADER); hi->biPlanes = 1; hi->biBitCount = 32; hi->biCompression = BI_RGB; hi->biSizeImage = 0; hi->biClrUsed = 0; hi->biClrImportant = 0; hi->biWidth = size.cx; hi->biHeight = size.cy; hbmp = CreateDIBSection(ScreenInfo().GetHandle(), bi, DIB_RGB_COLORS, (void **)&pixel, NULL, 0); dcMem = ::CreateCompatibleDC(hdc); hbmOld = (HBITMAP) ::SelectObject(dcMem, hbmp); ::BitBlt(dcMem, 0, 0, size.cx, size.cy, hdc, x, y, SRCCOPY); } DrawDirect::~DrawDirect() { ::BitBlt(hdc, pos.x, pos.y, size.cx, size.cy, dcMem, 0, 0, SRCCOPY); ::SelectObject(dcMem, hbmOld); ::DeleteDC(dcMem); ::DeleteObject(hbmp); } int CompShadow(int level) { return min(level * 50 + 70, 256); } inline void SetShadow(SRGBA *p, int black) { p->r = (black * p->r) >> 8; p->g = (black * p->g) >> 8; p->b = (black * p->b) >> 8; } void Shadow::Paint(HDC hdc) { Size size = GetSize(); if(size.cx > size.cy) { if(size.cx > 10) { DrawDirect dd(hdc, 0, 0, size.cx, 3); for(int y = 0; y < 3; y++) { SRGBA *p = dd[y]; for(int i = 0; i < 3; i++) SetShadow(p++, CompShadow(5 - i - y)); int b = CompShadow(3 - y); for(int i = size.cx - 6; i--;) SetShadow(p++, b); for(int i = 0; i < 3; i++) SetShadow(p++, CompShadow(3 + i - y)); } } } else { if(size.cy > 10) { DrawDirect dd(hdc, 0, 0, 3, size.cy); for(int x = 0; x < 3; x++) { SRGBA *p = dd.pixel + x; int b = CompShadow(x + 1); for(int i = size.cy - 3; i--;) { SetShadow(p, b); p += size.cx; } for(int i = 0; i < 3; i++) { SetShadow(p, CompShadow(i + x + 1)); p += size.cx; } } } } } GUI_APP_MAIN { Shadow w, w1; w.SetRect(808, 200, 95, 3); w.PopUp(); w1.SetRect(900, 108, 3, 92); w1.PopUp(); StaticRect test; test.SetFrame(BlackFrame()); test.SetRect(800, 100, 100, 100); test.PopUp(); TopWindow ww; ww.SetRect(400, 400, 100, 100); ww.OpenMain(); ww.Run(); }