⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menushadows.h

📁 这是一本学习 window编程的很好的参考教材
💻 H
字号:
#ifndef __DIALOGSHADOWS_H__
#define __DIALOGSHADOWS_H__

/////////////////////////////////////////////////////////////////////////////
// Menu shadows - an experimental menu shadow
//
// To use this class:
//   Derive from CDialogShadows.
//   Then place a MSG_MAP_CHAIN in the top of the dialog/window
//   message map.
//
// Written by Bjarke Viksoe (bjarke@viksoe.dk)
// Copyright (c) 2002 Bjarke Viksoe.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. 
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever. It's free, so don't hassle me about it.
//
// Beware of bugs.

#pragma once

#ifndef __cplusplus
   #error WTL requires C++ compilation (use a .cpp suffix)
#endif

#ifndef __ATLDIB_H__
  #error This control requires my atldib.h header to be included first
#endif


// From Platform SDK (Win2000 and above only)
#ifndef CS_DROPSHADOW
   #define CS_DROPSHADOW 0x00020000
#endif // CS_DROPSHADOW

// Size of the shadow (be carefull when changing)
#ifndef SHADOW_SIZE
   #define SHADOW_SIZE 5
#endif // SHADOW_SIZE


typedef CWinTraits<WS_VISIBLE|WS_OVERLAPPED|WS_POPUP, 0> CShadowWinTraits;

class CShadowWindow :
   public CWindowImpl< CShadowWindow, CWindow, CShadowWinTraits >
{
public:
   DECLARE_WND_CLASS(_T("WTL_MenuShadow"))

   CDib24 m_dib;

   BEGIN_MSG_MAP(CShadowWindow)
      MESSAGE_HANDLER(WM_PAINT, OnPaint)
   END_MSG_MAP()

   LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
   {
      if( wParam != 0 ) return 0; // No printing support
      CPaintDC dc(m_hWnd);
      ATLASSERT(!m_dib.IsEmpty());
      m_dib.Draw(dc, 0,0);
      return 0;
   }

   void CreateShadowBitmap(CDCHandle dc, const RECT& rcWin, bool bVertical)
   {
      if( !m_dib.IsEmpty() ) m_dib.DeleteObject();

      // Recalculate new shadow

      const int cxWin = rcWin.right - rcWin.left;
      const int cyWin = rcWin.bottom - rcWin.top;

      CWindowDC dcWin(HWND_DESKTOP);
      CDC dcMem;
      dcMem.CreateCompatibleDC(dcWin);
      CBitmap bmp;
      bmp.CreateCompatibleBitmap(dcWin, cxWin, cyWin);
      HBITMAP hOldBmp = dcMem.SelectBitmap(bmp);
      dcMem.BitBlt(0, 0, cxWin, cyWin, dcWin, rcWin.left, rcWin.top, SRCCOPY);
      dcMem.SelectBitmap(hOldBmp);

      m_dib.Create(bmp);

      DWORD nLine = m_dib.GetLineWidth();
      DWORD nPixel = m_dib.GetPixelWidth();

      if( bVertical ) {
         int x, y;

         LPBYTE pStream = m_dib.GetBits() + ((cyWin - SHADOW_SIZE) * nLine);
         for( x = 0; x < SHADOW_SIZE; x++ ) {
            LPBYTE p = pStream;
            for( y = 0; y < SHADOW_SIZE; y++ ) {
               //int iScale = 16 + ((8 - x*2) / (y+1));
               int iScale = 16 + (((SHADOW_SIZE - x) * 2) / (y + 1));
               *p++ = (BYTE) ((*p << 4) / iScale);
               *p++ = (BYTE) ((*p << 4) / iScale);
               *p++ = (BYTE) ((*p << 4) / iScale);
               p += nLine - 3;
            }
            pStream += nPixel;
         }

         pStream = m_dib.GetBits();
         for( x = 0; x < SHADOW_SIZE; x++ ) {
            LPBYTE p = pStream;
            int iScale = 16 + ((SHADOW_SIZE-x)*2);
            for( y = 0; y < cyWin - SHADOW_SIZE; y++ ) {
               *p++ = (BYTE) ((*p << 4) / iScale);
               *p++ = (BYTE) ((*p << 4) / iScale);
               *p++ = (BYTE) ((*p << 4) / iScale);
               p += nLine - 3;
            }
            pStream += nPixel;
         }
      }
      else {
         int x, y;

         LPBYTE pStream = m_dib.GetBits();
         for( y = 0; y < SHADOW_SIZE; y++ ) {
            LPBYTE p = pStream;
            for( int x = 0; x < SHADOW_SIZE; x++ ) {
               int iScale = 16 + (y*4 / (SHADOW_SIZE - x + 1));
               *p++ = (BYTE) ((*p << 4) / iScale);
               *p++ = (BYTE) ((*p << 4) / iScale);
               *p++ = (BYTE) ((*p << 4) / iScale);
            }
            pStream += nLine;
         }

         pStream = m_dib.GetBits() + (SHADOW_SIZE * nPixel);
         for( y = 0; y < SHADOW_SIZE; y++ ) {
            LPBYTE p = pStream;
            int iScale = 16 + y*2;
            for( x = 0; x < cxWin - (SHADOW_SIZE * 2) - 1; x++ ) {
               *p++ = (BYTE) ((*p << 4) / iScale);
               *p++ = (BYTE) ((*p << 4) / iScale);
               *p++ = (BYTE) ((*p << 4) / iScale);
            }
            pStream += nLine;
         }

         pStream = m_dib.GetBits() + ((cxWin - SHADOW_SIZE - 1) * nPixel);
         for( y = 0; y < SHADOW_SIZE; y++ ) {
            LPBYTE p = pStream;
            for( x = 0; x < SHADOW_SIZE; x++ ) {
               int iScale = 16 + ((y + 1) * 3 / (x + 3));
               *p++ = (BYTE) ((*p << 4) / iScale);
               *p++ = (BYTE) ((*p << 4) / iScale);
               *p++ = (BYTE) ((*p << 4) / iScale);
            }
            pStream += nLine;
         }
      }
   }
};

template< class T, class TWin=CShadowWindow >
class CDialogShadows
{
public:
   BEGIN_MSG_MAP(CDialogShadows)
      MESSAGE_HANDLER(WM_PAINT, OnPaint)
   END_MSG_MAP()

   LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
   {
      _CreateShadows();
      bHandled = FALSE;
      return 0;
   }

   // Implementation

   RECT _GetShadowRect(bool bVertical) const
   {
      const T* pT = static_cast<const T*>(this);
      RECT rc;
      pT->GetWindowRect(&rc);
      RECT rcWin;
      if( bVertical ) {
         ::SetRect(&rcWin, rc.right, rc.top + SHADOW_SIZE, rc.right + SHADOW_SIZE, rc.bottom);
      }
      else {
         ::SetRect(&rcWin, rc.left + SHADOW_SIZE, rc.bottom, rc.right + SHADOW_SIZE, rc.bottom + SHADOW_SIZE);
      }
      return rcWin;
   }

   void _CreateShadows()
   {
      T* pT = static_cast<T*>(this);

      // Test if it already has shadows enabled
      DWORD dwStyle = ::GetClassLong(pT->m_hWnd, GCL_STYLE);
      if( dwStyle & CS_DROPSHADOW ) return;

      RECT rc;
      pT->GetWindowRect(&rc);

      if( !m_wndRight.IsWindow() && !m_wndBottom.IsWindow() ) {
         // Create the shadow bitmaps
         CWindowDC dcDesktop(HWND_DESKTOP);
         // Create the 2 shadow windows (they are created as seperate windows).
         // We don't create them visible since this forces them to take focus...
         RECT rcWin;
         rcWin = _GetShadowRect(true);
         m_wndRight.CreateShadowBitmap( (HDC) dcDesktop, rcWin, true );
         m_wndRight.Create(pT->m_hWnd, 
            CWindow::rcDefault, 
            NULL, 
            WS_OVERLAPPED | WS_POPUP | WS_DISABLED,
            0);
         m_wndRight.SetWindowPos(pT->m_hWnd, &rcWin, SWP_NOACTIVATE | SWP_SHOWWINDOW);
         rcWin = _GetShadowRect(false);
         m_wndBottom.CreateShadowBitmap( (HDC) dcDesktop, rcWin, false );
         m_wndBottom.Create(pT->m_hWnd, 
            CWindow::rcDefault, 
            NULL, 
            WS_OVERLAPPED | WS_POPUP | WS_DISABLED,
            0);
         m_wndBottom.SetWindowPos(pT->m_hWnd, &rcWin, SWP_NOACTIVATE | SWP_SHOWWINDOW);
      }
   }

   TWin m_wndRight;
   TWin m_wndBottom;
};


#endif // !defined(__DIALOGSHADOWS_H__)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -