2025-11-27 16:46:48 +09:00

253 lines
6.1 KiB
C++

// OXShdWnd.cpp : implementation file
//
#include "stdafx.h"
#include "OXShdWnd.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int m_giFirst = 5;
const int m_giSecond = 5;
/////////////////////////////////////////////////////////////////////////////
// COXShdWnd
COXShdWnd::COXShdWnd()
{
m_pCastingWindow = NULL;
}
COXShdWnd::~COXShdWnd()
{
}
BEGIN_MESSAGE_MAP(COXShdWnd, CWnd)
//{{AFX_MSG_MAP(COXShdWnd)
ON_WM_WINDOWPOSCHANGED()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COXShdWnd message handlers
//DEL void COXShdWnd::OnPaint()
//DEL {
//DEL CPaintDC dc(this); // device context for painting
//DEL
//DEL CRect rect;
//DEL GetWindowRect(rect);
//DEL
//DEL DrawShadow(dc.m_hDC, rect, NULL);
//DEL }
COLORREF COXShdWnd::DarkenColor(long lScale, COLORREF lColor)
{
long R = MulDiv(GetRValue(lColor), (255 - lScale), 255);
long G = MulDiv(GetGValue(lColor), (255 - lScale), 255);
long B = MulDiv(GetBValue(lColor), (255 - lScale), 255);
return RGB(R, G, B);
}
// Wrapper function for ::GetPixel(...) that facilitates the shadow buffering
COLORREF COXShdWnd::GetShadowPixel(HDC hDC, int iXPos, int iYPos, bool bUseSavedShadow)
{
if (bUseSavedShadow)
return 0; // we don't need this pixel
return ::GetPixel(hDC, iXPos, iYPos);
};
// Wrapper function for ::SetPixelV(...) that facilitates the shadow buffering
void COXShdWnd::SetShadowPixel(HDC hDC, int iXPos, int iYPos, COLORREF clr, bool bSaveShadow, bool bUseSavedShadow, OXSHADOWARRAY* pShadowArray, int& iIndex)
{
if (bUseSavedShadow)
::SetPixelV(hDC, iXPos, iYPos, pShadowArray->GetAt(iIndex++));
else
::SetPixelV(hDC, iXPos, iYPos, clr);
if (bSaveShadow)
pShadowArray->Add(clr);
// AddPixelToMap(iXPos, iYPos, clr);
};
// Draws a menu shadow for the given rectangle
void COXShdWnd::DrawShadow(HDC hDC, LPRECT lpRect, OXSHADOWARRAY* pShadowArray)
{
int iArrayIndex = 0;
bool bSaveShadow, bUseSavedShadow;
if (pShadowArray == NULL)
{
// We don't need to use the shadow array
bSaveShadow = false;
bUseSavedShadow = false;
}
else if (pShadowArray->GetSize() == 0)
{
// Save the shadow in the array
bSaveShadow = true;
bUseSavedShadow = false;
}
else
{
// Use the shadow from the array
bSaveShadow = false;
bUseSavedShadow = true;
}
CRect rectWindow(lpRect);
// Draw the shadow - get the pixels from the desktop, darken them
// and place them on the popup window
HDC hDesktopDC = ::GetWindowDC(::GetDesktopWindow());
// copy desktop to mem DC and work with that for Get/Set pixel (Vista bug)
CDC* pDC = CDC::FromHandle(hDesktopDC);
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(pDC, rectWindow.Width(), rectWindow.Height());
CBitmap *pOldBitmap = dcMem.SelectObject(&bitmap);
// working with a mem bitmap at 0,0 for GetPixel
dcMem.BitBlt(0,0, rectWindow.Width(), rectWindow.Height(), pDC, rectWindow.left, rectWindow.top, SRCCOPY);
int x, y;
CPoint pt;
COLORREF clr;
int iLeft = 4;
int iTop = 4;
int iRight = rectWindow.Width();
int iBottom = rectWindow.Height();
// Right shadow
for (x = 1; x <= 4; x++)
{
// Copy the top right pixels
for (y = 1; y <= 4; y++)
{
pt.x = iRight - x;
pt.y = iTop + y - 4 - 1;
clr = GetShadowPixel(dcMem.m_hDC, pt.x, pt.y, bUseSavedShadow);
SetShadowPixel(hDC, pt.x, pt.y, clr, bSaveShadow, bUseSavedShadow, pShadowArray, iArrayIndex);
}
// Top right corner
for (y = 4; y >= 1; y--)
{
pt.x = iRight - x;
pt.y = iTop + y - 1;
clr = GetShadowPixel(dcMem.m_hDC, pt.x, pt.y, bUseSavedShadow);
SetShadowPixel(hDC, pt.x, pt.y, DarkenColor(3 * x * y, clr), bSaveShadow, bUseSavedShadow, pShadowArray, iArrayIndex);
}
// Vertical line
for (y = iTop + 4; y <= iBottom - 4 - 1; y++)
{
pt.x = iRight - x;
pt.y = y;
clr = GetShadowPixel(dcMem.m_hDC, pt.x, pt.y, bUseSavedShadow);
SetShadowPixel(hDC, pt.x, pt.y, DarkenColor(15 * x, clr), bSaveShadow, bUseSavedShadow, pShadowArray, iArrayIndex);
}
// Bottom right corner
for (y = 1; y <= 4; y++)
{
pt.x = iRight - x;
pt.y = iBottom - y;
clr = GetShadowPixel(dcMem.m_hDC, pt.x, pt.y, bUseSavedShadow);
SetShadowPixel(hDC, pt.x, pt.y, DarkenColor(3 * x * y, clr), bSaveShadow, bUseSavedShadow, pShadowArray, iArrayIndex);
}
}
// Bottom shadow
for (y = 1; y <= 4; y++)
{
// Copy the bottom left pixels
for (x = 1; x <= 4; x++)
{
pt.x = iLeft - x;
pt.y = iBottom - y;
clr = GetShadowPixel(dcMem.m_hDC, pt.x, pt.y, bUseSavedShadow);
SetShadowPixel(hDC, pt.x, pt.y, clr, bSaveShadow, bUseSavedShadow, pShadowArray, iArrayIndex);
}
// Bottom left corner
for (x = 1; x <= 4; x++)
{
pt.x = iLeft - x + 4;
pt.y = iBottom - y;
clr = GetShadowPixel(dcMem.m_hDC, pt.x, pt.y, bUseSavedShadow);
SetShadowPixel(hDC, pt.x, pt.y, DarkenColor(3 * (5 - x) * y, clr), bSaveShadow, bUseSavedShadow, pShadowArray, iArrayIndex);
}
// Horizontal line
for (x = iLeft + 4; x <= iRight - 5; x++)
{
pt.x = x;
pt.y = iBottom - y;
clr = GetShadowPixel(dcMem.m_hDC, pt.x, pt.y, bUseSavedShadow);
SetShadowPixel(hDC, pt.x, pt.y, DarkenColor(15 * y, clr), bSaveShadow, bUseSavedShadow, pShadowArray, iArrayIndex);
}
}
// done with bitmap here
dcMem.SelectObject(pOldBitmap);
::ReleaseDC(0, hDesktopDC);
}
void COXShdWnd::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos)
{
CWnd::OnWindowPosChanged(lpwndpos);
// TODO: Add your message handler code here
//Invalidate();
}
BOOL COXShdWnd::OnEraseBkgnd(CDC* pDC)
{
// handle pending WM_PAINT messages
MSG msg;
while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
{
// if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
// return FALSE;
ASSERT(msg.message == WM_PAINT);
DispatchMessage(&msg);
}
CRect rect;
GetWindowRect(rect);
DrawShadow(pDC->m_hDC, rect, NULL);
// if (m_pCastingWindow != NULL)
// ::SetWindowPos(m_hWnd, m_pCastingWindow->m_hWnd, 0, 0, 0, 0,
// SWP_NOSENDCHANGING | SWP_NOMOVE | SWP_NOSIZE);
return FALSE;
}
void COXShdWnd::SetCastingWindow(CWnd* pWnd)
{
m_pCastingWindow = pWnd;
}