程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 哲學家就餐問題——MFC演示程序

哲學家就餐問題——MFC演示程序

編輯:C++入門知識

[cpp]
</pre><pre name="code" class="cpp"> 
     這個問題實際上就是多線程的調度問題,因為MFC裡面已經給我們封裝好了線程類,CWinThread類,因此我們要做的僅僅是簡單的為每位哲學家分別創建進程。程序邏輯不是很復雜,但在用MFC來做哲學家就餐問題的演示問題時,就涉及到的圖像繪制可能比較麻煩,因為你要給每位哲學家的當前狀態給出相應的圖示。

\

這個是我寫的演示程序的主界面,左邊使用圖形顯示哲學家就餐中的一些狀態切換,右邊用編輯框給每位哲學家配以文字說明。

     一、先說下演示程序的核心部分,CWinThread類和CCriticalSection臨界區類

            MFC給我們封裝好了線程類CWinThread供我們在程序裡面去創建新的線程,其提供了兩種線程,工作線程和用戶線程(具體區別可以去查相應資料,這裡就不多說了),本程序采用的是工作線程(工作線程就是在後台處理大量數據,並不需要響應消息請求,用戶線程就是在線程運行的時候還要時刻捕獲用戶的消息請求)。

           工作線程創建很簡單

           CWinThread *pThread;

            pThread->AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );

           函數具體參數可以查MSDN,我們常用的就是前面兩個參數,第一個是是指定我們創建的線程所執行的代碼,第二個參數是我們要傳遞給線程的數據結構。

           本程序因為有六位哲學家,所以我創建了6個線程,並為其指定了執行函數        


[cpp] CWinThread *pthread[6]; 
       for(int i=0;i<6;i++) 
           pthread[i]=AfxBeginThread(Eat,&imageinfo[i]); 
 CWinThread *pthread[6];
        for(int i=0;i<6;i++)
            pthread[i]=AfxBeginThread(Eat,&imageinfo[i]);
          其中Eat是我指定線程執行的代碼,因為本演示程序中六位哲學家做的事都是一樣的,所以每位哲學家線程的執行代碼也是一樣的,imageinfo是我要從主程序中傳遞給線程的一些基本數據信息。         

 

[cpp] struct ImageInfo 

  int index;                                   //索引,表示當前的是幾號哲學家線程在執行  
  CPoint pt_chair;                         //椅子的坐標  
  CPoint pt_chopstick_middle[2]; //  
  CPoint pt_chopstick_start[2];     //叉子的坐標信息  
  CPoint pt_chopstick_end[2];      //  
  double radius_chair;                 //椅子半徑  
  double radius_table;                 //桌子的半徑  
  CWnd* pWnd;                          //主程序窗口的句柄  
  CRect rect;    
  HWND edit;                             //右邊相應編輯框的句柄  
}; 
struct ImageInfo
{
  int index;                                   //索引,表示當前的是幾號哲學家線程在執行
  CPoint pt_chair;                         //椅子的坐標
  CPoint pt_chopstick_middle[2]; //
  CPoint pt_chopstick_start[2];     //叉子的坐標信息
  CPoint pt_chopstick_end[2];      //
  double radius_chair;                 //椅子半徑
  double radius_table;                 //桌子的半徑
  CWnd* pWnd;                          //主程序窗口的句柄
  CRect rect;  
  HWND edit;                             //右邊相應編輯框的句柄
};        [cpp] UINT Eat(LPVOID param) 
{    
    while (true)                     //設置為無線循環,好讓線程一直運行下去  
    { 
 
    ImageInfo *imageinfo=(ImageInfo*)param; 
    CDC *pDC=imageinfo->pWnd->GetDC();               //獲得主程序窗口的DC  
       //char textbuff[1024];  
    //::GetWindowText(imageinfo->edit,textbuff,1024);  
    CString text; 
    CString temp; 
    bool caneat=FALSE;                                              //標識變量,驗證當前哲學家線程是否可以就餐 
UINT Eat(LPVOID param)
{  
 while (true)                     //設置為無線循環,好讓線程一直運行下去
 {

 ImageInfo *imageinfo=(ImageInfo*)param;
 CDC *pDC=imageinfo->pWnd->GetDC();               //獲得主程序窗口的DC
       //char textbuff[1024];
 //::GetWindowText(imageinfo->edit,textbuff,1024);
 CString text;
 CString temp;
 bool caneat=FALSE;                                              //標識變量,驗證當前哲學家線程是否可以就餐[cpp] CBrush brush_think,brush_eat,brush_wait,*oldbrush;  //表示各種狀態的畫刷和畫筆 
 CBrush brush_think,brush_eat,brush_wait,*oldbrush;  //表示各種狀態的畫刷和畫筆[cpp]     CPen whitepen,blackpen,backpen,*oldpen; 
 
    whitepen.CreatePen(PS_SOLID,4,RGB(255,255,255)); 
    blackpen.CreatePen(PS_SOLID,4,RGB(0,0,0)); 
    backpen.CreatePen(PS_SOLID,4,RGB(240,240,240)); 
     
     
    brush_think.CreateSolidBrush(RGB(255,0,0)); 
    brush_eat.CreateSolidBrush(RGB(0,255,0)); 
    brush_wait.CreateSolidBrush(RGB(0,0,255)); 
    CRect rect;  
  
     
 
    //思考階段  
    temp.Format("開始思考!");    
    //text.Format(textbuff);  
    //text=text+"\r\n"+temp;  
    ::SetWindowText(imageinfo->edit,(LPCTSTR)temp);   
 
    oldbrush=(CBrush*)pDC->SelectObject(&brush_think);    
     
    rect.left=imageinfo->pt_chair.x-imageinfo->radius_chair; 
    rect.right=imageinfo->pt_chair.x+imageinfo->radius_chair; 
    rect.top=imageinfo->pt_chair.y-imageinfo->radius_chair; 
    rect.bottom=imageinfo->pt_chair.y+imageinfo->radius_chair; 
    pDC->Ellipse(rect); 
    //num.Format("%d",imageinfo->index+1);  
    //pDC->DrawText(num,rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);  
    pDC->SelectObject(oldbrush); 
 
    g_cls.Lock();                  //g_cls為臨界區變量,此處進入臨界區  
    if (chopsticks[imageinfo->index]==1&&chopsticks[(imageinfo->index+5)%6]==1) 
    {        
        chopsticks[imageinfo->index]=0; 
        chopsticks[(imageinfo->index+5)%6]=0; 
        caneat=TRUE; 
    } 
    g_cls.Unlock();          //退出臨界區  
    Sleep(2000); 
    if (FALSE==caneat) 
    {            
 
       temp.Format("沒有拿到兩個叉子,無法吃飯!");   
       ::SetWindowText(imageinfo->edit,(LPCTSTR)temp); 
       Sleep(1000); 
       temp.Format("開始等待...");   
       ::SetWindowText(imageinfo->edit,(LPCTSTR)temp); 
 
       oldbrush=(CBrush*)pDC->SelectObject(&brush_wait); 
       pDC->Ellipse(rect); 
       pDC->SelectObject(oldbrush); 
       //pDC->DrawText(num,rect,DT_CENTER|DT_SINGLELINE|DT_VCENTER);  
       Sleep(2000); 
    } 
    if (TRUE==caneat) 
    { 
     
        temp.Format("成功拿到兩個叉子,開始吃飯!");   
        ::SetWindowText(imageinfo->edit,(LPCTSTR)temp); 
        Sleep(1000); 
        temp.Format("吃飯...",imageinfo->index); 
    //::GetWindowText(imageinfo->edit,textbuff,1024);  
    //text.Format(textbuff);  
    //text=text+"\r\n"+temp;  
        ::SetWindowText(imageinfo->edit,(LPCTSTR)temp); 
 
        //吃飯的狀態,拿起筷子  
        oldpen=(CPen*)pDC->SelectObject(&blackpen); 
        pDC->MoveTo(imageinfo->pt_chair); 
        pDC->LineTo(imageinfo->pt_chopstick_middle[0]); 
        pDC->MoveTo(imageinfo->pt_chair); 
        pDC->LineTo(imageinfo->pt_chopstick_middle[1]); 
        pDC->SelectObject(oldpen); 
 
        oldpen=(CPen*)pDC->SelectObject(&whitepen); 
        pDC->MoveTo(imageinfo->pt_chopstick_middle[0]); 
        pDC->LineTo(imageinfo->pt_chopstick_end[0]); 
        pDC->MoveTo(imageinfo->pt_chopstick_middle[1]); 
        pDC->LineTo(imageinfo->pt_chopstick_end[1]);                        
        pDC->SelectObject(oldpen); 
         
        oldbrush=(CBrush*)pDC->SelectObject(&brush_eat); 
        pDC->Ellipse(rect); 
        pDC->SelectObject(oldbrush); 
 
        //pDC->DrawText(num,rect,DT_VCENTER|DT_CENTER|DT_SINGLELINE);  
         
 
    Sleep((imageinfo->index+1)*1000); 
     
    //吃完飯,放下筷子  
    oldpen=(CPen*)pDC->SelectObject(&blackpen); 
    pDC->MoveTo(imageinfo->pt_chopstick_middle[0]); 
    pDC->LineTo(imageinfo->pt_chopstick_end[0]); 
    pDC->MoveTo(imageinfo->pt_chopstick_middle[1]); 
    pDC->LineTo(imageinfo->pt_chopstick_end[1]); 
    pDC->SelectObject(oldpen); 
 
    oldpen=(CPen*)pDC->SelectObject(&backpen); 
    pDC->MoveTo(imageinfo->pt_chair); 
    pDC->LineTo(imageinfo->pt_chopstick_middle[0]); 
    pDC->MoveTo(imageinfo->pt_chair); 
    pDC->LineTo(imageinfo->pt_chopstick_middle[1]); 
    pDC->SelectObject(oldpen); 
    oldbrush=(CBrush*)pDC->SelectObject(&brush_eat); 
    pDC->Ellipse(rect); 
        pDC->SelectObject(oldbrush); 
 
    g_cls.Lock(); 
    chopsticks[imageinfo->index]=1; 
    chopsticks[(imageinfo->index+5)%6]=1;     
    g_cls.Unlock(); 
    temp.Format("吃完飯,放下叉子!");   
    ::SetWindowText(imageinfo->edit,(LPCTSTR)temp); 
    Sleep(1000); 
    caneat=FALSE;    
    }   
      
    } 
    //::SetWindowText(imageinfo->edit,"1");  
     
    return TRUE; 

 CPen whitepen,blackpen,backpen,*oldpen;

 whitepen.CreatePen(PS_SOLID,4,RGB(255,255,255));
 blackpen.CreatePen(PS_SOLID,4,RGB(0,0,0));
 backpen.CreatePen(PS_SOLID,4,RGB(240,240,240));
 
 
 brush_think.CreateSolidBrush(RGB(255,0,0));
 brush_eat.CreateSolidBrush(RGB(0,255,0));
 brush_wait.CreateSolidBrush(RGB(0,0,255));
 CRect rect;
 
 

 //思考階段
 temp.Format("開始思考!"); 
 //text.Format(textbuff);
 //text=text+"\r\n"+temp;
 ::SetWindowText(imageinfo->edit,(LPCTSTR)temp); 

 oldbrush=(CBrush*)pDC->SelectObject(&brush_think); 
 
 rect.left=imageinfo->pt_chair.x-imageinfo->radius_chair;
 rect.right=imageinfo->pt_chair.x+imageinfo->radius_chair;
 rect.top=imageinfo->pt_chair.y-imageinfo->radius_chair;
 rect.bottom=imageinfo->pt_chair.y+imageinfo->radius_chair;
 pDC->Ellipse(rect);
 //num.Format("%d",imageinfo->index+1);
 //pDC->DrawText(num,rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
 pDC->SelectObject(oldbrush);

    g_cls.Lock();                  //g_cls為臨界區變量,此處進入臨界區
 if (chopsticks[imageinfo->index]==1&&chopsticks[(imageinfo->index+5)%6]==1)
 {  
  chopsticks[imageinfo->index]=0;
  chopsticks[(imageinfo->index+5)%6]=0;
  caneat=TRUE;
 }
    g_cls.Unlock();          //退出臨界區
    Sleep(2000);
 if (FALSE==caneat)
 {          

       temp.Format("沒有拿到兩個叉子,無法吃飯!"); 
       ::SetWindowText(imageinfo->edit,(LPCTSTR)temp);
    Sleep(1000);
    temp.Format("開始等待..."); 
       ::SetWindowText(imageinfo->edit,(LPCTSTR)temp);

    oldbrush=(CBrush*)pDC->SelectObject(&brush_wait);
    pDC->Ellipse(rect);
    pDC->SelectObject(oldbrush);
       //pDC->DrawText(num,rect,DT_CENTER|DT_SINGLELINE|DT_VCENTER);
    Sleep(2000);
 }
 if (TRUE==caneat)
 {
 
  temp.Format("成功拿到兩個叉子,開始吃飯!"); 
        ::SetWindowText(imageinfo->edit,(LPCTSTR)temp);
  Sleep(1000);
     temp.Format("吃飯...",imageinfo->index);
 //::GetWindowText(imageinfo->edit,textbuff,1024);
 //text.Format(textbuff);
 //text=text+"\r\n"+temp;
     ::SetWindowText(imageinfo->edit,(LPCTSTR)temp);

     //吃飯的狀態,拿起筷子
        oldpen=(CPen*)pDC->SelectObject(&blackpen);
     pDC->MoveTo(imageinfo->pt_chair);
     pDC->LineTo(imageinfo->pt_chopstick_middle[0]);
     pDC->MoveTo(imageinfo->pt_chair);
     pDC->LineTo(imageinfo->pt_chopstick_middle[1]);
        pDC->SelectObject(oldpen);

     oldpen=(CPen*)pDC->SelectObject(&whitepen);
     pDC->MoveTo(imageinfo->pt_chopstick_middle[0]);
      pDC->LineTo(imageinfo->pt_chopstick_end[0]);
     pDC->MoveTo(imageinfo->pt_chopstick_middle[1]);
     pDC->LineTo(imageinfo->pt_chopstick_end[1]);                   
   pDC->SelectObject(oldpen);
  
  oldbrush=(CBrush*)pDC->SelectObject(&brush_eat);
     pDC->Ellipse(rect);
  pDC->SelectObject(oldbrush);

  //pDC->DrawText(num,rect,DT_VCENTER|DT_CENTER|DT_SINGLELINE);
  

 Sleep((imageinfo->index+1)*1000);
 
 //吃完飯,放下筷子
 oldpen=(CPen*)pDC->SelectObject(&blackpen);
    pDC->MoveTo(imageinfo->pt_chopstick_middle[0]);
 pDC->LineTo(imageinfo->pt_chopstick_end[0]);
 pDC->MoveTo(imageinfo->pt_chopstick_middle[1]);
 pDC->LineTo(imageinfo->pt_chopstick_end[1]);
    pDC->SelectObject(oldpen);

 oldpen=(CPen*)pDC->SelectObject(&backpen);
    pDC->MoveTo(imageinfo->pt_chair);
 pDC->LineTo(imageinfo->pt_chopstick_middle[0]);
 pDC->MoveTo(imageinfo->pt_chair);
 pDC->LineTo(imageinfo->pt_chopstick_middle[1]);
    pDC->SelectObject(oldpen);
 oldbrush=(CBrush*)pDC->SelectObject(&brush_eat);
 pDC->Ellipse(rect);
  pDC->SelectObject(oldbrush);

 g_cls.Lock();
 chopsticks[imageinfo->index]=1;
 chopsticks[(imageinfo->index+5)%6]=1;   
 g_cls.Unlock();
 temp.Format("吃完飯,放下叉子!"); 
 ::SetWindowText(imageinfo->edit,(LPCTSTR)temp);
 Sleep(1000);
 caneat=FALSE; 
 } 
    
 }
 //::SetWindowText(imageinfo->edit,"1");
   
 return TRUE;
}       線程處理函數裡面主要的就是一個臨界區變量g_cls,其是MFC提供的一個同步互斥類CCriticalSection的一個對象,其管理控制線程對共享資源的訪問,MFC總共提供了四種同步互斥類可以用以處理共享變量的問題(CMutex,CSemaphore,CEvent,CCriticalSection,各有區別,具體可以去網上查找相關資料或者看MSDN)。

        臨界區對象要和共享變量一起放在MFC框架代碼的外面       


[cpp] //全局變量  
CCriticalSection g_cls;//臨界區對象  
int chopsticks[6]; 
//全局變量
CCriticalSection g_cls;//臨界區對象
int chopsticks[6];        在g_cls.Lock()和g_cls.Unlock()之間的變量將限制為同一時刻只能讓一位線程訪問。

 二、演示程序的圖形繪制部分

         這部分主要就是計算坐標有點麻煩,繪圖用CDC自帶的一些繪圖函數繪制而成。

[cpp] void CPhilosophy_EatingDlg::OnPaint()  

    if (IsIconic()) 
    { 
        CPaintDC dc(this); // device context for painting  
 
        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); 
 
        // Center icon in client rectangle  
        int cxIcon = GetSystemMetrics(SM_CXICON); 
        int cyIcon = GetSystemMetrics(SM_CYICON); 
        CRect rect; 
        GetClientRect(&rect); 
        int x = (rect.Width() - cxIcon + 1) / 2; 
        int y = (rect.Height() - cyIcon + 1) / 2; 
 
        // Draw the icon  
        dc.DrawIcon(x, y, m_hIcon); 
    } 
    else 
    { 
        CDialog::OnPaint(); 
    } 
     
    //獲得顯示框的大小rect  
    CRect rect; 
    GetDlgItem(IDC_STATIC_TABLE)->GetWindowRect(&rect); 
    ScreenToClient(&rect); 
     /***************************************************************/ 
    //計算這個rect的中心坐標,求出桌子中心的坐標,以及其外接矩形的坐標//  
     /***************************************************************/ 
     
    //1.計算桌子中心的坐標  
     
    pt_table.x=(rect.right+rect.left)/2; 
    pt_table.y=(rect.bottom+rect.top)/2; 
     
    //2.計算桌子外接矩形的大小  
     
    radius_table=(rect.right-rect.left)/3;//我們去顯示框長度的1/3做為桌子的半徑  
     
    rect.left=pt_table.x-radius_table; 
    rect.right=pt_table.x+radius_table; 
    rect.top=pt_table.y-radius_table; 
    rect.bottom=pt_table.y+radius_table; 
      
    CDC *pDC=GetDC();    
    pDC->Ellipse(rect);   
 
    //計算每個椅子的中心坐標  
    double pi=3.1415926535; 
    double sin_temp,cos_temp; 
    double x=pi/3; 
    for (int i=0;i<6;i++)    {    
         
        sin_temp=sin(i*x); 
        cos_temp=cos(i*x); 
        pt_chair[i].x=pt_table.x-(3*radius_table)/2.0*sin_temp; 
        pt_chair[i].y=pt_table.y-(3*radius_table)/2.0*cos_temp; 
    } 
    radius_chair=radius_table/4.0; 
     
    //計算每個椅子的外接矩形,並畫出椅子  
    for (i=0;i<6;i++) 
    { 
        rect.left=pt_chair[i].x-radius_chair; 
        rect.right=pt_chair[i].x+radius_chair; 
        rect.top=pt_chair[i].y-radius_chair; 
        rect.bottom=pt_chair[i].y+radius_chair; 
        pDC->Ellipse(rect); 
        CString num; 
        num.Format("%d",i+1); 
        pDC->DrawText(num,&rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);//單行居中  
    } 
     
     
    //計算叉子的起始坐標和終止  
    for (i=0;i<6;i++) 
    {    
         
 
        pt_chopstick_start[i].x=pt_table.x-radius_table*sin(i*x+pi/6); 
        pt_chopstick_start[i].y=pt_table.y-radius_table*cos(i*x+pi/6); 
 
        pt_chopstick_end[i].x=pt_table.x-25*sin(i*x+pi/6); 
        pt_chopstick_end[i].y=pt_table.y-25*cos(i*x+pi/6); 
 
    } 
     
 
 
 
    //畫筷子  
    CPen pen(PS_SOLID,4,RGB(0,0,0)); 
    pDC->SelectObject(&pen); 
    for (i=0;i<6;i++) 
    { 
        pDC->MoveTo(pt_chopstick_start[i]); 
        pDC->LineTo(pt_chopstick_end[i]); 
    }   

void CPhilosophy_EatingDlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // device context for painting

  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  // Center icon in client rectangle
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  // Draw the icon
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CDialog::OnPaint();
 }
 
 //獲得顯示框的大小rect
 CRect rect;
 GetDlgItem(IDC_STATIC_TABLE)->GetWindowRect(&rect);
 ScreenToClient(&rect);
     /***************************************************************/
 //計算這個rect的中心坐標,求出桌子中心的坐標,以及其外接矩形的坐標//
  /***************************************************************/
   
 //1.計算桌子中心的坐標
 
 pt_table.x=(rect.right+rect.left)/2;
 pt_table.y=(rect.bottom+rect.top)/2;
   
 //2.計算桌子外接矩形的大小
   
 radius_table=(rect.right-rect.left)/3;//我們去顯示框長度的1/3做為桌子的半徑
 
 rect.left=pt_table.x-radius_table;
 rect.right=pt_table.x+radius_table;
 rect.top=pt_table.y-radius_table;
 rect.bottom=pt_table.y+radius_table;
    
    CDC *pDC=GetDC(); 
 pDC->Ellipse(rect); 

 //計算每個椅子的中心坐標
 double pi=3.1415926535;
 double sin_temp,cos_temp;
 double x=pi/3;
 for (int i=0;i<6;i++) {  
  
  sin_temp=sin(i*x);
  cos_temp=cos(i*x);
        pt_chair[i].x=pt_table.x-(3*radius_table)/2.0*sin_temp;
  pt_chair[i].y=pt_table.y-(3*radius_table)/2.0*cos_temp;
 }
 radius_chair=radius_table/4.0;
   
    //計算每個椅子的外接矩形,並畫出椅子
 for (i=0;i<6;i++)
 {
  rect.left=pt_chair[i].x-radius_chair;
  rect.right=pt_chair[i].x+radius_chair;
  rect.top=pt_chair[i].y-radius_chair;
  rect.bottom=pt_chair[i].y+radius_chair;
  pDC->Ellipse(rect);
  CString num;
  num.Format("%d",i+1);
  pDC->DrawText(num,&rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);//單行居中
 }
   
   
 //計算叉子的起始坐標和終止
 for (i=0;i<6;i++)
    {  
       

  pt_chopstick_start[i].x=pt_table.x-radius_table*sin(i*x+pi/6);
  pt_chopstick_start[i].y=pt_table.y-radius_table*cos(i*x+pi/6);

  pt_chopstick_end[i].x=pt_table.x-25*sin(i*x+pi/6);
  pt_chopstick_end[i].y=pt_table.y-25*cos(i*x+pi/6);

    }
   

 

    //畫筷子
 CPen pen(PS_SOLID,4,RGB(0,0,0));
 pDC->SelectObject(&pen);
    for (i=0;i<6;i++)
    {
        pDC->MoveTo(pt_chopstick_start[i]);
  pDC->LineTo(pt_chopstick_end[i]);
    } 
}
              上述代碼中的相關變量在CPhilosophy_EatingDlg中聲明:

       

[cpp] class CPhilosophy_EatingDlg : public CDialog 

// Construction  
public: 
    CPhilosophy_EatingDlg(CWnd* pParent = NULL);    // standard constructor  
public: 
    ImageInfo imageinfo[6]; 
    CWinThread *pthread[6]; 
    CPoint pt_table; 
    CPoint pt_chair[6]; 
    double radius_table; 
    double radius_chair; 
    CPoint pt_chopstick_start[6]; 
    CPoint pt_chopstick_end[6]; 
    //CPoint pt_chopstick_start[6];  
 
    BOOL m_continue; 
class CPhilosophy_EatingDlg : public CDialog
{
// Construction
public:
 CPhilosophy_EatingDlg(CWnd* pParent = NULL); // standard constructor
public:
 ImageInfo imageinfo[6];
 CWinThread *pthread[6];
 CPoint pt_table;
 CPoint pt_chair[6];
 double radius_table;
 double radius_chair;
 CPoint pt_chopstick_start[6];
 CPoint pt_chopstick_end[6];
 //CPoint pt_chopstick_start[6];

 BOOL m_continue;[cpp] </pre>          進程運行時圖形變化的繪制已經在進程函數Eat中了,大家可以自己看下,不是很復雜。  <p></p><p><strong>   三、兩個按鈕的代碼</strong></p><p><strong>           開始和停止按鈕的代碼,沒什麼內容,我把代碼貼下,大家可以參考~</strong></p><p><strong></strong></p><pre name="code" class="cpp">void CPhilosophy_EatingDlg::OnButtonStart()  

    // TODO: Add your control notification handler code here  
    for (int m=0;m<6;m++) 
    { 
        chopsticks[m]=1; 
    } 
 
     
    for(int i=0;i<6;i++) 
    {    
        switch(i) 
        { 
        case 0: 
             imageinfo[i].edit=GetDlgItem(IDC_EDIT_STATE1)->m_hWnd; 
             break; 
        case 1: 
            imageinfo[i].edit=GetDlgItem(IDC_EDIT_STATE2)->m_hWnd; 
            break; 
        case 2: 
            imageinfo[i].edit=GetDlgItem(IDC_EDIT_STATE3)->m_hWnd; 
            break; 
        case 3: 
            imageinfo[i].edit=GetDlgItem(IDC_EDIT_STATE4)->m_hWnd; 
            break; 
        case 4: 
            imageinfo[i].edit=GetDlgItem(IDC_EDIT_STATE5)->m_hWnd; 
            break; 
        case 5: 
            imageinfo[i].edit=GetDlgItem(IDC_EDIT_STATE6)->m_hWnd; 
            break; 
        default: 
            break; 
        } 
        imageinfo[i].pWnd=this; 
         
        imageinfo[i].index=i; 
        imageinfo[i].pt_chair=pt_chair[i]; 
        imageinfo[i].pt_chopstick_middle[0]=pt_chopstick_start[i]; 
        imageinfo[i].pt_chopstick_middle[1]=pt_chopstick_start[(i+5)%6]; 
        imageinfo[i].radius_chair=radius_chair; 
        imageinfo[i].radius_table=radius_table; 
        imageinfo[i].pt_chopstick_end[0]=pt_chopstick_end[i]; 
        imageinfo[i].pt_chopstick_end[1]=pt_chopstick_end[(i+5)%6]; 
        pthread[i]=AfxBeginThread(Eat,&imageinfo[i]); 
    } 
 
 
     

 
void CPhilosophy_EatingDlg::OnButtonStop()  

    // TODO: Add your control notification handler code here      
    if (FALSE==m_continue) 
    { 
        GetDlgItem(IDC_BUTTON_STOP)->SetWindowText("繼續演示"); 
        for (int i=0;i<6;i++) 
        { 
        pthread[i]->SuspendThread(); 
        } 
        m_continue=TRUE; 
        return; 
    } 
    else 
    {    
        GetDlgItem(IDC_BUTTON_STOP)->SetWindowText("暫停演示"); 
        for (int i=0;i<6;i++) 
        { 
            pthread[i]->ResumeThread(); 
        } 
        m_continue=FALSE; 
        return; 
    } 
     
 

</pre>          進程運行時圖形變化的繪制已經在進程函數Eat中了,大家可以自己看下,不是很復雜。  <p></p><p><strong>   三、兩個按鈕的代碼</strong></p><p><strong>           開始和停止按鈕的代碼,沒什麼內容,我把代碼貼下,大家可以參考~</strong></p><p><strong></strong></p><pre name="code" class="cpp">void CPhilosophy_EatingDlg::OnButtonStart()
{
 // TODO: Add your control notification handler code here
 for (int m=0;m<6;m++)
 {
  chopsticks[m]=1;
 }

   
 for(int i=0;i<6;i++)
 {  
  switch(i)
  {
  case 0:
    imageinfo[i].edit=GetDlgItem(IDC_EDIT_STATE1)->m_hWnd;
    break;
  case 1:
   imageinfo[i].edit=GetDlgItem(IDC_EDIT_STATE2)->m_hWnd;
   break;
  case 2:
   imageinfo[i].edit=GetDlgItem(IDC_EDIT_STATE3)->m_hWnd;
   break;
  case 3:
   imageinfo[i].edit=GetDlgItem(IDC_EDIT_STATE4)->m_hWnd;
   break;
  case 4:
   imageinfo[i].edit=GetDlgItem(IDC_EDIT_STATE5)->m_hWnd;
   break;
  case 5:
            imageinfo[i].edit=GetDlgItem(IDC_EDIT_STATE6)->m_hWnd;
   break;
  default:
   break;
  }
  imageinfo[i].pWnd=this;
       
  imageinfo[i].index=i;
  imageinfo[i].pt_chair=pt_chair[i];
  imageinfo[i].pt_chopstick_middle[0]=pt_chopstick_start[i];
  imageinfo[i].pt_chopstick_middle[1]=pt_chopstick_start[(i+5)%6];
  imageinfo[i].radius_chair=radius_chair;
  imageinfo[i].radius_table=radius_table;
  imageinfo[i].pt_chopstick_end[0]=pt_chopstick_end[i];
  imageinfo[i].pt_chopstick_end[1]=pt_chopstick_end[(i+5)%6];
  pthread[i]=AfxBeginThread(Eat,&imageinfo[i]);
    }


 
}

void CPhilosophy_EatingDlg::OnButtonStop()
{
 // TODO: Add your control notification handler code here 
 if (FALSE==m_continue)
 {
  GetDlgItem(IDC_BUTTON_STOP)->SetWindowText("繼續演示");
  for (int i=0;i<6;i++)
  {
  pthread[i]->SuspendThread();
  }
  m_continue=TRUE;
  return;
 }
 else
 {  
  GetDlgItem(IDC_BUTTON_STOP)->SetWindowText("暫停演示");
  for (int i=0;i<6;i++)
  {
   pthread[i]->ResumeThread();
  }
  m_continue=FALSE;
  return;
 }
 

}
            主要的就是這麼多了,大家結合著代碼看看,有不明白的歡迎和我交流~~~

            貼幾個程序運行的圖片

 \


 

 源代碼下載:http://www.BkJia.com/uploadfile/2012/0217/20120217094104830.rar

           

 我把代碼貼出來是希望能幫助一些人,如果有不明白的可以和我討論,希望不要將本程序直接拷貝,謝了!

 

 

        

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