程序練習來自博客:_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;
}