zoukankan      html  css  js  c++  java
  • 用VC6.0编写Win32程序加载文本文件

    文章结构说明:

    1. 本文是要说明什么
    2. 关键代码解释和说明
    3. 上机实践的工程源码和提示

    一、文章概要

      在VC6.0编译环境用C加载显示多行的文本文件。主要是参考:http://www.bccn.net/Article/kfyy/cjj/jszl/200412/430.html

      重点主要是windows中字体结构信息的学习,以及如何计算字符的宽度高度,如何排列加载的字符和文字完成多行显示。原理也很简单,得到当前设备的字符高度,第一行的起点在(0,0),第二行就是(0,字符高度),第三行就是(0,字符高度*2)等等。然后调用函数在这些位置显示字符即可。

    二、代码说明

     这里解释下WM_CREATE消息处理函数的代码:

    1         case WM_CREATE:
    2             hdc = GetDC(hWnd);//从OS借用设备
    3             GetTextMetrics(hdc, &tm);//获取显示设备上下文
    4             xChar = tm.tmAveCharWidth;//设备的字符平均宽度
    5             yChar = tm.tmHeight + tm.tmExternalLeading;//设备的字符高度
    6             ReleaseDC(hWnd, hdc);//释放设备
    7             break;

    GetDC()函数的MSDN(VC6.0版)解释如下:

    The GetDC function retrieves a handle to a display device context (DC) for the client area of a specified window or for the entire screen. You can use the returned handle in subsequent GDI functions to draw in the DC. 

    即返回一个显示设备上下文句柄。

    GetTextMetrics()函数MSDN:

    The GetTextMetrics function fills the specified buffer with the metrics for the currently selected font. 

    即从第一个参数——hdc显示设备上下文——中获得的一种字体有关的基本信息填入到第二个参数——tm描述字体信息的结构类型TEXTMETRIC变量中去。

    TEXTMETRIC结构:

    结构类型TEXTMETRIC描述了与一种字体有关的基本信息,它的各域所给出的字体大小以逻辑单位表示(关于逻辑单位的介绍参见下一章)。该结构类型包含有许多域,图2-2给出了与字体垂直尺寸有关的五个域的定义。

    图2-1 TEXTMETRIC结构类型中定义垂直尺寸字体的域


      tmInternalLeading的值是允许在一个字符上加上重音号的空隙量,tmExternalLeading的值是字体的设计者推荐的空隙量,在显示多行文本时程序员可以拒绝使用这个空隙量。
      在TEXTMETRIC结构类型中,有两个域用来定义字符的宽度:tmAveCharWidth表示字体字符的平均宽度,tmMaxCharWidth表示字体最宽的字符的宽度。Windows中使用两种类型的字体,一类是固定宽度的字体,固定宽度的字体的每个字符的宽度是一样的,这样tmAveCharWidth和tmMaxCharWidth两值相等;另一类是可变宽度的字体,对于这类字体,每个字符占用的宽度不一样。例如, 字符“w”和“i”的宽度就不同,使用可变宽度的字体可以绘制紧凑的文本。
      可以使用函数GetTextExtent计算出一个特定的文本行的宽度和高度,使用函数GetTextMetrics可以得到字符的有关尺寸

    接着是WM_PAINT的代码:

     1         case WM_PAINT:
     2 //            hdc = BeginPaint(hWnd, &ps);
     3 //            RECT rt;
     4 //            GetClientRect(hWnd, &rect);
     5 //            DrawText(hdc, "xxxx", -1, &rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
     6 //            EndPaint(hWnd, &ps);
     7 //            break;
     8 
     9             hdc = BeginPaint(hWnd, &ps);
    10             line =0;
    11             if((fp=fopen("e:\\xxx.txt","r"))!= NULL)  //此处文件地址要自己修改
    12             {
    13                 while(!feof(fp)) {
    14                     int i = 0;
    15                     char ch;
    16                     while((ch = fgetc(fp)) != '\n' && ch != EOF)    //换行则调用TextOut显示
    17                         szBuffer[i++] = (char)ch;
    18                     TextOut(hdc, xChar, line*yChar, szBuffer, i);   //xChar是每行前面留出xChar宽度的空白,line*yChar是计算该行的纵坐标
    19                     line++;                                         //很有趣的是,可以尝试把xChar换成0,把line*yChar换成0看看效果,会发生覆盖
    20                 }
    21                 fclose(fp);
    22             }
    23             EndPaint(hWnd, &ps);
    24             break;

    三、工程说明

      首先新建一个Hello World的win32 application,然后在主要的cpp中做如下修改:

      1. 加入两个头文件:

        #include <windows.h>
        #include <stdio.h>

      2. 修改WndProc函数:

        WndProc函数中需要加入WM_CREATE消息处理并修改自动生成的WM_PAINT消息处理。

     附:WndProc函数代码,记得要加上两个头文件。

     1 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
     2 {
     3     int wmId, wmEvent;
     4     PAINTSTRUCT ps;
     5     HDC hdc;
     6     TCHAR szHello[MAX_LOADSTRING];
     7     LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
     8 
     9 //声明一些要用到的变量
    10     int line;
    11     TEXTMETRIC tm;
    12     static int xChar, yChar;
    13     char szBuffer[256];
    14     FILE *fp;
    15 
    16     switch (message) 
    17     {
    18         case WM_COMMAND:
    19             wmId    = LOWORD(wParam); 
    20             wmEvent = HIWORD(wParam); 
    21             // Parse the menu selections:
    22             switch (wmId)
    23             {
    24                 case IDM_ABOUT:
    25                    DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
    26                    break;
    27                 case IDM_EXIT:
    28                    DestroyWindow(hWnd);
    29                    break;
    30                 default:
    31                    return DefWindowProc(hWnd, message, wParam, lParam);
    32             }
    33             break;
    34 
    35 //加入创建窗口的消息处理
    36         case WM_CREATE:
    37             hdc = GetDC(hWnd);//从OS借用设备
    38             GetTextMetrics(hdc, &tm);//获取显示设备上下文
    39             xChar = tm.tmAveCharWidth;//设备的字符平均宽度
    40             yChar = tm.tmHeight + tm.tmExternalLeading;//设备的字符高度
    41             ReleaseDC(hWnd, hdc);//释放设备
    42             break;
    43 
    44 //修改自动生成的绘图消息处理
    45         case WM_PAINT:
    46 //            hdc = BeginPaint(hWnd, &ps);
    47 //            RECT rt;
    48 //            GetClientRect(hWnd, &rect);
    49 //            DrawText(hdc, "xxxx", -1, &rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
    50 //            EndPaint(hWnd, &ps);
    51 //            break;
    52 
    53             hdc = BeginPaint(hWnd, &ps);
    54             line =0;
    55             if((fp=fopen("e:\\xxx.txt","r"))!= NULL)  //此处文件地址要自己修改
    56             {
    57                 while(!feof(fp)) {
    58                     int i = 0;
    59                     char ch;
    60                     while((ch = fgetc(fp)) != '\n' && ch != EOF)    //如果该行结束则立即调用TextOut显示该行
    61                         szBuffer[i++] = (char)ch;
    62                     TextOut(hdc, xChar, line*yChar, szBuffer, i);   //xChar是每行前面留出xChar宽度的空白,line*yChar是计算该行的纵坐标
    63                     line++;                                         //很有趣的是,可以尝试把xChar换成0,把line*yChar换成0看看效果
    64                 }
    65                 fclose(fp);
    66             }
    67             EndPaint(hWnd, &ps);
    68             break;
    69         case WM_DESTROY:
    70             PostQuitMessage(0);
    71             break;
    72         default:
    73             return DefWindowProc(hWnd, message, wParam, lParam);
    74    }
    75    return 0;
    76 }

    PS:不知道,上面链接的网站的内容是哪本书上的,如果有读者知道,希望留言告知一下哈,谢啦。本人邮箱:huanqing2010@gmail.com

  • 相关阅读:
    【转】UTF8文件的Unicode签名BOM(Byte Order Mark)问题
    【转】java使用正则表达式去除字符串的html标签
    用UltraEdit转换大小写
    【转】浅谈字节序(Endianness)
    【转】用UltraEdit的正则表达式替换功能来格式化网页源代码
    【转】关于正则表达式匹配任意字符(包括换行符)的写法
    【转】C# 中的 #region 和 #endregion
    网易游戏开发工程师笔试题
    c++笔试题汇总
    恒生电子面试过程纪录
  • 原文地址:https://www.cnblogs.com/muyun/p/2868205.html
Copyright © 2011-2022 走看看