请编写一个程序,该程序能够将从键盘输入的普通字符以“宋体,红色,默认大小”的形式输出在窗口的客户区,窗口的客户区具有象稿纸一样的形式,即具有象下图一样的线条(颜色为纯蓝色),输入的字符都在线条之间显示,该程序每隔30秒钟自动将所有的输入清空,输入的字符个数最多为10000个,另外,该程序运行时,限制鼠标的运动情况,只要进入窗口的客户区,就只能停留在某个特定位置其他功能都差不多了,只是在输出时不能换行输出的,大家爱帮忙看看啊 源程序如下:
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>long WINAPI WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam);
BOOL InitWindowsClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hInstance,int nCmdShow);int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int nCmdShow)
{
    MSG           Message;
    if(!InitWindowsClass(hInstance))
        return FALSE;
    if(!InitInstance (hInstance,nCmdShow))
        return FALSE;
     while (GetMessage (&Message, NULL, 0, 0))            //消息循环
    {
            TranslateMessage (&Message) ;
            DispatchMessage (&Message) ;
    }    return Message.wParam ;                               //程序终止时将信息返回系统
}
long WINAPI WndProc(HWND hwnd,UINT iMessage,UINT wParam,LONG lParam)
{
    const int BufSize = 10000;         //设置存放字符的缓冲区大小
    static char cCharBuf[BufSize];  //  设置静态字符数组,存放输入的字符
    static int nNumChar = 0;       //现有字符个数
    static int nArrayPos = 0;      //字符的位置
    static int nLnHeight;
    static int nCharWidth;
    int i ,a;
    POINT lt,rb;
    RECT rect;
    int x,y;    // 鼠标位置
    int X = 0,Y = 20;
    HDC hdc;
    HFONT h;              //定义字体句柄
    HPEN hP ,hPenOld;             //定义画笔句柄
    PAINTSTRUCT ps;
    TEXTMETRIC tm;        //定义一个TEXTMETRIC结构,用以记录字体信息
    GetClientRect(hwnd,&rect);
    
    switch(iMessage)     // 处理消息
    {
        case WM_CHAR:
            {
                if(nNumChar >= BufSize)
                {
                    MessageBox(hwnd,"以输入10000个字符,不能再输入字符了",NULL,MB_OK);
                    break;
                }
                for(x = nNumChar;x > nArrayPos;x = x -1)
                    cCharBuf[x] = cCharBuf[x-1];
                cCharBuf[nArrayPos] = (unsigned char )wParam;
                nArrayPos = nArrayPos + 1;
                nNumChar = nNumChar + 1;
                InvalidateRect(hwnd,NULL,TRUE);
            }
            break;        case WM_CREATE:
            {
                hdc = GetDC(hwnd);
                h = CreateFont                    //创建字体
                (
                0,
                0,
                0,
                0,
                400,
                0,
                1,
                0,
                GB2312_CHARSET,
                OUT_DEFAULT_PRECIS,
                CLIP_DEFAULT_PRECIS,
                DEFAULT_QUALITY,
                DEFAULT_PITCH|FF_DONTCARE,
                "宋体"
                );
                SelectObject(hdc,h);   //选入字体
            GetTextMetrics(hdc,&tm);  //得到包含字体信息的结构体
            nLnHeight = tm.tmHeight + tm.tmExternalLeading;
            nCharWidth = tm.tmAveCharWidth;
            ReleaseDC(hwnd,hdc);
            }
            break;
        case WM_KEYDOWN:
        {
            switch(wParam)
            {
                  case VK_END:
                      nArrayPos = nNumChar;
                      break;
                  case VK_ESCAPE:
                      PostQuitMessage(0);
                      break;            }
            break;
        }
        case WM_PAINT:
            hP = CreatePen(PS_SOLID,1,RGB(0,250,0));
            hPenOld = (HPEN)SelectObject(hdc,hP);
            hdc = BeginPaint(hwnd,&ps);
            SelectObject(hdc,hP);
            SetTextColor(hdc,RGB(255,0,0));              //设置文本颜色为红色
            TextOut(hdc,nCharWidth,Y,cCharBuf,nNumChar); //输出文本
        //    DrawText(hdc,cCharBuf,nNumChar,&rect,DT_CALCRECT);
            Y = Y + tm.tmHeight+tm.tmExternalLeading;   //计算换行时下一行文本的输出坐标
            X++;
            for( i  = 0;i < 50;i++)
            {
                 a =20;
                 a =(i+1)*a ;
                 MoveToEx(hdc,0,a,NULL);
                 LineTo(hdc,800,a);
            }
            EndPaint(hwnd,&ps);
             DeleteObject(hP);
            break;
        case WM_MOUSEMOVE:                        //如果鼠标进入客户区,则固定在客户区最左上方
                x = LOWORD(lParam);
                y = HIWORD(lParam);
                GetClientRect(hwnd,&rect);
                lt.x = rect.left;
                lt.y = rect.top;
                rb.x = rect.right;
                rb.y = rect.bottom;
                ClientToScreen(hwnd,&lt);
                ClientToScreen(hwnd,&rb);
                rect.left = lt.x;
                rect.top = lt.y;
                rect.right = rb.x;
                rect.bottom = rb.y;
                if(x >= lt.x&&y >= lt.y&&x <= rb.x&&y <=rb.y)
                {
                    SetCursorPos(lt.x,lt.y);
                }
            break;
        case WM_TIMER:
        case WM_DESTROY:
            PostQuitMessage(0);
            KillTimer(hwnd,1);
            break;
        default:
            return DefWindowProc(hwnd,iMessage,wParam,lParam);
    }
    return 0;
}BOOL InitInstance(HINSTANCE hInstance,int nCmdShow)         //初始化窗口
{
    HWND hwnd ;
    hwnd = CreateWindow ( "TextOut",          //窗口类名
                            "E06620334",             //窗口实例的标题
                          WS_OVERLAPPEDWINDOW,
                           0,            //窗口左上角图标
                           0,
                           600,
                           600,             //窗口的宽和高
                           NULL,                      //窗口无父菜单
                           NULL,                      //窗口无主菜单
                            hInstance,                //创建此窗口应用程序的当前句柄
                            NULL                       //不使用该值
                            ) ;
    if(!hwnd)
        return FALSE;
    ShowWindow (hwnd, nCmdShow) ;                    //显示窗口
    UpdateWindow (hwnd) ;    SetTimer(hwnd,1,30000,NULL);
    return TRUE;
    
}BOOL  InitWindowsClass(HINSTANCE hInstance)        //定义窗口类
{
    WNDCLASS      wndclass;
    wndclass.cbClsExtra   = 0 ;                            //窗口类无扩展
    wndclass.cbWndExtra   = 0 ;                            //窗口实例无扩展
    wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ; //窗口背景色为白色
    wndclass.hCursor      = LoadCursor (NULL, IDC_ARROW) ;  //窗口采用箭头光标
    wndclass.hIcon = LoadIcon (hInstance, IDI_APPLICATION) ;  //窗口的最小化图标为默认图标
    wndclass.hInstance    = hInstance ;                   //当前实例句柄
    wndclass.lpfnWndProc= WndProc ;                        //窗口处理函数为WndProc
    wndclass.lpszClassName="TextOut";
    wndclass.lpszMenuName  = NULL ;                        //窗口中无菜单
    wndclass.style        = CS_HREDRAW | CS_VREDRAW ;      //窗口类型为默认类型
    return RegisterClass(&wndclass);
}

解决方案 »

  1.   

    TextOut只能输出一行;多行的话自己分行来绘制。
      

  2.   

    nLnHeight = tm.tmHeight + tm.tmExternalLeading;這一句,判斷字體高度,用這個確定下一行
      

  3.   

    那个,谁能帮忙实现下么,我试了很久都不行的,刚学API的,呵呵,谢谢了
      

  4.   

    没人帮啊,为什么 TextOut(hdc,nCharWidth,Y,cCharBuf,nNumChar); //输出文本 
     然后改变Y的值还是只在第一行输出呢 
      

  5.   

    CreateWindow 创建出来的窗口对象不支持多行,
    用CreateWindowEx函数
      

  6.   

    刚用了那个函数,为什么用这样的代码还是只在第一行输出呢
     case WM_PAINT: 
    ......
    TextOut(hdc,nCharWidth,Y,cCharBuf,nNumChar); 
    Y +=20;
      

  7.   

    怎么用TextOut输出换行呢?
    以上答案都不好!
    其实最简单的办法就是
    使用 CDC::DrawText
    给个例子,OnDraw 这里
    pDC->DrawText( m_szMsg,m_szMsg.GetLength(),CRect(75,55,300,100),DT_WORDBREAK|DT_NOCLIP);
      

  8.   

    怎么用TextOut输出换行呢?
    以上答案都不好!
    其实最简单的办法就是
    使用 CDC::DrawText
    给个例子,OnDraw 这里
    pDC->DrawText( m_szMsg,m_szMsg.GetLength(),CRect(75,55,300,100),DT_WORDBREAK|DT_NOCLIP);
      

  9.   

    在多用一个textout改下纵坐标不就行了么。