二、编程步骤
1、 启动Visual
C++6.0,生成一个Win32应用程序,将该程序命名为"transparent";
2、 使用Class
Wizard在应用程序中添加CMyWnd类,其基类选择CWnd;
3、
向应用程序的项目中添加背景位图和掩模位图,其ID分别设置为IDB_SHOW、IDB_MASK;
4、
添加代码,编译运行程序。
三、程序代码
////////////////////////////////////////////////////////////////
MyWnd.h : header file #if
!defined(AFX_MYWND_H__A761190E_CDF2_4A56_8848_AEE5AC7AD160__INCLUDED_) #define
AFX_MYWND_H__A761190E_CDF2_4A56_8848_AEE5AC7AD160__INCLUDED_ #if
_MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 //
CMyWnd window class CMyWnd : public CWnd { //
Construction public: CMyWnd(); //
Attributes public: // Operations public: //
Overrides // ClassWizard generated virtual function
overrides //{{AFX_VIRTUAL(CMyWnd) //}}AFX_VIRTUAL //
Implementation public: void Initialize(LPCTSTR lpszName,CRect
&rectWnd,UINT nMaskId,UINT nShowId); void Display(CDC *pDC,UINT
nMaskId); virtual ~CMyWnd(); // Generated message map
functions protected: //{{AFX_MSG(CMyWnd) afx_msg BOOL
OnEraseBkgnd(CDC* pDC); afx_msg UINT OnNcHitTest(CPoint
point); afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT
nFlags); //}}AFX_MSG DECLARE_MESSAGE_MAP() private: UINT
m_nBitmapId; }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++
will insert additional declarations immediately before the previous
line. #endif //
!defined(AFX_MYWND_H__A761190E_CDF2_4A56_8848_AEE5AC7AD160__INCLUDED_)
//////////////////////////////////////////////////////////
MyWnd.cpp : implementation file #include "stdafx.h" #include
"transparent.h" #include "MyWnd.h" #ifdef _DEBUG #define new
DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] =
__FILE__; #endif //
CMyWnd CMyWnd::CMyWnd() {}
CMyWnd::~CMyWnd() {}
BEGIN_MESSAGE_MAP(CMyWnd,
CWnd) //{{AFX_MSG_MAP(CMyWnd) ON_WM_ERASEBKGND() ON_WM_NCHITTEST() ON_WM_CHAR() //}}AFX_MSG_MAP END_MESSAGE_MAP()
BOOL
CMyWnd::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler
code here and/or call default CRect
rectWnd; this->GetWindowRect(&rectWnd); CDC
memDC; CBitmap
myBitmap,*pOldBitmap; myBitmap.LoadBitmap(m_nBitmapId); memDC.CreateCompatibleDC(pDC); pOldBitmap
=
memDC.SelectObject(&myBitmap); pDC->BitBlt(0,0,rectWnd.Width(),rectWnd.Height(),
&memDC,0,0,SRCCOPY); // 将设备还原 memDC.SelectObject(pOldBitmap
); return TRUE; }
UINT CMyWnd::OnNcHitTest(CPoint point)
{ // TODO: Add your message handler code here and/or call
default UINT nHitTest = CWnd :: OnNcHitTest(point) ; return
(nHitTest == HTCLIENT) ? HTCAPTION : nHitTest ; }
void
CMyWnd::Display(CDC *pDC, UINT nMaskId) { // 获得窗体矩形 CRect
rectWnd; this->GetWindowRect(rectWnd); // 读取位图资源 CBitmap
myBitmap,*pOldBitmap; myBitmap.LoadBitmap(nMaskId); //
创建"内存一致"设备 CDC
memDC; memDC.CreateCompatibleDC(pDC); //选择绘图设备 pOldBitmap =
memDC.SelectObject(&myBitmap); // 创建窗体的初始区域 CRgn
rgnWnd,rgnTemp; rgnWnd.CreateRectRgn(0,0,rectWnd.Width(),rectWnd.Height()); int
nWidth,nHeight; COLORREF color; for (nWidth = 0;nWidth <=
rectWnd.Width()-1;nWidth++) { for (nHeight = 0;nHeight <=
rectWnd.Height();nHeight++) { color =
memDC.GetPixel(nWidth,nHeight);
// 当象素是白色时,去掉该点 if (color
==
RGB(255,255,255)) { rgnTemp.CreateRectRgn(nWidth,nHeight,nWidth+1,nHeight+1); rgnWnd.CombineRgn(&rgnWnd,&rgnTemp,RGN_XOR); rgnTemp.DeleteObject();
} } } memDC.SelectObject(pOldBitmap); SetWindowRgn((HRGN)rgnWnd,TRUE); }
void
CMyWnd::Initialize(LPCTSTR lpszName, CRect &rectWnd, UINT nMaskId,
UINT
nShowId) { this->CreateEx(0,AfxRegisterWndClass(0),lpszName,WS_POPUP |
WS_SYSMENU,rectWnd,NULL,NULL,NULL); this->Display(GetWindowDC(),nMaskId); m_nBitmapId
= nShowId; }
void CMyWnd::OnChar(UINT nChar, UINT nRepCnt, UINT
nFlags) { // TODO: Add your message handler code here and/or call
default if(nChar==VK_ESCAPE) { PostMessage(WM_QUIT); } CWnd::OnChar(nChar,
nRepCnt,
nFlags); } //////////////////////////////////////////////////////////// BOOL
CTransparentApp::InitInstance() { #ifdef
_AFXDLL Enable3dControls(); // Call this when using MFC in a shared
DLL #else Enable3dControlsStatic(); // Call this when linking to
MFC statically #endif m_pMainWnd = &m_wndMain;//
m_wndMain是CmyWnd类成员变量; CRect rectWnd(500, 300, 580,
380); m_wndMain.Initialize(_T("loveghost"),rectWnd,IDB_MASK,IDB_SHOW); m_wndMain.ShowWindow(SW_SHOW);
// 窗体创建完毕,显示之; return TRUE; //
返回非零值表示要继续处理消息 } | 四、小结
这种异形窗口的创建方法适应于所有的基于CWnd类的派生窗口,采用这一方法,可以创建出任何形状的"异形"窗体。
131
|