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