/* *-------------------------------------------------------------------------------- * 成员函数名 : OnPaint() * 功能描述 : 绘制窗体或窗体尺寸发生改变时重画窗体 * 算法 : 透明显示位图,透明色为 g_stuPaintSet.tranCol * 附加说明 : 窗口缩放时图像并不改变,而是在显示时改变复制位图,然后缩放显示 *-------------------------------------------------------------------------------- */ void CFloatDibWnd::OnPaint() { ASSERT(m_pDib); CRect rect; GetClientRect(&rect); // 用当前图像创建一个临时位图,对它进行缩放显示,以防失真 CDib *pTmpDib = m_pDib->Clone(); pTmpDib->ChangeImageSize(rect.Width(), rect.Height()); pTmpDib->DisplayTransparent(GetDC(), 0, 0, g_stuPaintSet.tranCol); delete pTmpDib; CWnd::OnPaint(); }
/* *-------------------------------------------------------------------------------- * 函数名 : RotateAngle * 功能 : 旋转浮动窗口 * 参数 : double angle - 旋转的角度 *-------------------------------------------------------------------------------- */ BOOL CFloatDibWnd::RotateAngle(double angle) { // 因为是对源图像进行旋转操作,所以要把上一次旋转角度与此次旋转角度叠加 m_dblPreRotateAngle += angle; if (m_dblPreRotateAngle > 360) m_dblPreRotateAngle -= 360; angle = m_dblPreRotateAngle; //对pDib操作实际上就是对m_pDib操作 HBITMAP *m_hBitmap ; CDib * pDib; pDib = m_pSrcDib->Clone(); CPoint cirpoint; CRect rect; GetClientRect(&rect); //使源DIB缩放成当前画布区大小 pDib->ChangeImageSize(rect.Width(), rect.Height()); m_pDib->ChangeImageSize(rect.Width(), rect.Height()); //得到图形矩形区的中心点坐标值 cirpoint.x = rect.Width()/2; cirpoint.y = rect.Height()/2; CClientDC dc(this); ASSERT_VALID(&dc); //以下生成一相要操作的源内存设备上下文,它同目的内存上下文数据一致 BITMAP srcbm; HBITMAP * hBitmap; CDC srcDC; CBitmap pBitmap; // 产生源内存设备情境对象(为避免失真总是选用最初的源DIB) srcDC.CreateCompatibleDC(NULL); hBitmap=(HBITMAP *)pDib->GetBitmap()->GetSafeHandle(); srcDC.SetBkMode(TRANSPARENT); // 将位图选入源内存设备情境对象 srcDC.SelectObject(hBitmap); GetObject(hBitmap, sizeof(srcbm),&srcbm); //为使旋转的源和目的设备上下文一致,必须使目的DIB使用m_pDib CDC * MemDC = m_pDib->BeginPaint(&dc); MemDC->SetBkMode(TRANSPARENT); int i,j; BITMAP m_Bm ; m_hBitmap = (HBITMAP *)m_pDib->GetBitmap()->GetSafeHandle(); // 将目的位图选入内存设备情境对象(此时源及目的位图数据内容一致) MemDC->SelectObject(m_hBitmap); GetObject(m_hBitmap, sizeof(m_Bm),&m_Bm); //将目的内存设备上下文件全部填充为粉红色 MemDC->FillSolidRect(CRect(0, 0, m_pDib->GetWidth(), m_pDib->GetHeight()),g_stuPaintSet.tranCol); CPoint point1, point2; point1.x = m_pDib->GetWidth()/ 2; point1.y = m_pDib->GetHeight()/ 2; //开始对内存DC进行旋转操作 for (i = (int) -0.4 * m_Bm.bmWidth; i < (int) 1.4 * m_Bm.bmWidth; i++) for(j = (int) -0.4 * m_Bm.bmHeight; j < (int) 1.4 * m_Bm.bmHeight; j++) { point2.x = i; point2.y = j; point2 = CountPoint(point1, point2, angle); if(srcDC.GetPixel(point2) != g_stuPaintSet.tranCol) MemDC->StretchBlt( cirpoint.x + i-point1.x, cirpoint.y + j-point1.y, 1, 1, &srcDC, point2.x, point2.y, 1,1, SRCCOPY ); } m_pDib->EndPaint(); if (pDib) delete pDib; // 缩放窗口,以与旋转过后的图像大小相匹配 /* int nWidth, nHeight, left, top; nWidth = m_pDib->GetWidth(); nHeight = m_pDib->GetHeight(); CPoint ptCenter = RectToParentClient().CenterPoint(); left = ptCenter.x - nWidth / 2; top = ptCenter.y - nHeight / 2; ::MoveWindow(GetSafeHwnd(), left, top, nWidth, nHeight, TRUE); */ return TRUE; }