Typer.cpp

04SimpleTyper 工程下。先创建一个 Win32 应用程序工程,再将上节例子中的代码复制过来,然后一步步添加新的功能就可以了。

///
// Typer.cpp文件#include <windows.h>
#include "resource.h"
#include <string>// 窗口函数的函数原形
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR     lpCmdLine,int       nCmdShow)
{char szClassName[] = "MainWClass";WNDCLASSEX wndclass;// 用描述主窗口的参数填充WNDCLASSEX结构wndclass.cbSize = sizeof(wndclass);    // 结构的大小wndclass.style = CS_HREDRAW | CS_VREDRAW;  // 指定如果大小改变就重画wndclass.lpfnWndProc = MainWndProc;  // 窗口函数指针wndclass.cbClsExtra = 0;      // 没有额外的类内存wndclass.cbWndExtra = 0;        // 没有额外的窗口内存wndclass.hInstance = hInstance;        // 实例句柄 wndclass.hIcon = ::LoadIcon(hInstance,(LPSTR)IDI_TYPER);   // 使用自定义图标  wndclass.hCursor = ::LoadCursor(NULL,IDC_ARROW);       // 使用预定义的光标wndclass.hbrBackground =(HBRUSH)(COLOR_3DFACE + 1);    // 使用预定义画刷wndclass.lpszMenuName = (LPSTR)IDR_TYPER;wndclass.lpszClassName = szClassName;  // 窗口类的名称   wndclass.hIconSm = NULL;       // 没有类的小图标// 注册这个窗口类::RegisterClassEx(&wndclass);// 创建主窗口HWND hwnd = ::CreateWindowEx(WS_EX_CLIENTEDGE,    // dwExStyle,扩展样式// 注意,WS_EX_CLIENTEDGE风格指定了这个窗口有一个边框和一个下沉的边缘szClassName,     // lpClassName,类名            "My first Window!",   // lpWindowName,标题       WS_OVERLAPPEDWINDOW,    // dwStyle,窗口风格  CW_USEDEFAULT,      // X,初始 X 坐标     CW_USEDEFAULT,      // Y,初始 Y 坐标     CW_USEDEFAULT,      // nWidth,宽度         CW_USEDEFAULT,      // nHeight,高度            NULL,           // hWndParent,父窗口句柄          NULL,           // hMenu,菜单句柄        hInstance,      // hlnstance,程序实例句柄      NULL);          // lpParam,用户数据          if (hwnd == NULL){::MessageBox(NULL, "创建窗口出错!", "error", MB_OK);return -1;}// 显示窗口,刷新窗口客户区::ShowWindow(hwnd, nCmdShow);::UpdateWindow(hwnd);// 从消息堆中取出消息MSG msg;while (::GetMessage(&msg, NULL, 0, 0)){// 转化键盘消息::TranslateMessage(&msg);// 将消息发送到相应的窗口函数::DispatchMessage(&msg);}// 当GetMessage返回0时程序结束return msg.wParam;
}LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{// str对象用于保存窗口客户区显示的字符串// 为了使用string类,应该包含头文件:“#include <string>”static std::string str;switch (message){case WM_CREATE:{// 设置窗口的标题::SetWindowText(hwnd, "最简陋的打字程序");//::SendMessage(hwnd, WM_SETTEXT, 0, (long)"最简陋的打字程序");return 0;}case WM_COMMAND:switch (LOWORD(wParam)){case ID_FILE_EXIT:// 向hwnd指定的窗口发送一个WM_CLOSE消息。::SendMessage(hwnd, WM_CLOSE, 0, 0);// ::PostMessage(hwnd, WM_CLOSE, 0, 0);break;}case WM_PAINT:{PAINTSTRUCT ps;HDC hdc = ::BeginPaint(hwnd, &ps);// 设置输出文本的背景颜色和文字颜色::SetTextColor(hdc, RGB(255, 0, 0));::SetBkColor(hdc, ::GetSysColor(COLOR_3DFACE));::TextOut(hdc, 0, 0, str.c_str(), str.length());::EndPaint(hwnd, &ps);return 0;}case WM_CHAR:{// 保存ansi码str = str + char(wParam);// 使整个客户区无效::InvalidateRect(hwnd, NULL, 0);return 0;}case WM_LBUTTONDOWN:{char szPoint[56];// 保存坐标信息wsprintf(szPoint, "X =%d,Y =%d", LOWORD(lParam), HIWORD(lParam));str = szPoint;if (wParam & MK_SHIFT)str = str + "   Shift Key is down";::InvalidateRect(hwnd, NULL, 1);return 0;}case WM_DESTROY: // 正在销毁窗口// 向消息队列投递一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环::PostQuitMessage(0);return 0;}// 将我们不处理的消息交给系统做默认处理return ::DefWindowProc(hwnd, message, wParam, lParam);
}


使用资源

资源是一些二进制数据,它能够添加到基于窗口的应用程序的可执行文件中。资源可以是标准的或者自定义的。标准资源中数据描述的资源类型有图标、光标、菜单、对话框、bitmap图像、字符串表入口等。应用程序定义的资源,也称为自定义资源,可以包含应用程序需要的任意数据。

资源文件的“源文件”是以rc为扩展名的脚本文件,由资源编译器Rc.exe编译成为以res为扩展名的二进制文件,在链接的时候,由Link.exe链入到可执行文件中。所以要想使用资源,必须首先建立一个资源脚本文件。具体过程如下:

单击菜单“File/New…",在弹出的对话框中选择Files选项卡,选中 Resource Script选项。在右边的File窗口下输入文件名resource(名字是任意的),单击“OK”按钮,如图4.4所示。

此时在工作区左边中多了一个栏目Resource View。而 VC++会自动在工程目录下创建两个文件:resource.rc和l resource.h。

.rc 文件中的所有资源都关联了一个字符串名称或数字,当使用数字标识资源的时候,resource.h文件对这些数字都定义了宏名,比如:

#define IDI_MAIN  101

这说明程序中有一个ID号为101的资源。要引用此资源,在程序中包含resource.h头文件以后,直接用宏名IDI_MAIN就可以。一般不要直接修改resource.h文件中的内容,这些定义语句是由VC++自动加上去的,读者可以通过可视化资源编译器对它们进行修改。

资源脚本文件 resource.rc是用简单的脚本语言对所添加的资源的描述。用记事本打开它,会看到类似下面的代码。

IDI_MAIN ICON DISCARDABLE "Main.ico"

资源编译器Rc.exe看到这行代码以后会将文件名为Main.ico的图标添加到目标二进制文件中。IDI_MAIN是这个图标的标识,许多与资源有关的函数都要以它为参数。

向工程中添加资源,也就是向资源脚本中添加资源描述代码,并向resource.h中添加宏定义。在 VC++下完成这个过程是很简单的,选择菜单命令“Insert/Resource…",将弹出图4.5所示的对话框。在这个对话框里选择要添加的资源类型即可。

菜单和图标

先为打字程序添加菜单。在Insert Resource对话框中选中 Menu,单击 New按钮即把菜单资源加入到了工程中,如图4.5所示。

打开工作区的 Resource选项卡,找到刚刚添加的菜单资源,双击它,这时系统会弹出一个属性对话框中。在这个对话框里将菜单的ID号改为IDR_TYPER(默认为IDR_MENU1)。选中资源,按下alt+enter即可。

作为示例我们只向菜单中添加一个File项:双击菜单中的第一个菜单项,在弹出的对话框的Caption窗口下键入名称“文件”。

继续添加子项,ID号设为ID_FILE_EXIT,Caption为退出,如图4.6所示。

菜单设置完后在程序的开头加上包含头文件的代码#include "resource.h",就可以在程序中引用添加的资源了。上一节中讲到,WNDCLASSEX结构成员lpszMenuName用于指定基于此类的窗口的菜单名称,所以程序代码要做如下修改。

wndclass.lpszMenuName = (LPSTR) IDR_TYPER;

也可以通过 SetMenu 函数设置窗口上的菜单。比如,要实现同样的效果,可以在处理WM_CREATE 消息时,添加如下的代码。

HMENU hMenu = ::LoadMenu(::GetModuleHandle(NULL), (LPCTSTR)IDR_TYPER);
::SetMenu(hwnd, hMenu);

LoadMenu函数用于从指定的模块中加载菜单资源,第一个参数是包含要加载资源的模块句柄,第二个参数是资源ID号。无论用哪一种方法,运行程序,都可以看到一个菜单。

当用户点击菜单中的某一个选项时,Windows即向应用程序发送一个 WM_COMMAND消息,其中参数wParam 的低字节包含了用户点击菜单的ID号。04SimpleTyper 响应WM_COMMAND消息的代码如下。

case WM_COMMAND: switch(LOWORD(wParam)) { case ID_FILE_EXIT: // 向hwnd 指定的窗口发送一个WM_CLOSE 消息。::SendMessage(hwnd, WM_CLOSE, 0, 0); break; } return 0;

窗口接收到WM_COMMAND消息时,用宏LOWORD 从wParam参数中取出菜单ID号。LOWORD宏定义用于取出 wParam变量的低16位。相应地,wParam参数的高字节包含了一些消息通知码,可以用HIWORD宏取出。这些消息通知码只对子窗口控件有效。

之后,如果用户单击的是“退出”命令,则调用SendMessage函数向此窗口发送一个wM_CLOSE的消息。由SendMessage函数发送的消息并不进入消息队列等待GetMessage函数取出,而是直接传给窗口函数 MainWndProc,并等待MainWndProc函数返回时再返回,其返回值也就是 WndProc函数的返回值。

WM_CLOSE消息在默认情况下由DefWindowProc函数处理,它会调用DestroyWindow函数来销毁窗口。窗口销毁时,窗口函数 MainWndProc会收到一个 WM_DESTROY消息(由DestroyWindow函数发出),表示窗口正在销毁。程序用PostQuitMessage(0);语句来响应这个消息。PostQuitMessage函数向消息队列中投递了一个WM_QUIT消息,GetMessage函数取到此消息后返回0,消息循环结束,程序退出。

可以处理 WM_CLOSE 消息,以决定是否允许关闭窗口。比如,向MainWndProc函数添加如下代码。

case WM_CLOSE: // 屏蔽掉WM_CLOSE 消息return 0;

这样此窗口是无论如何也关不掉了。但是更一般的做法是:

case WM_CLOSE: 【处理关闭前的工作】::DestroyWindow ( hwnd ) ; return 0;

另外一个常用的函数 PostMessage,它的功能是向指定窗口投递消息,原型如下。

BOOL PostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

与SendMessage函数不同的是PostMessage函数发送消息后马上返回,并不等待消息的运行结果。它不是把消息直接发给窗口处理函数MainWndProc,而是像邮递员一样把消息投放到窗口所在线程的消息队列中等待GetMessage函数取出。

添加完菜单后,还要再添加一个图标资源。选择菜单命令“InsertResource…",在弹出的Insert Resource对话框中选中Icon选项。如果想新建一个图标,则点击“New”按钮;想导入一个已存在的图标,则点击“Import…”按钮再选择图标的路径。

双击新加入的图标,把ID号改为IDI_TYPER。在 WNDCLASSEX 结构中有一个hlcon成员,就是为接受图标句柄而存在的,这里将它设置为:

wndclass.hIcon = ::LoadIcon(hInstance, (LPSTR)IDI_TYPER); // 使用自定义图标

LoadIcon 是装载图标的函数。现在运行程序,窗口标题栏的左上角将出现一个小图标。

接收键盘输入

当按下一个键时,Windows会向获得输入焦点的那个窗口所在线程的消息队列投递一个WM_KEYDOWN或WM_SYSKEYDOWN消息。当释放这个键时,Windows就会投递一个WM_KEYUP或WM_SYSKEYUP消息。WM_SYSKEYDOWN和 WM_SYSKEYUP是用户敲击系统键时产生的消息。比如Alt十F4是关闭窗口的快捷键。默认情况下应该把它们交给DefWindowProc 函数来处理。

在这几个消息中,wParam参数包含了敲击键的虚拟键码,IParam参数则包含了另外一些状态信息。

当一个WM_KEYDOWN消息被TranslateMessage函数转化以后会有一个WM_CHAR消息产生,此消息的wParam参数包含了按键的ANSI 码。例如,用户敲击一次“A”键,窗口会顺序地收到以下3个消息。

WM_KEYDOWN     lParam 的含义为虚拟键码“A”(0x41)
WM_CHAR        lParam 的含义为 ANSI 码“a”(0x61)
WM_KEYUP       lParam 的含义为虚拟键码“A”(0x41)

本节的打字程序通过处理 WM_CHAR 消息来接受用户输入,相关代码如下。

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{// str对象用于保存窗口客户区显示的字符串// 为了使用string类,应该包含头文件:“#include <string>”static std::string str;switch (message){case WM_CREATE:{// 设置窗口的标题::SetWindowText(hwnd, "最简陋的打字程序");//::SendMessage(hwnd, WM_SETTEXT, 0, (long)"最简陋的打字程序");return 0;}case WM_COMMAND:switch (LOWORD(wParam)){case ID_FILE_EXIT:// 向hwnd指定的窗口发送一个WM_CLOSE消息。::SendMessage(hwnd, WM_CLOSE, 0, 0);// ::PostMessage(hwnd, WM_CLOSE, 0, 0);break;}case WM_PAINT:{PAINTSTRUCT ps;HDC hdc = ::BeginPaint(hwnd, &ps);// 设置输出文本的背景颜色和文字颜色::SetTextColor(hdc, RGB(255, 0, 0));::SetBkColor(hdc, ::GetSysColor(COLOR_3DFACE));::TextOut(hdc, 0, 0, str.c_str(), str.length());::EndPaint(hwnd, &ps);return 0;}case WM_CHAR:{// 保存ansi码str = str + char(wParam);// 使整个客户区无效::InvalidateRect(hwnd, NULL, 0);return 0;}case WM_LBUTTONDOWN:{char szPoint[56];// 保存坐标信息wsprintf(szPoint, "X =%d,Y =%d", LOWORD(lParam), HIWORD(lParam));str = szPoint;if (wParam & MK_SHIFT)str = str + "   Shift Key is down";::InvalidateRect(hwnd, NULL, 1);return 0;}case WM_DESTROY: // 正在销毁窗口// 向消息队列投递一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环::PostQuitMessage(0);return 0;}// 将我们不处理的消息交给系统做默认处理return ::DefWindowProc(hwnd, message, wParam, lParam);
}

std:string是标准C++库中的字符串类,为了使用这个类,应该将文件 string包含进来。 str变量保存着要显示给用户的字符串,每次处理WM_PAINT消息的时候,程序都会试图将它包含的内容全部绘制到客户区。

用户敲击键盘时,产生 WM_CHAR消息,程序把对应的字符加到str变量里。InvalidateRect函数使整个客户区变得无效,迫使Windows再次发送WM_PAINT消息。这个函数原型是:

BOOL InvalidateRect ( HWND hWnd , CONST RECT *lpRect, BOOL bErase ) ;

第二个参数 lpRect 指定了无效区域的范围,它是一个指向 RECT 类型的指针。

typedef struct tagRECT
{LONG    left; // 左上角的X 坐标LONG    top; // 左上角的Y 坐标LONG    right; // 右下角的X 坐标LONG    bottom; // 右下角的Y 坐标
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;

(left, top)指定了区域左上角的坐标,(right,bottom)指定了区域右下角的坐标。把这个参数设为NULL,则是要Windows无效整个客户区。

bErase参数指定在更新区域时,其背景是否要擦除。

窗口处理函数接收到WM_PAINT消息,可能是因为整个客户区变的无效了,也可能是因为客户区中的某一块区域变得无效了。BegainPaint函数的第二个参数为一个指向PAINTSTRUCT结构的指针,此结构包含了应用程序重画窗口客户区时所需的信息。

typedef struct tagPAINTSTRUCT {HDC         hdc; // 设备环境句柄BOOL        fErase; // 指定背景是否必须删除RECT        rcPaint; // 指定要求重画的区域BOOL        fRestore;BOOL        fIncUpdate;BYTE        rgbReserved[32];
} PAINTSTRUCT, *PPAINTSTRUCT, *NPPAINTSTRUCT, *LPPAINTSTRUCT;

这里面有用的一个成员就是 rcPaint,它指定了客户区中无效区域的范围。

接收鼠标输入

应用程序以接收发送或者投递到它的窗口的消息的形式接收鼠标输入。当用户移动鼠标,或按下、释放鼠标的一个键时,鼠标会产生输入事件。系统将鼠标输入事件转化成消息,投递它们到相应线程的消息队列。和处理键盘输入一样,Windows将捕捉鼠标动作,并把它们发送到相关窗口。

当用户移动光标到窗口的客户区时,系统投递WM_MOUSEMOVE消息到这个窗口。当用户在客户区按下或者释放鼠标的键时,它投递下面的消息:

发送这些消息时,lParam 参数包含了鼠标的位置坐标,可以这样读出坐标信息。

xPos = LOWORD (lParam);
yPos = HIWORD (lParam);

这些坐标都以客户区的左上角为原点,向右是x轴正方向,向下是 y轴正方向。ClientToScreen 函数可以把坐标转化为以屏幕的左上角为原点的坐标。

BOOL ClientToScreen(HWND hWnd, LPPOINT lpPoint) ;
BOOL ScreenToClient(HWND hWnd, LPPOINT lpPoint );

同样,ScreenToClient 函数又可把坐标转化回来。lpPoint参数是指向POINT结构的指针,把要转化的坐标信息写入lpPoint参数指向的内存,Windows把转化后的结果也返回到这块内存中。

wParam参数包含鼠标按钮的状态,这些状态都以MK_(意为mouse key)为前缀,,取值如下:

MK_LBUTTON     左键按下
MK_MBUTTON     中间的键按下
MK_RBUTTON     右键按下
MK_SHIFT       <Shift>键按下
MK_CONTROL     <Ctrl>键按下

例如,收到WM_LBUTTONDOWN消息时,如果wParam&MK_SHIFT的值为TRUE,就会知道当单击左键时,<Shift>键也被按下了。

为了进行试验,可以在程序中加入如下响应WM_LBUTTONDOWN消息的代码。

case WM_LBUTTONDOWN:
{char szPoint[56];// 保存坐标信息wsprintf(szPoint, "X =%d,Y =%d", LOWORD(lParam), HIWORD(lParam));str = szPoint;if (wParam & MK_SHIFT)str = str + "   Shift Key is down";::InvalidateRect(hwnd, NULL, 1);return 0;
}

wsprintf函数比printf 函数多了一个参数szPoint,它的作用可以认为是接收 printf 函数的输出结果。运行程序,在窗口客户区单击鼠标左键,就可以看到程序具体的运行效果。

设置文本颜色和背景色

设置窗口客户区背景色的方法在4.2.3节已经有所讨论,也就是给WNDCLASSEX结构的 hbrBackground成员安排一个画刷对象句柄。当然,这个画刷对象也可以是预定义的。比如要把背景色设置为最常见的灰色(对话框的颜色)可以用下面的代码。

wcex.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);

可是TextOut函数输出文本时,默认的文本背景色为白色,文本颜色为黑色,而不管客户区的背景色是什么。为了使文本的背景色同客户区的背景色一致,有必要在输出文本时先设置它的背景色。

PAINTSTRUCT ps;
HDC hdc = ::BeginPaint(hwnd, &ps);// 设置输出文本的背景颜色和文字颜色
::SetTextColor(hdc, RGB(255, 0, 0));
::SetBkColor(hdc, ::GetSysColor(COLOR_3DFACE));::TextOut(hdc, 0, 0, str.c_str(), str.length());
::EndPaint(hwnd, &ps);
return 0;

SetTextColor函数把输出文本的颜色设置为了红色。COLOR_3DFACE是Windows预定义的显示元素(显示元素是屏幕上窗口的一部分),GetSysColor 函数则可以获取它的颜色。

4.3一个“简陋”的打字程序相关推荐

  1. 金山打字游戏c语言代码,一天练习一个小C/C++程序(一) 控制台版“金山打字”游戏...

    今天练习了一个C语言小程序,控制台版的简易"金山打字"小游戏. 效果图: 代码: #include #include #include #include void printfSp ...

  2. 一天练习一个小C/C++程序(一) 控制台版“金山打字”游戏

    今天练习了一个C语言小程序,控制台版的简易"金山打字"小游戏. 效果图: 代码: #include<stdio.h> #include<stdlib.h> ...

  3. python界面显示图片更换背景_用python制作一个简陋的证件照换底色的桌面控制台应用...

    获取抠图API密钥 前往RemoveBg官网注册一个账号 注册账户界面已翻译,Api每月可用50次 注册成功后登录,按图示所选点击 点击 Get Api Key 获取Api密钥 安装所需支持库 imp ...

  4. 【C语言】之实现简单的打字程序

    /************************************************ 文件名:typeWroe.c* 文件描述:实现简易的字符界面的打字程序-linux平台下* 编写人: ...

  5. java swt shell_一个java swt桌面程序开发到打包的总结(1)

    一个java swt桌面程序开发到打包的总结(1) --概述与关于swt的问题 一.概述: 几天一直在用金山打字通练习英语(本人英语比较烂),把金山打字能里面的文章全部掠了N遍.打的没意思了,想想怎么 ...

  6. C#操作数据库、打字程序,GridView访问数据库、程序打包本地sqlite数据库文件

    这里写自定义目录标题 访问数据库的类 程序打包本地sqlite数据库文件 访问数据库的类 class MyMeans //访问数据库的类--类包含了程序使用的数据和方法声明.类一般包含多个方法.方法定 ...

  7. 用java做一个简单记事本_用记事本写一个简单的java程序

    用记事本写一个简单的java程序 第一步: 安装好jdk,并设置好环境变量. 桌面-计算机(右键)-属性-高级系统设置-环境变量-path-在变量值后加上:和jdk安装路径加上(路径即为C:\Prog ...

  8. pygame做一个简单的打字游戏

    pygame做一个简单的打字游戏 1.基本代码 下面的代码完成了每一秒在界面的顶部随机生成一个新的字母 # -*- coding=utf-8 -*- import pygame from pygame ...

  9. 臻好黄金百香果苗做一个有脑子的程序员

    程序员是最理性的一个群人,除非面对电子产品的时. 程序员是一群高智商的群体,唯一的缺点就是发际线总是很难防守. 程序员是一群情商比较低的人群,常常看到程序员仅仅因为对技术的理解不同而大吵起来. 程序员 ...

最新文章

  1. 2022-2028年中国搪胶行业市场深度分析及投资前景分析报告
  2. Echart遇到的问题:tooltip提示框大小异常
  3. 推荐:Visual Basic.NET Windows Forms 编程
  4. PHP_SCREW 加密
  5. DateTimePicker 日期时间选择器报错 Cannot read property ‘getHours‘ of undefined, 无法选中`[__ob_: observer__]`时做判断
  6. SAP Spartacus 中的 Commands and queries
  7. CHIP ID was not passed on from the tile; contact your system administrator
  8. HTML DOM content 属性
  9. Java获取方法信息(某一函数,方法也是一个对象)
  10. mysql geocode_百度地图Geocoding API获取特定地区或地址的经纬度信息,然后在MySql数据库多表循环遍历更新...
  11. mysql中使用sqldriverconnect()报错的解决
  12. 老李分享:5个衡量软件质量的标准
  13. java开发个人项目_个人项目-WC (java实现)
  14. vs2015 professional 密钥
  15. H5制作模板推荐:微信小游戏消消乐玩法亮点
  16. windows自带的使用键盘代替鼠标操作问题._百度知道
  17. insert的语句的三种方式
  18. Java整合FFmpeg截取视频某一帧为图片
  19. 哈佛大学砸场子:DALL-E 2只是「粘合怪」,生成正确率只有22%
  20. root用户修改root密码提示The password fails the dictionary check

热门文章

  1. 单片机最小系统c语言报告,单片机最小系统实验报告.doc
  2. Redis-数据结构01-压缩列表(ziplist)
  3. Linux C基础笔记(2)
  4. python except用法和作用_Python保留字简单释义
  5. cefsharp 网页另存为图片_如何将PDF转换为JPG图片?这些转换方法一学就会
  6. oppo面经-java开发
  7. win7记事本txt图标显示异常解决方法
  8. 杂项:JFB-权限设置
  9. python基础--字符串单引号双引号和三引号
  10. Hive-RCFile文件存储格式