欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MFC繪制不規(guī)則窗體的方法

 更新時(shí)間:2015年05月25日 16:00:41   作者:惟愿蓮心不染塵  
這篇文章主要介紹了MFC繪制不規(guī)則窗體的方法,涉及MFC窗體操作的相關(guān)技巧,需要的朋友可以參考下

本文實(shí)例講述了MFC 繪制不規(guī)則窗體的方法。分享給大家供大家參考。具體分析如下:

實(shí)現(xiàn)過程:

1、首先創(chuàng)建基于DLG的MFC應(yīng)用程序,命名為:tryBGDlg,并將DLG的屬性設(shè)置為:Title Bar :False ,其它設(shè)置不變

2、制作兩幅圖像,其中的一幅黑白圖像,是根據(jù)播放器外觀來制作的,其中白色區(qū)域是要保留的最終在桌面上顯示的區(qū)域。將這兩幅圖像添加到工程中,第一個(gè)ID號(hào)設(shè)置為IDB_INTERFACE,第二個(gè)ID號(hào)設(shè)置為:IDB_MASK

3、在CtryBGDlg類中添加一個(gè)在函數(shù):

函數(shù)說明:cBitmap是要傳入的掩碼位置變量,這里是指IDB_MASK創(chuàng)建的對象,TransColor是指要設(shè)為透明相素的RGB值

void CtryBGDlg::SetupRegion( CDC *pDC, CBitmap &cBitmap, COLORREF TransColor ) 
{ 
  CDC memDC; 
  memDC.CreateCompatibleDC(pDC); 
  CBitmap *pOldMemBmp=NULL; 
  pOldMemBmp=memDC.SelectObject(&cBitmap); 
  BITMAP bit; 
  cBitmap.GetBitmap (&bit); 
  CRgn crRgn, crRgnTmp; 
  crRgn.CreateRectRgn(0, 0, 0, 0);//創(chuàng)建一個(gè)空區(qū)域 
  int iX = 0;int iY = 0; 
  for (iY = 0; iY < bit.bmHeight; iY++) 
  { 
    do 
    { 
      //skip over transparent pixels at start of lines. 
      while (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) == TransColor) 
        iX++; 
      //remember this pixel 
      int iLeftX = iX; 
      //now find first non transparent pixel 
      while (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) != TransColor) 
        ++iX; 
      //create a temp region on this info 
      crRgnTmp.CreateRectRgn(iLeftX, iY, iX, iY+1); 
      //combine into main region. 
      crRgn.CombineRgn(&crRgn, &crRgnTmp, RGN_XOR); 
      //delete the temp region for next pass (otherwise you'll get an ASSERT) 
      crRgnTmp.DeleteObject(); 
    }while(iX < bit.bmWidth); 
    iX = 0; 
  } 
  SetWindowRgn(crRgn, TRUE); 
  iX = (GetSystemMetrics(SM_CXSCREEN))-700; 
  iY = (GetSystemMetrics(SM_CYSCREEN)) / 2 - (bit.bmHeight / 2); 
  SetWindowPos(&wndTop, iX, iY, bit.bmWidth, bit.bmHeight, NULL);  
  // Free resources. 
  memDC.SelectObject(pOldMemBmp);
  // Put the original bitmap back (prevents memory leaks) 
  memDC.DeleteDC(); 
  crRgn.DeleteObject(); 
}

4、在BOOL CtryBGDlg::OnInitDialog()函數(shù)中添加如下代碼:

CBitmap bmp; 
bmp.LoadBitmapW(IDB_MASK); 
this->SetupRegion(this->GetWindowDC(),bmp,RGB(0,0,0));

5、添加對WM_ERASEBKGND消息響應(yīng),并在BOOL CtryBGDlg::OnEraseBkgnd(CDC* pDC)函數(shù)中添加如下代碼

BOOL CtryBGDlg::OnEraseBkgnd(CDC* pDC) 
{ 
  // TODO: 在此添加消息處理程序代碼和/或調(diào)用默認(rèn)值 
  CRect rect; 
  this->GetWindowRect(&rect); 
  CDC memDC; 
  CBitmap bmp; 
  CBitmap *pOldBmp=NULL; 
  bmp.LoadBitmapW(IDB_INTERFACE); 
  memDC.CreateCompatibleDC(pDC); 
  pOldBmp=memDC.SelectObject(&bmp); 
  pDC->BitBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY); 
  if(pOldBmp) 
  { 
    memDC.SelectObject(pOldBmp); 
  } 
  return true; 
// return CDialog::OnEraseBkgnd(pDC); 
}

到此就實(shí)現(xiàn)了不規(guī)則窗體的創(chuàng)建,創(chuàng)建后的視圖如開頭所示。

6、一般我們還要實(shí)現(xiàn)對窗體的托動(dòng)操作,實(shí)現(xiàn)方法如下:
添加對WM_NCHITTEST消息的響應(yīng),并在生成的LRESULT CtryBGDlg::OnNcHitTest(CPoint point)函數(shù)中添加如下代碼:

LRESULT CtryBGDlg::OnNcHitTest(CPoint point) 
{ 
  // TODO: 在此添加消息處理程序代碼和/或調(diào)用默認(rèn)值 
  CRect rc; 
  GetClientRect(&rc); 
  ClientToScreen(&rc); 
  return rc.PtInRect(point) ? HTCAPTION : CDialog::OnNcHitTest(point); 
// return CDialog::OnNcHitTest(point); 
}

至此就完全實(shí)現(xiàn)了,不規(guī)則窗體的創(chuàng)建和對窗體托動(dòng)消息的響應(yīng)部分。

下面將細(xì)致的講解具體實(shí)現(xiàn)原理及部分的代碼的解析:

總原理:這個(gè)程序的原理主要是先用IDB_MASK圖像計(jì)算出要設(shè)定的窗體的輪廓,然后利用SetWindowRgn()函數(shù)來對其進(jìn)行更改。最后在窗體重繪的時(shí)候響應(yīng)WM_ERASEBKGND消息,將窗體背景圖片IDB_INTERFACE貼到窗體上。
 
利用IDB_MASK圖像計(jì)算窗體輪廓的原理:

計(jì)算窗體輪廓的代碼主要靠SetupRegion()函數(shù)來實(shí)現(xiàn),考慮到窗體的不規(guī)則,應(yīng)采取掩模位圖的方式來對其進(jìn)行描述,對于本例,其白色區(qū)域?yàn)橐A舻牟灰?guī)則窗體的輪廓區(qū)域。這段代碼首先是用crRgn.CreateRectRgn(0, 0, 0, 0)創(chuàng)建一個(gè)空的區(qū)域,然后對IDB_MASK圖像的像素信息進(jìn)行一列一列的枚舉,計(jì)算出每列中不設(shè)為透明的區(qū)域,然后跟crRgn合并,所以最后的crRgn就是所要設(shè)定的區(qū)域。

核心代碼為:

CRgn crRgn, crRgnTmp; 
  //創(chuàng)建一個(gè)空區(qū)域 
  crRgn.CreateRectRgn(0, 0, 0, 0); 
  int iX = 0;int iY = 0; 
  for (iY = 0; iY < bit.bmHeight; iY++) 
  { 
    do 
    { 
      //skip over transparent pixels at start of lines. 
      //以一個(gè)相素列為單位,找到在這一個(gè)相素列中,第一個(gè)不是要設(shè)為透明相素的點(diǎn)iX。 
      //然后再找到以這個(gè)iX為起點(diǎn)的,在這個(gè)一個(gè)相素列中最后跟他臨近的最后一個(gè)不是透明的點(diǎn)。 
      //然后將他們一起合并到crRgn中。 
      while (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) == TransColor) 
        iX++;//在iY和iY+1這個(gè)相索列中,第一個(gè)不設(shè)為透明的點(diǎn)的X坐標(biāo) 
      int iLeftX = iX;//保存這個(gè)點(diǎn)的坐標(biāo) 
      while (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) != TransColor) 
        ++iX;//這是找到在iX最臨近的不透明的X坐標(biāo) 
      crRgnTmp.CreateRectRgn(iLeftX, iY, iX, iY+1);//這四個(gè)點(diǎn)連在一起就是現(xiàn)在剛找到的不透明的區(qū)域 
      //合并區(qū)域 
      crRgn.CombineRgn(&crRgn, &crRgnTmp, RGN_OR); 
      //記得最終要手動(dòng)刪除crRgnTmp對象 
      crRgnTmp.DeleteObject(); 
    }while(iX < bit.bmWidth);
    //如果iX沒有達(dá)到圖片的末尾,說明還沒有枚舉完這一行,則在iY和iY+1這個(gè)行上,進(jìn)行下一輪的//枚舉 
    iX = 0; 
}

希望本文所述對大家的MFC程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • C++實(shí)現(xiàn)LeetCode165.版本比較)

    C++實(shí)現(xiàn)LeetCode165.版本比較)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode165.版本比較),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++引用的使用與const修飾符

    C++引用的使用與const修飾符

    這篇文章介紹了C++引用使用與const修飾符,引用是給已經(jīng)定義的變量一個(gè)別名,可以簡單理解成同一個(gè)變量的昵稱,既然是昵稱或者是別名,顯然它和原本的變量名有著同樣的效力,所以我們對別名進(jìn)行修改,原本的變量值也一樣會(huì)發(fā)生變化,下面來看看詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-11-11
  • 老生常談C++中實(shí)參形參的傳遞問題

    老生常談C++中實(shí)參形參的傳遞問題

    下面小編就為大家?guī)硪黄仙U凜++中實(shí)參形參的傳遞問題。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • 深入理解:Java是類型安全的語言,而C++是非類型安全的語言

    深入理解:Java是類型安全的語言,而C++是非類型安全的語言

    本篇文章是對Java是類型安全的語言,而C++是非類型安全的語言進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • C語言數(shù)據(jù)結(jié)構(gòu)遞歸之斐波那契數(shù)列

    C語言數(shù)據(jù)結(jié)構(gòu)遞歸之斐波那契數(shù)列

    這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)遞歸之斐波那契數(shù)列的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • C語言指針詳解及用法示例

    C語言指針詳解及用法示例

    這篇文章主要介紹了C語言指針詳解及用法示例,介紹了其相關(guān)概念,然后分享了幾種用法,具有一定參考價(jià)值。需要的朋友可以了解下。
    2017-11-11
  • C++音樂播放按鈕的封裝過程詳解

    C++音樂播放按鈕的封裝過程詳解

    此篇文章用于記錄學(xué)習(xí)C++封裝音樂播放按鈕,封裝將對象的屬性和行為作為一個(gè)整體,表現(xiàn)生活中的事物、將屬性和行為加以權(quán)限控制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • C語言實(shí)現(xiàn)自動(dòng)發(fā)牌程序

    C語言實(shí)現(xiàn)自動(dòng)發(fā)牌程序

    這篇文章主要介紹了利用C語言實(shí)現(xiàn)自動(dòng)發(fā)牌程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • C++中字符串全排列算法及next_permutation原理詳解

    C++中字符串全排列算法及next_permutation原理詳解

    這篇文章主要為大家詳細(xì)介紹了C++中字符串全排列(遞歸法)和(迭代法)以及next_permutation底層原理,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2023-02-02
  • C++中的模板template小結(jié)

    C++中的模板template小結(jié)

    這篇文章主要介紹了C++中的模板template的相關(guān)知識(shí),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03

最新評論