zoukankan      html  css  js  c++  java
  • 文本和字体

    解题:
    一、在用户区的某个坐标位置打印一行字符串
    二、在用户区的中心位置打印一行字符串,位置始终不变
    三、读取一个纯文本文件(FILE)内容到用户区中,(保持格式)


    BeginPaint(HWND hWnd,LPPAINTSTRUCT lpPaint);:获取HDC句柄,其中LPPAINTSTRUCT lpPaint,是一个指向PAINTSTRUCT的指针。

    PAINTSTRUCT结构:特别之处在于,它记录需要重绘的矩形区域(比如被遮盖的无效区域),在接收WM_PAINT消息时,重绘这个区域。

    关于重绘的几个问题,第一,不是所有区域都需要重绘(比如标题栏,工具条等等),只是无效区域需要重绘。windows又如何知道重绘区域的大小呢?在BeginPaint()函数中,将无效区域的大小写在PAINTSTRUCT结构中。

    typedef struct tagPAINTSTRUCT {
        HDC         hdc;/*标识显示设备对象的句柄*/
        BOOL        fErase;/*若为非零,说明用户背景已被重画,否则未被重画*/
        RECT        rcPaint;/*指定要求重画的矩形区域的左上角和右下角的坐标*/
        BOOL        fRestore;
        BOOL        fIncUpdate;
        BYTE        rgbReserved[32];
    } PAINTSTRUCT, *PPAINTSTRUCT, *NPPAINTSTRUCT, *LPPAINTSTRUCT;

    InvalidateRect()函数强制某个区域为无效区域。

    InvalidateRect(
        HWND hWnd ,
        CONST RECT *lpRect, /*无效区域坐标,如果为NULL,则整个用户区无效*/
        BOOL bErase);/*是否擦除RECT所标示的区域内容*/

    TextOut函数(文本输出):

    BOOL TextOut
    (
        HDC hdc;
        int x;/*串起始点的逻辑x坐标值*/
        int y;/*串起始点的逻辑y坐标值*/
        LPSTR lpString;/*指向字符串的指针*/
        int nCount)/*绘制的字符个数*/

    EndPaint(),两个作用:第一,返回借用的设备对象,第二,清除消息队列中的WM_PAINT消息。

    具体的在用户区中显示文本的几种特别方法:
    (1)要求文本始终居于用户区的正中间

    //DrawText()函数用于格式化显示文本

    这种方法的一个缺点在于,只要产生WM_PAINT消息时,就需要计算用户区域的大小,但实际情况下用户区域的大小很少去动,这种计算显的多余。

    改进:在windows窗口的大小发生改变时,会发送WM_SIZE(一个知识点)消息,直接进入消息队列,其中,在消息的附加参数lParam中,低位表示最后的宽度,高位表示最后的高度,通过对lParam的分离,得到窗口最后的宽高。然后借用这个矩形坐标显示文本,也能达成目的。

    case WM_SIZE:
             rect.right=LOWORD(lParam);/*分离宽度*/
             rect.bottom=HIWORD(lParam);/*分离高度*/
             break;

     关于字体

    字体的信息图:

    BOOL GetTextMetrics(HDC hdc,LPTEXTMETRICS lpMetric);
    /*得到设备对象使用字体的尺寸,并存入到TEXTMETRICS的变量中*/

    /*--------------完整代码-----------------*/

    //-------------------程序包含的内容如下:---------------------//
    
    //创建窗口时产生的第一条消息:WM_CREATE;
    //获取设备DC:BeginPaint(),EndPaint(),InvalidateRect()..
    //获取用户区的区域大小..GetClientRect()
    //自定义用户消息,SendMessage()的使用;
    
    //窗口改变时,产生的WM_SIZE消息
    //如何检测鼠标双键按下的消息
    //文本输出:TextOut(),格式化输出:DrawText()
    
    //3个小例子
    //一、在用户区的某个坐标位置打印字符串
    //二、始终在用户区区域的中心位置显示某个字符串
    //三、读取一个文本文件,并在用户区显示
    
    //---------------------------------------------------------------//
    
    #include "stdio.h"
    #include <windows.h>
    
    #define WM_MYMSG WM_USER+100 /*自定义消息的ID*/
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;/*回调函数声明*/
    
    int _stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
    {
         static char szAppName[] = TEXT ("HelloWin") ;
         HWND         hwnd ;                //窗口句柄
         MSG          msg ;                 //消息结构
         WNDCLASS     wndclass ;            //窗口类结构
         wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
         wndclass.lpfnWndProc   = WndProc ;
         wndclass.cbClsExtra    = 0 ;
         wndclass.cbWndExtra    = 0 ;
         wndclass.hInstance     = hInstance ;
         wndclass.hIcon         = LoadIcon (NULL, IDI_WARNING) ;//加载图标
         wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;    //加载鼠标指针
         wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;//获取一个图形对象
         wndclass.lpszMenuName  = NULL ;
         wndclass.lpszClassName = szAppName ;
    
         RegisterClass (&wndclass);//注册窗口(类)
         
         hwnd = CreateWindow (szAppName,//创建窗口                  
                              TEXT ("一个简单的Win32程序"), 
                              WS_OVERLAPPEDWINDOW,        
                              CW_USEDEFAULT,              
                              CW_USEDEFAULT,              
                              CW_USEDEFAULT,             
                              CW_USEDEFAULT,              
                              NULL,                      
                              NULL,                       
                              hInstance,                  
                              NULL) ;                     
         /*在此处发出第一个消息WM_CREATE*/
         ShowWindow (hwnd, iCmdShow) ;          //显示窗口     
         UpdateWindow (hwnd) ;                  //窗口刷新
         /*在此处发出第一个WM_PAINT消息*/
         
         while (GetMessage (&msg, NULL, 0, 0))            //从消息队列中获取消息
         {
              TranslateMessage (&msg) ;                   //转换某些键盘消息
              DispatchMessage (&msg) ;                    //将消息发送给窗口过程
         }
         return msg.wParam ;
    }
    
    LRESULT  CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {   
        HDC hdc;
        const static char msg[]="hello,welcome to Windows!";
        static RECT rect;/*静态矩形区域*/
        PAINTSTRUCT ps;
        static int xChar,yChar;
        char szBuffer[256];
        int line=0;
        TEXTMETRIC tm;//字体尺寸信息结构体
        FILE *fp;
        
         switch(message)
         {   
         case WM_CREATE://窗口创建的第一条消息:WM_CREATE         
                /*hdc=GetDC(hwnd);
    
                //GetDC()只能用于非WM_PAINT消息,原因是即使释放DC之后,并不能清除WM_PAINT消息
    
                GetTextMetrics(hdc,&tm);//获取字体的相关信息,并存放在变量tm中;
                xChar=tm.tmAveCharWidth;//字符的平均宽度
                yChar=tm.tmHeight+tm.tmExternalLeading;/*高度=字符高度+默认行距,此高度作为打印行的间距
                ReleaseDC(hwnd,hdc);*/
             break;
    
         case WM_SIZE:/*窗口大小接收到的消息*/
             rect.right=LOWORD(lParam);//分离宽度
             rect.bottom=HIWORD(lParam);//分离高度
             
             break;
    
         case WM_PAINT:   
             //InvalidateRect(hwnd,NULL,0);/*强制整个用户区为无效区域*/
             hdc=BeginPaint(hwnd,&ps);
             //TextOut(hdc,10,20,msg,strlen(msg));
             GetClientRect(hwnd,&rect);//获取用户区的区域坐标,放在矩形变量rect中;
             DrawText(hdc,msg,-1,&rect,DT_SINGLELINE | DT_CENTER | DT_VCENTER);
    
                /*if((fp=fopen("disp.txt","r"))==NULL) //需要在当前目录下建立一个disp.c文件
                {
                    TextOut(hdc,0,0,"打开错误!",8);//一个汉字两字节//
                    break;
                }
                else
            {
                while(!feof(fp))
                {    
                    int i=0;
                    char ch;
                    while((ch=fgetc(fp))!='
    ' && ch!=EOF)
                    szBuffer[i++]=char(ch);
                    TextOut(hdc,xChar,line*yChar,szBuffer,i);//打印文件,每一行控制间距//
                    line++;
                }
                fclose(fp);
            }*/
             EndPaint(hwnd,&ps);//EndPaint()可以清除消息队列中的WM_PAINT消息
              break;
    
         case WM_MYMSG:/*自定义消息*/
            MessageBox(NULL,"用户自定义消息","自定义",MB_OK);
            break;
    
         case WM_LBUTTONDOWN:/*鼠标左键按下后发送自定义消息WM_MYMSG*/
             SendMessage(hwnd,WM_MYMSG,wParam,lParam);
             break;
    
         //case WM_LBUTTONDOWN:/*双键检测*/
             //if(wParam & MK_RBUTTON)
             //SendMessage(hwnd,WM_MYMSG,wParam,lParam);
             //break;
    
         case WM_DESTROY:
              PostQuitMessage (0) ; //在消息队列中插入一条“退出”消息
             break;
         }
         return DefWindowProc (hwnd, message, wParam, lParam);//执行默认的消息处理
    }
    View Code

    GetDC()和BeginPaint()的区别

    GetDC()通过ReleaseDC()释放后,但不能清除WM_PAINT消息,所以适合在非WM_PAINT消息中创建,EndPaint()可以清除WM_PAINT消息。

  • 相关阅读:
    Channel
    MemCache
    算法笔记_124:密码脱落(Java)
    算法笔记_123:蓝桥杯第七届省赛(Java语言B组部分习题)试题解答
    算法笔记_122:蓝桥杯第七届省赛(Java语言A组)试题解答
    算法笔记_121:蓝桥杯第六届省赛(Java语言C组部分习题)试题解答
    算法笔记_120:蓝桥杯第六届省赛(Java语言B组部分习题)试题解答
    算法笔记_119:蓝桥杯第六届省赛(Java语言A组)试题解答
    算法笔记_118:算法集训之结果填空题集二(Java)
    算法笔记_117:算法集训之结果填空题集一(Java)
  • 原文地址:https://www.cnblogs.com/tinaluo/p/5388666.html
Copyright © 2011-2022 走看看