您的位置:首页 > 职场人生

TextOut输出中文汉字——记练习程序员表白程序

2014-05-18 21:28 1041 查看
程序练习来自博客:_BlueCoder_  http://blog.csdn.net/crocodile__/article/details/9527845  

简单说下程序的主要内容:

(1)来一张赏心悦目的背景(.bmp); 就是贴一张bmp位图, 在WM_CREATE消息中加载位图信息, 在WM_PAINT消息中绘制背景。

(2)逐个字显示一首情诗(.txt) ; 就是绘制文本,先将诗歌保存到一个txt文档中,然后读取这个文件。

(3)来一首催人泪下的、优美的歌曲(.wav);就是用PlaySound()函数。

原来的代码请看上述博客里面的链接,这里也附上吧。程序员表白程序.zip

我自己也是下载的源代码练习的。用VS2012的过程中,有几个问题。

1. 首先是那几个函数fopen、fscanf 编译出错,提示不安全,需要用安全版本的,即fopen_s、fscanf_s等。几个小问题。

2. 然后是出现了很多无法加载PDB文件的问题,解决办法网上也有:
点 调试 - 选项和设置 然后右边勾上 启用源服务器支持 然后在左边点 符号 把微软符号服务器勾上。。。。。就能在线去下载那些文件。。


3.最重要的一点是运行时,输出的都是两个并列的竖线 || 。汉字没有读出来。后来调整,已经把汉字读入了,但是TextOut输出全是乱码


但是网上的几乎都是TextOut直接输出常量字符串,或者用其他函数printf等。这涉及到汉字怎么读取和存储的。


比如,网上有通过getc来读取汉字的。


getc每次读取一个字符(与字节不同,英文1字节=1字符,中文2字节=1字符)


我就用如下代码尝试下,


#include <stdio.h>
#include <stdlib.h>

//char word[2];

int main()
{
FILE *fp;
fopen_s(&fp,"Poem.txt","r");
char c;
while((c = getc(fp)) != EOF)//getc函数
{
printf("%c", c);
//getchar();//如果要看到汉字一个一个地输出,可以用getchar暂停等待输入
}
return 0;
}
测试,可以运行,说明getc可以读取一个汉字字符,但是不止用一个字节存储。

然后,在代码中改,用fgets函数读取汉字,fgets(c1,3,fp),3为3个字节大小的字符串(目的是要读取一个汉字,应该只读取了2个字节的数据,后面加入英文字母应该可以算做验证)。放入一个3单元的char数组,原文给的是2个,可能跟编译器有关系。调试的时候可以看到数组后面的汉字。


.txt文件也要保存为ANSI格式的。




说明读取正确,但是TextOut输出不正确。最后改了TextOut函数为ANSI版本的TextOutA。正确输出。




把.txt文本中加入一些英文字母,也可以显示。因为,前面显示汉字是用了fgets,且指定为3字节大小字符串。看看读取并输出的效果:




可以看到,每2个英文字母的颜色是一样的(或者1个和另外一个空格符,不显示),即一次读取输出的。所以,可以验证,fgets函数中指定字节数为字符串大小,读取数据比指定字节数目少一个,末尾应该是置字符串结束标志。


win32对于读取和输出汉字的支持,没有深究,有研究的朋友,欢迎指导。


如下是我的代码,原文中有注释,所以我没有注释,写的比较简单。


#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <TCHAR.h>
#include <string>
#include "resource1.h"

#pragma comment(lib, "winmm.lib")

#define WS_NORESIZEWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)

#define ID_TIMER0
#define IDB_BITMAP11

FILE*fp = NULL;
CHARc1[3];
introw, col;
intcxChar, cyChar;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int ShowWord(HDC);

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
{
static TCHAR szAppName[] = TEXT("I Love U");
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_APPLICATION);
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;

if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"),szAppName,MB_ICONERROR);
return 0;
}

hwnd = CreateWindow(szAppName,szAppName,WS_NORESIZEWINDOW,
0, 0, 1, 1,
NULL,NULL,hInstance,NULL);

ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);

while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
static HBITMAP hBitmap;
static int cxBitmap, cyBitmap;
BITMAP bitmap;
HDC hdc, hdcMem;
HINSTANCE hInstance;
PAINTSTRUCT ps;
TEXTMETRIC tm;

switch (message)
{
case WM_CREATE:
PlaySound(TEXT("C:/Users/Administrator.WIN-BC2SV23HDRV/Desktop/爱尔兰风笛.wav"),NULL,SND_FILENAME | SND_ASYNC);

hInstance = ((LPCREATESTRUCT)lParam)->hInstance; //lParam是操作系统调用你的窗口过程传给你的参数 他根据处理消息的不同含义也会不同
//当在处理WM_CREATE消息时 lParam里面保存的是一指针既LPCREATESTRUCT结构的地址 其中有一个域名为hInstance
//((LPCREATESTRUCT) lParam)->hInstance 就是通过保存在lParam里面的地址取出LPCREATESTRUCT结构里面的hInstance 既程序的实例句柄
hBitmap = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP1));
GetObject(hBitmap, sizeof(BITMAP), &bitmap);
cxBitmap = bitmap.bmWidth;
cyBitmap = bitmap.bmHeight;

int cxScreen, cyScreen;
cxScreen = GetSystemMetrics(SM_CXSCREEN);
cyScreen = GetSystemMetrics(SM_CXSCREEN);
MoveWindow(hwnd, cxScreen / 4, cyScreen / 16, cxBitmap, cyBitmap, TRUE); //按照位图大小设定窗口大小,没有像原文作者在WM_CREAT消息里面直接设定

hdc = GetDC(hwnd);
GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight;
ReleaseDC(hwnd, hdc);

SetTimer(hwnd, ID_TIMER, 420, NULL);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd,&ps);
hdcMem = CreateCompatibleDC(hdc);
SelectObject(hdcMem, hBitmap);
BitBlt(hdc, -1, -1, cxBitmap, cyBitmap, hdcMem, 0, 0, SRCCOPY);
DeleteDC(hdcMem);
EndPaint(hwnd, &ps);
Sleep(2500);
return 0;
case WM_TIMER:
hdc = GetDC(hwnd);
SetTextColor(hdc, RGB(rand()%255, rand()%255, rand()%255));
SetBkMode(hdc, TRANSPARENT);

if (ShowWord(hdc) == EOF)
{
KillTimer(hwnd, ID_TIMER);
}
ReleaseDC(hwnd, hdc);
return 0;
case WM_DESTROY:
DeleteObject(hBitmap);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}

int ShowWord(HDC hdc)
{
if (fp == NULL)
{
fopen_s(&fp,"Poem.txt","r");
}

if(NULL != fgets(c1,3,fp))
{
if (c1[0] == '\n' | c1[1] == '\n' | c1[2] == '\n')
{
++ row;
col = 0;
}
else
{
++ col;
TextOutA(hdc, col * (cxChar*2 +3) + 100, row * cyChar + 5,c1, 2);
}
return 0;
}
return EOF;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息