程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 撲克控件制作實例

撲克控件制作實例

編輯:關於VC++

前言

本文以撲克控件的制作過程為實例,介紹了MFC ActiveX控件的詳細制作過程,希望對學習控件編寫的朋友有所幫助。

一、撲克控件的制作

1、新建一個“MFC ActiveX ControlWizard”工程。為工程名起名為Cards,然後用向導的默認值一路OK生成工程。

2、為工程中添加五十四張撲克牌位圖以及撲克背景位圖資源。注意位圖中有一張IDB_CARDS位圖為控件顯示時的圖標,可以自行修改成自己喜歡的圖樣。

3、為控件填加屬性值,打開View—>ClassWizard。點擊Automation標簽。從類名下拉框中選擇CCardsCtrl,點擊“Add Property”按鈕彈出屬性添加對話框。在External name中輸入value,Type選擇為short類型。同時在Implementation一項中選擇Get/Set methods,還有兩項不管它,就用它自己設置的函數就行了。現在我們已經為控件添加好了一個屬性,它是用來處理撲克牌的點數的。

4、按照第三步的方法,我們再依次設置幾個屬性,分別是backbmp,類型為short,用來處理背景圖案是什麼;background,類型為BOOL,用來處理顯示牌正面還是反面。

5、屬性添加好了,下面為這些屬性設置初始值:打開CardsCtl.cpp文件,在構造函數CCardsCtrl::CCardsCtrl()中加入代碼:value=1;backbmp=1;

6、為了使控件能夠在程序中正常顯示出來,我們還需要對CCardsCtrl::OnDraw進行修改。修改後的內容如下:

void CCardsCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
  CBitmap *pOldBitmap;
  CBitmap bitmap;
  CRect rect;
  GetClientRect(rect);
  CDC ppdc;
  CClientDC dc(this);
  ppdc.CreateCompatibleDC(&dc);
  if(background)//背景圖案
  {
    if(backbmp==1)bitmap.LoadBitmap(255);
    if(backbmp==2)bitmap.LoadBitmap(256);
  }
  else//前景圖案
    bitmap.LoadBitmap(IDB_BITMAP1+value-1);
  pOldBitmap=ppdc.SelectObject(&bitmap);
  dc.BitBlt(0,0,rect.Width(),rect.Height(),&ppdc,0,0,SRCCOPY);
  ppdc.SelectObject(pOldBitmap);
}

在上面的代碼中,要注意的是bitmap.LoadBitmap(IDB_BITMAP1+value-1);語句,一定要保證你在資源中插入的位圖資源連續。可以打開Resource.h文件看一看,你的位圖資源是否是連續的。

7、接下來要修改屬性函數了。修改前在CardsCtl.h中加入成員變量(有些在後面能夠用得上):

protected:
  short value,backbmp;
  BOOL background;
  BOOL IsMove,m_IsMove;
  BOOL IsGoHome;
  CPoint OldPoint;
  CRect rect;
  long xx,yy;

修改後的函數如下:

short CCardsCtrl::GetValue()
{
  return value;
}
void CCardsCtrl::SetValue(short nNewValue)
{
  value=nNewValue;
  SetModifiedFlag();
  InvalidateControl();//立即刷新
}
BOOL CCardsCtrl::GetBackground()
{  
  return background;
}
void CCardsCtrl::SetBackground(BOOL bNewValue)
{
  background=bNewValue;
  SetModifiedFlag();
  InvalidateControl();
}
short CCardsCtrl::GetBackbmp()
{
  return backbmp;
}
void CCardsCtrl::SetBackbmp(short nNewValue)
{
  backbmp=nNewValue;
  SetModifiedFlag();
  InvalidateControl();
}

可以看出,這些函數的修改都是大同小異,GetXXXXX()是用來得到屬性值,SetXXXXX()用來設置屬性值。InvalidateControl()函數用來刷新控件,使修改屬性後的控件能立刻反映在屏幕上。

8、為了能使控件能夠被隨意拖動,我們還需要做下面的准備工作,首先按照第三步的方法添加兩個屬性:IsMove,類型為BOOL,用來處理控件是否能被拖動;IsGoHome,類型為BOOL,用來處理控件拖動後是否回到原位置。之後為這兩個屬性設置初始值,也是在構造函數CCardsCtrl::CCardsCtrl()中增加代碼

IsMove=false;
m_IsMove=false;
IsGoHome=true;

9、使控件能被拖動,需要處理鼠標左鍵按下、鼠標拖動以及鼠標左鍵抬起三個消息。在ClassWizard的“Message Maps”標簽中,為WM_LBUTTONDOWN、WM_MOUSEMOVE、WM_LBUTTONUP增加消息處理函數,然後修改這三個函數如下: void CCardsCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
  if(IsMove)//是否是允許拖動鼠標
  {
    m_IsMove=true;
    SetCapture();//捕獲鼠標
    xx=point.x;//得到鼠標(相對於控件左上角)的坐標
    yy=point.y;
    GetClientRect(&rect);//保存拖動前的撲克位置
    ::ClientToScreen(m_hWnd,&rect.TopLeft());
    OldPoint=rect.TopLeft();
    MoveWindow(0,0,0,0);//得到相對量
    GetClientRect(&rect);
    ::ClientToScreen(m_hWnd,&rect.TopLeft());
  }
  COleControl::OnLButtonDown(nFlags, point);
}
void CCardsCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  CPoint MyPoint=point;
  if(m_IsMove)
  {
    ClientToScreen(&MyPoint);
       MoveWindow(MyPoint.x-xx-rect.left,MyPoint.y-yy-rect.top,71,96);
  }
  COleControl::OnMouseMove(nFlags, point);
}
void CCardsCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  if(m_IsMove)
  {
    ReleaseCapture();
    m_IsMove=false;
    if(IsGoHome)
      MoveWindow(OldPoint.x-rect.left,OldPoint.y-rect.top,71,96);//還原到撲克牌拖動前的位置
  }
  COleControl::OnLButtonUp(nFlags, point);
}
10、到了這一步,此控件的主要工作已經完成了,現在我們為控件添加屬性頁,以使它和用戶的交流更友好。首先在ResourceView中修改默認的屬性頁對話框為你需要的(詳見程序源代碼)。然後在ClassWizard的“Member Variables”中。從類中選擇CCardsPropPage,點擊“Add Variable…”按鈕分別為你加入在屬性頁中的控件添加變量。這裡添加變量的方法大致和為普通對話框添加變量相同,唯一有區別的是這裡多了一項可選屬性名(Optional property name),用於選擇和變量相連的屬性。具體設置詳見下表:

控件名 變量名 組件 變量類型 可選屬性名 IDC_CHECK1 m_check1 value BOOL background IDC_CHECK2 m_check2 value BOOL IsMove IDC_CHECK4 m_check4 value BOOL IsGoHome IDC_EDIT1 m_edit1 value short value IDC_EDIT2 m_edit2 value short backbmp

11、最後,為了使屬性頁和控件關聯起來,我們再在void CCardsCtrl::DoPropExchange(CPropExchange* pPX)函數中添加代碼: PX_Short(pPX,"value",value,1);
PX_Short(pPX,"backbmp",backbmp,1);
PX_Bool(pPX,"background",background,false);
PX_Bool(pPX,"IsMove",IsMove,false);
PX_Bool(pPX,"IsGoHome",IsGoHome,false);
補充:控件中的右鍵單擊處理因為和制作此控件無關,這裡沒有解釋,若想知詳情請看源代碼。

二、控件測試

1、新建一“MFC AppWizard(exe)”工程,取名為test,建立完畢,在Project(工程)中選擇“Add Project(添加工程)”,再選“Components and Controls…”選項。 之後從彈出的對話框中雙擊“Registered ActiveX Controls”目錄。從目錄中選擇剛才我們編的控件“Cards Control”,點“Insert”按鈕把此控件插入到test工程中。

2、打開對話框資源,把控件拖動至對話框中,用鼠標右鍵單擊Cards控件,進行屬性設置,完畢後就可以運行了。

另外你也可以通過調用SetValue(short propVal)來手工設置撲克點數。好了,一切都OK了!

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved