图形学留的作业,汉喏塔演示用递归实现想在递归调用中,程序可以接受ESC并退出代码如下,递归开始后,根本不响应键盘按下的消息第一次用MFC,一点也不熟悉,请大家多多指教/////////////////////////////////// hntView.cpp : implementation of the CHntView class
//#include "stdafx.h"
#include "hnt.h"#include "hntDoc.h"
#include "hntView.h"#ifdef _DEBUG
#define new DEBUG_NEW  
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CHntViewIMPLEMENT_DYNCREATE(CHntView, CView)BEGIN_MESSAGE_MAP(CHntView, CView)
//{{AFX_MSG_MAP(CHntView)
ON_WM_KEYDOWN()
ON_WM_KEYUP()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CHntView construction/destructionCHntView::CHntView()
{
// TODO: add construction code here
total_blocks=0;
current_block=0;
OldnChar=0;
quit=0;
}CHntView::~CHntView()
{
}BOOL CHntView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
//  the CREATESTRUCT cs return CView::PreCreateWindow(cs);
}/////////////////////////////////////////////////////////////////////////////
// CHntView drawing
void CHntView::move (int n,int a,int b,int c)
{
if (n>0)
{
move(n-1,a,c,b);
current_block=n;
moveone(a,b);
move(n-1,c,b,a);
}
}void CHntView::moveone (int m,int p)
{
// CString s;
// s.Format ("%d",p); 
// MessageBox(s,NULL,0);
OnKeyDown(quit,0,0);
CClientDC dc(this);
         dc.SetROP2(R2_NOT);
int i,j,M,P;
switch (m)
{
case 110:
M=0;break;
case 300:  
M=1;break;
case 490:
M=2;break;
};
switch (p)
{
case 110: 
P=0;break;
case 300:
P=1;break;
case 490:
P=2;break;
};
Sleep(150);
j=zhuzigaodu[M];
i=300-(15 * j);
//m-70::第total_blocks个柱子横坐标
//total_blocks-current_block
//计算当前需要移动的块,横坐标
dc.Rectangle(m-70+(total_blocks-current_block)*8,i,m+70-(total_blocks-current_block)*8,i+15);
dc.Rectangle(m-70+(total_blocks-current_block)*8,100,m+70-(total_blocks-current_block)*8,115);
Sleep(80);
dc.Rectangle(m-70+(total_blocks-current_block)*8,100,m+70-(total_blocks-current_block)*8,115);
zhuzigaodu[M]--;
j=zhuzigaodu[P];
i=300-(15 * j);
dc.Rectangle(p-70+(total_blocks-current_block)*8,100,p+70-(total_blocks-current_block)*8,115);
Sleep(80);
dc.Rectangle(p-70+(total_blocks-current_block)*8,100,p+70-(total_blocks-current_block)*8,115);
dc.Rectangle(p-70+(total_blocks-current_block)*8,i-15,p+70-(total_blocks-current_block)*8,i);
zhuzigaodu[P]++;
}void CHntView::OnDraw(CDC* pDC)

CHntDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CPen Pen; CPen *OldPen;
Pen.CreatePen(PS_SOLID,2,RGB(128,128,128)); 
OldPen=pDC->SelectObject(&Pen);
pDC->TextOut (190,10,"^_^计算机图形学作业一   汉喏塔演示^_^");
pDC->TextOut (260,28,"a-->b  using c");
pDC->TextOut (220,45,"请输入汉喏塔所含块数 '1-9'");
pDC->TextOut (108,301,"a");
pDC->TextOut (298,301,"b");
pDC->TextOut (488,301,"c");
pDC->MoveTo (35,300);
pDC->LineTo (185,300);
pDC->MoveTo (225,300);
pDC->LineTo (375,300);   
pDC->MoveTo (415,300); 
pDC->LineTo (565,300);
pDC->MoveTo (110,90);
pDC->LineTo (110,300);
pDC->MoveTo (300,90); 
pDC->LineTo (300,300);
pDC->MoveTo (490,90);
pDC->LineTo (490,300);
//DoEvent
    pDC->SelectObject(OldPen);
}/////////////////////////////////////////////////////////////////////////////
// CHntView printingBOOL CHntView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}void CHntView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}void CHntView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}/////////////////////////////////////////////////////////////////////////////
// CHntView diagnostics#ifdef _DEBUG
void CHntView::AssertValid() const
{
CView::AssertValid();
}void CHntView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}CHntDoc* CHntView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CHntDoc)));
return (CHntDoc*)m_pDocument;
}
#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////
// CHntView message handlersvoid CHntView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
// TODO: Add your message handler code here and/or call default
int n(0);//有几个块;
int m(0);//纪录nChar;
CClientDC dc(this);
dc.SetROP2(R2_NOT);
if (nChar==13)//enter
{
if (total_blocks==0)
MessageBox("请输入希望的块数",NULL,0);
else
{
dc.TextOut(180,65,"正在演示汉喏塔移动过程   耐心等待哦~~      ");
move(total_blocks,110,300,490); 
MessageBox("计算机2000级7班\n\n郭玉海\n\n200005237",NULL,0);
exit(1);
}

else
{
if ((nChar>=97 && nChar<=105) || (nChar>=49 && nChar<=57))
{
if (nChar>=97 && nChar<=105)
nChar=nChar-48;
m=nChar;
// dc.TextOut (220,45,"  指定汉喏塔所含块数为        ");
// CString s;
// s.Format ("%d",nChar); 
//     MessageBox(s,NULL,0);
// dc.TextOut (380,45,nChar);
nChar=nChar-48;//画几个块,用户输入几个块
while(nChar!=0)
{
while (OldnChar!=0)
//用户重新绘制块数时,清除上次绘制
{
dc.TextOut (220,45,"  正在取消上次绘制结果.......       ");
--OldnChar;
Sleep(100);
dc.TextOut(175,65,"                                                                ");
dc.Rectangle(40+OldnChar*8,285-OldnChar*15,180-OldnChar*8,300-OldnChar*15);
}
dc.TextOut (220,45,"  指定汉喏塔所含块数为        ");
dc.TextOut (390,45,m);
dc.Rectangle(40+n*8,100,180-n*8,115);
Sleep(80);
dc.Rectangle(40+n*8,100,180-n*8,115);
dc.Rectangle(40+n*8,285-n*15,180-n*8,300-n*15); 
nChar--;
n++;
Sleep(80);
}
dc.TextOut (390,45,n+48);
dc.TextOut(205,65,"按ENTER开始 或者重新制定块数");
// dc.TextOut(175,65,"PRESS ENTER TO START APPLICATION");
for (int i=0;i<3;i++)
zhuzigaodu[i]=0; 
zhuzigaodu[0]=n;
total_blocks=n;
OldnChar=n;
}
}
CView::OnKeyUp(nChar, nRepCnt, nFlags);
}  void CHntView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
// TODO: Add your message handler code here and/or call default
if(nChar==27)
         PostQuitMessage(0);
//为什么不能用?CPU有空闲吧?
//为什么不处理这个消息? CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

解决方案 »

  1.   

    BOOL CView::PreTranslateMessage(MSG* pMsg) 处理试一下
      

  2.   

    Use The API Function:
    SendMessage
      

  3.   

    重载函数 PreTranslateMessage(MSG* pMsg);这是我自己对话框响应的函数
    BOOL CNEDlgShowCityEntry::PreTranslateMessage(MSG* pMsg) 
    {
    // TODO: Add your specialized code here and/or call the base class if (pMsg->message == WM_KEYDOWN)
    {

    int nVirtKey = (int) pMsg->wParam;
    if ( nVirtKey == VK_ESCAPE)
    {  
                           //加入你自己想调用的函数
    }
    }
    return CDialog::PreTranslateMessage(pMsg);
    }
    );
      

  4.   

    谢谢以上个位但是还是不可以给我的感觉是,在调用MOVE这个递归时程序就不再去响应键盘发出的消息了怎么解决那?不光是递归进行中,还有在单一个循环里比如
    //这部分,在初始化刚开始的界面时,按键盘就没有响应
    dc.TextOut (220,45,"  指定汉喏塔所含块数为        ");
    dc.TextOut (390,45,m);
    dc.Rectangle(40+n*8,100,180-n*8,115);
    Sleep(100);
    dc.Rectangle(40+n*8,100,180-n*8,115);
    dc.Rectangle(40+n*8,285-n*15,180-n*8,300-n*15); 
    nChar--;
    n++;
    Sleep(100);
    ///////////////////////////////////////////////////////////////////再次请教各位
      

  5.   

    void CHntView::move (int n,int a,int b,int c)
    {
    if (n>0)
    {
                    MSG Msg;
           while(::PeekMessage(&Msg,NULL,NULL,NULL,PM_REMOVE))
           {
     ::TranslateMessage(&Msg);
     ::DispatchMessage(&Msg);
    }
    move(n-1,a,c,b);
    current_block=n;
    moveone(a,b);
    move(n-1,c,b,a);
    }
    }
      

  6.   

    Cline(营营) 大哥照您的方法做了,但递归开始后我点窗口右上角的关闭按钮,窗口立刻就关闭了可程序仍旧在运行,还能在任务管理器中看到我写程序经验很少,也不很懂MFC,这是第一次用谢谢您的指教,谢谢大家
      

  7.   

    刚看了MSDN  明白Cline的意思了  呵呵void CHntView::move (int n,int a,int b,int c)
    {
    if (n>0)
    {
            MSG Msg;
        while(::PeekMessage(&Msg,NULL,NULL,NULL,PM_REMOVE))
        {
    if (Msg.wParam == VK_ESCAPE || Msg.message ==WM_QUIT)
    exit(0);
     ::TranslateMessage(&Msg);
     ::DispatchMessage(&Msg);
    }
    move(n-1,a,c,b);
    current_block=n;
    moveone(a,b);
    move(n-1,c,b,a);
    }
    }问题已经解决了,按ESC,关闭都能正常退出程序谢谢大家   送分  送分
      

  8.   

    又出问题了    怎么送分?想多送分      为什么不行啊?头一次上CSDN    晕头转向