TextOut輸出中文漢字——記練習程序員表白程序

程序練習來自博客:_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_TIMER	0
#define IDB_BITMAP1		1


FILE	*fp = NULL;
CHAR	c1[3];
int		row, col;
int		cxChar, 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;
}



發佈了28 篇原創文章 · 獲贊 7 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章