MFC 不规则对话框(加载png 为背景)

1:本文是使用的是 Gdi 的cImage 加载png

2:首先加载函数如下:

bool CPNGDialogRegionDlg::LoadImageFromResource( CImage* pImage, UINT nResID, LPCWSTR lpTyp )
{
 if (pImage == NULL) return false;

 pImage->Destroy();

 // 查找资源
 HRSRC hRsrc = ::FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(nResID), lpTyp);
 if (hRsrc == NULL) return false;

 // 加载资源
 HGLOBAL hImgData = ::LoadResource(AfxGetResourceHandle(), hRsrc);
 if (hImgData == NULL)
 {
  ::FreeResource(hImgData);
  return false;
 }

 // 锁定内存中的指定资源
 LPVOID lpVoid    = ::LockResource(hImgData);

 LPSTREAM pStream = NULL;
 DWORD dwSize    = ::SizeofResource(AfxGetResourceHandle(), hRsrc);
 HGLOBAL hNew    = ::GlobalAlloc(GHND, dwSize);
 LPBYTE lpByte    = (LPBYTE)::GlobalLock(hNew);
 ::memcpy(lpByte, lpVoid, dwSize);

 // 解除内存中的指定资源
 ::GlobalUnlock(hNew);

 // 从指定内存创建流对象
 HRESULT ht = ::CreateStreamOnHGlobal(hNew, TRUE, &pStream);
 if ( ht != S_OK )
 {
  GlobalFree(hNew);
 }
 else
 {
  // 加载图片
  pImage->Load(pStream);

  GlobalFree(hNew);
 }

 // 释放资源
 ::FreeResource(hImgData);

 // 像素转换,由于CImage 中没有对alpha 进行处理
 for( int row = 0; row < pImage->GetWidth(); row++ )
 {
  for( int col = 0; col < pImage->GetHeight(); col++ )
  {
   UCHAR* cr = (UCHAR*) pImage->GetPixelAddress(row, col);
   cr[0] = cr[0] * cr[3] / 255;
   cr[1] = cr[1] * cr[3] / 255;
   cr[2] = cr[2] * cr[3] / 255;
  }
 }
 return true;
}

3:根据png 裁剪掉透明的区域

void CPNGDialogRegionDlg::CreateRgnByImage( CImage* pImage, CRgn &rgn )
{
 rgn.CreateRectRgn(0, 0, 0, 0);
 CRgn tempRgn;
 for (UINT h = 0; h < (UINT)pImage->GetHeight(); ++ h)
 {
  UINT w = 0;
  while(w < (UINT)m_ImageBg.GetWidth())
  {
   UINT leftX = w;
   while (w < (UINT)m_ImageBg.GetWidth() )
   {
    UCHAR* cr = (UCHAR*) pImage->GetPixelAddress(w, h);
    if( cr[3] != 0 )
     break;
    leftX = w;
    w++;
   }
   while (w < (UINT)m_ImageBg.GetWidth() )
   {
    UCHAR* cr = (UCHAR*) pImage->GetPixelAddress(w, h);
    if( cr[3] == 0 )
     break;
    w++;
   }
   tempRgn.CreateRectRgn(leftX, h, w - 1, h + 1);
   rgn.CombineRgn(&rgn, &tempRgn, RGN_OR);
   tempRgn.DeleteObject();
  }
 }
}

 

4:在CPNGDialogRegionDlg::OnInitDialog() 函数中:

// TODO: 在此添加额外的初始化代码
 int width = 1024;
 int height= 768;

 CRgn rgn;
 //CreateRgnByImage( IDB_BITMAP_BACKGROUND, rgn, width, height );
 LoadImageFromResource(&m_ImageBg, IDB_PNG_BACKGROUND, _TEXT("RCPNG"));
 width = m_ImageBg.GetWidth();
 height = m_ImageBg.GetHeight();
 CreateRgnByImage( &m_ImageBg, rgn );

 CRect rc;
 GetWindowRect(&rc);
 int nScreenWidth = GetSystemMetrics( SM_CXFULLSCREEN );
 int nScreenHeight = GetSystemMetrics( SM_CYFULLSCREEN );
 if( nScreenWidth > width )
  rc.left = (nScreenWidth-width)/2;
 if( nScreenHeight > height )
  rc.top = (nScreenHeight-height)/2;
 rc.right = rc.left + width;
 rc.bottom = rc.top + height;

 MoveWindow(&rc);
 SetWindowRgn(rgn, TRUE);

 

4:在OnEraseBkgnd(CDC* pDC) 是显示,并且背景透明模式

BOOL CPNGDialogRegionDlg::OnEraseBkgnd(CDC* pDC)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
 m_ImageBg.AlphaBlend(pDC->GetSafeHdc(),0,0);
 pDC->SetBkMode( TRANSPARENT );
 //return CDialog::OnEraseBkgnd(pDC);
 return TRUE;
}

按上面的4个步骤即可用png 做不规则的窗体了

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值