手记

屋顶打字通(三)--windows开发总结

当我发现,添加文件,计时器,刷新列表出现问题后,我又翻出屋顶打字通代码做了一番修改,勉强添加了显示英的样式,把刷新列表的问题用绝对路径解决了,至此,我的屋顶打字通算是完成了它的第二个版本,这份代码也没什么特别的,就开源出来分享给大家,整个工程几乎用的都是Unicode,当然也有用的不是宽字节的,我写了这两个之间的转换函数,只是字符串之间的转换,这次写打字通学到了,GDI绘图,多线程的使用,U码和A码转换,绝对路径和相对路径的使用,WINDOWS消息机制(主要是绘图)。

用到两种创建窗口的方式,而且这两种方式都通过resource添加了对话框:
DialogBox(hInstance,MAKEINTRESOURCE(ID_MENU_STARTMENU),NULL,DlgMain);//这种方式不会立即返回,只有对话框结束了才会返回
CreateDialog(hIstanceMain,MAKEINTRESOURCE(ID_DIG_GAMEVIEW),NULL,DlaGame);//这种方式会立即返回
设计界面:
一、开始界面
菜单栏,显示列表,选中提示框,开始按钮
(1):菜单栏
(1.1)编辑:
(1.1.1)添加:
(1.1.2)中英文显示转换:
(1.2)帮助:
(1.2.1)链接:
(1.2.2)关于:
(2):显示列表
用于显示文件夹内的TXT文件
(2.1):左键单击选中列表一行,选中提示框内容变化
(2.2):左键双击列表中的一行,直接打开文件
(2.3):右键单击列表中的一行,可以对文件进行操作,包括删除该文件和全删除
(3):选中提示框
用于提示用户选中了哪一行
(4):开始按钮
点击开始按钮则会判断选中框内是否有内容,有,则打开指定文件,没有,则提示用户进行选择


二、打字界面
当前文章标题,进度条,计时器,三行文字显示和输入框,速度显示,错误字数
(1):当前文章标题
显示打开文件的标题
(2):进度条
显示打字进度,数字显示百分比,进度条根据百分比显示相应长度
(3):计时器
当有字符键入时,开始计时
(4):三行显示和输入
(4.1):显示文章的20个字符,根据二维数组内的数字判断画出字的颜色
(4.2):输入框等待用户输入,对输入的每一个字符进行判断,与上面字符相匹配则显示蓝色,不匹配则显示红色,用户不可以更改输入框的焦点,特殊处理有:显示的时候遇到换行符则变成空格,到键入最后一个字符时,如果键入多个的时候,自动换行或换页显示
(4.3):输入至文章末尾,则结束打字界面
(5):速度显示
计时器线程的创建,显示 时 分 秒
(6):错误字数
每次键入都会判断是否匹配,计数显示

打字通写得一般,代码质量也不高,因为这份代码确实是想到哪里写到哪里的,连有那些功能都是想到了才去完成那些部分的,展示给大家全部代码,但是大家也用不了,因为资源文件是我手动创建的,所以直接复制源码还是用不了的,这是WIN32程序,对C/C++感兴趣并且对Windows消息机制和GDI绘图感兴趣的可以仔细看看我这份代码。

TypeMain.cpp


#include"Constant.h"
void EditFontController(float AimSize) {
	LOGFONT LogFont;
	memset(&LogFont, 0, sizeof(LOGFONT));
	lstrcpy(LogFont.lfFaceName, L"Arial");
	LogFont.lfWeight = FW_BLACK;//FW_NORMAL; 
	LogFont.lfHeight = (LONG)AimSize; // 字体大小 
	LogFont.lfCharSet = 134;
	LogFont.lfOutPrecision = 3;
	LogFont.lfClipPrecision = 2;
	LogFont.lfOrientation = 45;
	LogFont.lfQuality = 1;
	LogFont.lfPitchAndFamily = 2;
	// 创建字体 
	HFONT hFont = CreateFontIndirect(&LogFont);
	// 取得控件句柄 
	for (int i = 0; i < 3; i++) {//设置控件字体
		hWndEdit[i] = GetDlgItem(hWndGameView, EditInput1 + i);
		SendMessage(hWndEdit[i], WM_SETFONT, (WPARAM)hFont, TRUE);
	}
}
wchar_t* GetCurrentPath(wchar_t * target) {
	LPWSTR PointPath = NULL;
	wchar_t *cppoint = 0;
	cppoint = new wchar_t[MAX_PATH];
	cppoint[0] = 0;
	GetModuleFileName(NULL, cppoint, MAX_PATH);//获得绝对路径
	(_tcsrchr(cppoint, _T('\\')))[1] = 0;//截掉exe文件名
	if (target) {//根据需要粘贴指定字符串
		wcscat_s(cppoint, MAX_PATH, target);//给路径添加MyResource
	}	
	PointPath = cppoint;
	return PointPath;
}

void InitArray() {//初始化数组,赋值1
	for (int i = 0; i < 3; i++) 
		for (int j = 0; j < 20; j++) 
			ColorFlage[i][j] = 1;
}
void InitTxt() {
	InitArray();
	SetDlgItemText(hWndGameView, EditInput1, L"");//清空文本框内容
	SetDlgItemText(hWndGameView, EditInput2, L"");//
	SetDlgItemText(hWndGameView, EditInput3, L"");//
}
void Counter(int &hour, int &minute, int &second) {
	if (++second == 60) {//计时器
		TimePane[6] = 0;//满60秒记1分钟,秒的十位归零
		if (++minute == 60) {
			TimePane[3] = 0;//满60分钟记1小时,分钟的十位归零
			if (++hour == 60)
				return;
			minute = 0;
		}
		second = 0;
	}
}
void TimeChanger(int time, int shift) {
	int tmp1 = 0;
	wchar_t wtmp[2];//必须两个,不然没有办法安放'\0'
	if (time<10) {
		_itow_s(time, wtmp, 2, 10);
		TimePane[shift] = wtmp[0];
	}else {
		tmp1 = time / 10;
		_itow_s(tmp1, wtmp, 2, 10);
		TimePane[shift - 1] = wtmp[0];
		tmp1 = time % 10;
		_itow_s(tmp1, wtmp, 2, 10);
		TimePane[shift] = wtmp[0];
	}
}
DWORD WINAPI TimerFunction(LPVOID lpParam) {//计时器线程
	int Hour = 0, Minute = 0, Second = 0;
	RECT tmpR;
	for (int i = 0; i < 8; i++) {
		TimePane[i] = 0;//TimePane里面是这样的 00:00:00
	}//初始化时间面板数组
	TimePane[2] = ':';
	TimePane[5] = ':';
	tmpR.left = 620L;
	tmpR.right = 680L;
	tmpR.top = 42L;
	tmpR.bottom = 62L;
	while (hAndleTimer) {
		Sleep(1000);//下面采用最麻烦的计时,然后提取个位和十位数字分别放在要显示的面板上
		Counter(Hour, Minute, Second);
		if (Hour == 60) 
			return 0;
		TimeChanger(Second, 7);
		TimeChanger(Minute, 4);
		TimeChanger(Hour, 1);
		CountSecond = Hour * 60 * 60 + Minute * 60 + Second;//统计时间用于计算速度
		InvalidateRect(hWndGameView, &tmpR, false);
		UpdateWindow(hWndGameView);
	}
	return 0;
}
void StepMoveOn(int model) {
	if (model == 1)
		FlagBack = true;
	else
		FlagBack = false;
	if (FlagBack) {
		MOVE = MOVE - 1;
		TxtInfo.MoveAddress = TxtInfo.MoveAddress - 1;
	}
	int GoDown = (int)INTERVAL*(NUMBEREDIT - 1);
	AimRect.left = RECTX + (LONG)(MOVE)*(RECTA);
	AimRect.right = AimRect.left + RECTA;
	if (AimRect.right >= 234)
		AimRect.right = AimRect.right + 3L;
	if (AimRect.right >= 294)
		AimRect.right = AimRect.right + 5L;
	if (AimRect.right >= 512)
		AimRect.right = AimRect.right + 5L;
	AimRect.top = (((LONG)PointY - (LONG)3) + (LONG)GoDown);
	AimRect.bottom = (((LONG)PointY - (LONG)3) + ((LONG)SizeFont + (LONG)4) + (LONG)GoDown);
	ColorFlage[NUMBEREDIT - 1][MOVE] = model;
	if (EnglishOrChinese) {
		InvalidateRect(hWndGameView, &AimRect, false);
		UpdateWindow(hWndGameView);
	}
	else {
		InvalidateRect(hWndGameView, 0, false);
		UpdateWindow(hWndGameView);
	}
	
	if (!FlagBack) {
		MOVE = MOVE + 1;
		TxtInfo.MoveAddress = TxtInfo.MoveAddress + 1;
	}
	wchar_t * TmpCurrentPathA = GetCurrentPath(NULL);//exe所在绝对路径
	wchar_t SoundName[] = L"1466.wav";
	wcscat_s(TmpCurrentPathA, MAX_PATH, SoundName);//给路径添加MyResource
	PlaySound(TmpCurrentPathA, 0, SND_FILENAME | SND_ASYNC);
	delete[] TmpCurrentPathA;
}
void DealEditCallBack(WPARAM wWord) {
	if (TxtInfo.TXTSIZE) {
		wchar_t TmpChar = (wchar_t)wWord;
		wchar_t TmpSource = TxtInfo.TXTCONTENT[TxtInfo.MoveAddress];
		int tmpCount = 0;
		if (TmpChar != TmpSource) {//匹配失败
			if (wWord == 8) {//退格符
				if (MOVE>0) {//退格符有效
					StepMoveOn(GreyNUMBER);
				}
				//退格符无效
			}
			else {//不是退格符且匹配失败
				StepMoveOn(RedNUMBER);
				if (CountSecond > 0) {
					double SPEED = (double)TxtInfo.MoveAddress / (double)CountSecond * 60;
					stringstream tmpus;
					string tmpstr;
					tmpus << (int)SPEED;
					tmpus >> tmpstr;
					wchar_t *tmp1 = ConvertLPSTRtoLPWSTR(tmpstr.c_str());
					SetDlgItemText(hWndGameView, ViewSpeed, tmp1);
					delete[] tmp1;
				}
			}
		}else {//匹配成功
			StepMoveOn(BlueNUMBER);
			if (CountSecond > 0) {
				double SPEED = (double)TxtInfo.MoveAddress / (double)CountSecond * 60;
				stringstream tmpus;
				string tmpstr;
				tmpus << (int)SPEED;
				tmpus >> tmpstr;
				wchar_t * tmp2 = ConvertLPSTRtoLPWSTR(tmpstr.c_str());
				SetDlgItemText(hWndGameView, ViewSpeed, tmp2);
				delete[] tmp2;
			}
		}
		if (!hAndleTimer) {//计时器线程句柄
			hAndleTimer = CreateThread(0, 0, TimerFunction, 0, 0, 0);//创建计时器线程,返回值为句柄赋值给hAndleTimer
		}
		for (int i = 0; i < 3; i++) 
			for (int j = 0; j < 20; j++) 
				if (ColorFlage[i][j] == 3)
					tmpCount++;
		stringstream tmpus;
		string tmpstr;
		tmpus << tmpCount;
		tmpus >> tmpstr;//输入错误字数计数
		wchar_t * tmp3 = ConvertLPSTRtoLPWSTR(tmpstr.c_str());
		SetDlgItemText(hWndGameView, ErCount, tmp3);
		delete[] tmp3;
		if (MOVE == 20) {//换行
			if (NUMBEREDIT == 3) {//当焦点在第三个输入框
				TxtInfo.ViewStart = TxtInfo.ViewEnd;
				TxtInfo.ViewEnd = TxtInfo.ViewEnd + 60;
				InitTxt();//初始化
				InvalidateRect(hWndGameView, 0, true);//更新窗口
				UpdateWindow(hWndGameView);
			}
			TxtInfo.PartBuffer[0] = 0;
			TmpChar = 0;
			MOVE = 0;
			RowGrow(NUMBEREDIT);
			SetFocus(hWndEdit[NUMBEREDIT - 1]);
		}
		wchar_t tmplater[2];
		int seek = 0;
		if (wWord == 8) {
			for (; TxtInfo.PartBuffer[seek] != 0; seek++);
			if (!seek)
				TxtInfo.PartBuffer[0] = 0;
			else {
				TxtInfo.PartBuffer[seek - 1] = 0;
			}
		}
		else {
			tmplater[0] = TmpChar;
			tmplater[1] = 0;
			wcscat_s(TxtInfo.PartBuffer, tmplater);
			for (; TxtInfo.PartBuffer[seek] != 0; seek++);
		}
		if (NUMBEREDIT == 1) {
			SetDlgItemText(hWndGameView, EditInput3, L"");
		}
		SetDlgItemText(hWndGameView, EditInput1 + (NUMBEREDIT - 1), TxtInfo.PartBuffer);
		SendMessage(hWndEdit[NUMBEREDIT - 1], EM_SETSEL, seek, seek);
		SendMessage(hWndProgressBar, PBM_SETPOS, (WPARAM)TxtInfo.MoveAddress, 0);
		double tmpBar = ((double)TxtInfo.MoveAddress / (double)TxtInfo.TXTSIZE);
		int tmpView = (int)(tmpBar * 100);
		wchar_t viewint[10];
		viewint[0] = 0;
		_itow_s(tmpView, viewint, 10);
		SetDlgItemText(hWndGameView, PgIndex, viewint);
		if (TxtInfo.MoveAddress == TxtInfo.TXTSIZE) {
			InitTxt();
			MOVE = 0;
			NUMBEREDIT = 1;
			TxtInfo.PartBuffer[0] = 0;
			TxtInfo.MoveAddress = 0;
			InvalidateRect(hWndStart, 0, true);
			UpdateWindow(hWndStart);
			MessageBox(hWndGameView, L"congratulation!", L"Caution", MB_OK);
			ShowWindow(hWndStart, SW_SHOW);//GameView对话框已经创建,将它显示出来
			EndDialog(hWndGameView, 0);
		}
	}
	else {
		MessageBox(hWndGameView, L"Error!", L"Caution", MB_OK);
		ShowWindow(hWndStart, SW_SHOW);
		EndDialog(hWndGameView, 0);
	}
	return;
}
LRESULT CALLBACK EditProc1(HWND hWnd, UINT message,
	WPARAM wParam, LPARAM lParam)
{
	CallWindowProc(g_Edit[0], hWnd, message, wParam, lParam);
	switch (message)
	{
	case WM_CHAR:
		DealEditCallBack(wParam);
		break;
	}
	return 0;
}
void RdviewFile() {
	wchar_t * TmpCurrentPathB = GetCurrentPath(L"MyResource\\");//exe所在绝对路径
	wcscat_s(TmpCurrentPathB, MAX_PATH, SELECTEDTXT);
	HANDLE MFILE = CreateFile(TmpCurrentPathB, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);//windowsAPT获取文件句柄
	int Msize = GetFileSize(MFILE, 0);//获取文件大小
	if (Msize > 0) {
		char *Mtxt = new char[Msize + 1];//为缓冲区申请内存
		DWORD Mbyte;//out读取文件的实际大小
		ReadFile(MFILE, Mtxt, Msize, &Mbyte, 0);//读取文件保存到缓冲区
		Mtxt[Msize] = 0;//为结尾赋零
		int unicodelen = MultiByteToWideChar(CP_ACP, 0, Mtxt, -1, 0, 0);
		wchar_t * pUnicode;//定义U码指针
		pUnicode = new wchar_t[unicodelen];//申请U码缓冲区
		MultiByteToWideChar(CP_ACP, 0, Mtxt, -1, pUnicode, unicodelen);//ANSI转换宽字节
		TxtInfo.TXTCONTENT = pUnicode;
		TxtInfo.TXTSIZE = unicodelen;//字符数
	}
	else {
		TxtInfo.TXTCONTENT = 0;
		TxtInfo.TXTSIZE = 0;
	}
	CloseHandle(MFILE);
	return;
}
void RefreshList(HWND lview) {
	wchar_t * TmpCurrentPathC = GetCurrentPath(L"MyResource");//exe所在绝对路径
	char * filePath = ConvertLPWSTRToLPSTR(TmpCurrentPathC);
	vector<string> files;
	getFiles(filePath, "txt", files);
	int size = files.size(),pos;
	string s;
	LVITEM vitem;
	vitem.mask = LVIF_TEXT;
	SendMessage(lview, LVM_DELETEALLITEMS, 0, 0);
	for (int i = 0; i < size; i++){
		pos = files[i].find_last_of('\\');
		s = (string)(files[i].substr(pos + 1));
		wchar_t * pUnicode = ConvertLPSTRtoLPWSTR(s.c_str());
		vitem.pszText = pUnicode;
		vitem.iItem = i;
		vitem.iSubItem = 0;
		SendMessage(lview, LVM_INSERTITEM, i, (long)&vitem);
		delete[] pUnicode;
	}
	delete[] filePath;
}
VOID OnPaint(HDC hdc)
{
	Graphics graphics(hdc);
	FontFamily  fontFamily(L"Arial");
	Font        font(&fontFamily, SizeFont, FontStyleRegular, UnitPixel);
	PointF      pointFA((PointX), PointY);
	SolidBrush  solidBrush(GreyFont);
	SolidBrush solidBrush1(Color(255, 255, 255, 255));
	Pen solidBrush2(Color(255, 0, 0, 0));
	int nowaddress = TxtInfo.ViewStart;
	int ColumnNum = 20,ColorController=0;
	graphics.FillRectangle(&solidBrush1, 46, 95, 633, 40);
	graphics.DrawRectangle(&solidBrush2, 46, 95, 633, 82);
	graphics.FillRectangle(&solidBrush1, 46, 205, 633, 40);
	graphics.DrawRectangle(&solidBrush2, 46, 205, 633, 82);
	graphics.FillRectangle(&solidBrush1, 46, 315, 633, 40);
	graphics.DrawRectangle(&solidBrush2, 46, 315, 633, 82);
	if (EnglishOrChinese) {
		ColumnNum = 20;
	}
	else {
		ColumnNum = 20;
	}
	for (int p = 1; p < 4; p++) {
		pointFA.X = PointX;
		MeasureStringIntervel=0;
		for (int i = 0; i<ColumnNum; i++) {
			if (TxtInfo.MoveAddress <= TxtInfo.TXTSIZE) {
				if (TxtInfo.TXTCONTENT!=NULL) {
					wchar_t tmpwchar = TxtInfo.TXTCONTENT[nowaddress++];
					switch (ColorFlage[p - 1][i]) {
					case 1:
						solidBrush.SetColor(GreyFont);
						break;
					case 2:
						solidBrush.SetColor(BlueFont);
						break;
					case 3:
						solidBrush.SetColor(RedFont);
						break;
					}
					if (tmpwchar == 10) {//换行符
						tmpwchar = 32;//空格符
					}
					if (EnglishOrChinese) {
						graphics.DrawString(&tmpwchar, 1, &font, pointFA, &solidBrush);
						pointFA.X = (PointX)+(SizeFont)*(i + 1) + (float)(i + 1);
						
					}
					else {
						Font        font2(&fontFamily, SizeFont-10, FontStyleRegular, UnitPixel);
						RectF boundRect;
						graphics.DrawString(&tmpwchar, 1, &font2, pointFA, &solidBrush);
						graphics.MeasureString(&tmpwchar, 1, &font2, pointFA, &boundRect);
						//graphics.DrawRectangle(&Pen(Color(255, 0, 0, 0)), boundRect.X, boundRect.Y, boundRect.Width, boundRect.Height);
						MeasureStringIntervel = MeasureStringIntervel + boundRect.Width;
						pointFA.X = (PointX)+MeasureStringIntervel;
					}
				}
			}else {
				i = ColumnNum+1, p = 5;
			}
			if (nowaddress == (TxtInfo.TXTSIZE - 1)) {
				i = ColumnNum+1, p = 5;//此时为字符结尾
			}
		}
		pointFA.Y = PointY + INTERVAL*p;
	}
	if (hAndleTimer) {
		Font        font1(&fontFamily, 12.0f, FontStyleRegular, UnitPixel);
		solidBrush.SetColor(Color(255, 0, 0, 0));
		pointFA.X = 620;
		pointFA.Y = 42;
		SolidBrush solidBrush3(Color(255, 255, 255, 255));
		graphics.DrawRectangle(&solidBrush2, 620, 42, 55, 15);
		graphics.FillRectangle(&solidBrush3, 620, 42, 55, 15);
		graphics.DrawString(TimePane, 8, &font1, pointFA, &solidBrush);
	}
}
BOOL CALLBACK DlgGame(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
	hWndGameView = hWnd;
	HDC          hdc;
	PAINTSTRUCT  ps;
	switch (message){
	case WM_PAINT: {
		hdc = BeginPaint(hWnd, &ps);
		OnPaint(hdc);
		EndPaint(hWnd, &ps);
		return 0;
	}
	case WM_CLOSE:{//当点击×时候执行结束函数
		hAndleTimer = 0;//结束线程
		CloseHandle(hAndleTimer);
		ShowWindow(hWndStart, SW_SHOW);//GameView对话框已经创建,将它显示出来
		EndDialog(hWnd, 0);//结束对话框
		return 0;
	}
	}
	return FALSE;
}
BOOL CALLBACK DlgMain(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
	HWND hListview=NULL;
	hListview = GetDlgItem(hWnd, ListBox);//
		hWndStart = hWnd;
	switch (message){
	case WM_CLOSE:{//当点击×时候执行结束函数
		if (TxtInfo.TXTCONTENT) {
			delete[] TxtInfo.TXTCONTENT;
		}
		EndDialog(hWnd, 0);
		return 0;
	}
	case WM_COMMAND:{
		switch (LOWORD(wParam)){
		case E_ADD: {//当点击Add时
			TCHAR szBuffer[MAX_PATH] = { 0 };
			OPENFILENAME ofn = { 0 };
			ofn.lStructSize = sizeof(ofn);
			ofn.hwndOwner = 0;
			ofn.lpstrFilter = TEXT("txt文件(*.txt)\0*.txt\0");//要选择的文件后缀    
			ofn.lpstrFile = szBuffer;//存放文件的缓冲区   
			ofn.nMaxFile = sizeof(szBuffer) / sizeof(*szBuffer);
			ofn.nFilterIndex = 0;
			ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ALLOWMULTISELECT;//标志如果是多选要加上OFN_ALLOWMULTISELECT  
			GetOpenFileName(&ofn);//此时打开文件选择框,不关闭此对话框,此函数不返回
			//上面函数如果不在当前路径操作,会改变当前路径
			int i = (int)ofn.nFileOffset,j=0;
			wchar_t ExitFile[MAX_PATH] = { 0 };
			for (; j < i; j++) {
				if (szBuffer[j] == 0) {
					ExitFile[j] = '\\';
					ExitFile[j + 1] = 0;
					break;
				}
				ExitFile[j] = szBuffer[j];
				ExitFile[j + 1] = 0;
			}//获取除文件名外的路径	
			while (1) {
				int p = 0;//循环,一次复制一个文件
				wchar_t ExitCopy[MAX_PATH] = { 0 };//初始化 选择文件路径的临时变量
				wchar_t NameFile[MAX_PATH] = { 0 };//文件名
				wcscpy_s(ExitCopy, MAX_PATH, ExitFile);//将ExitFile内容赋值给ExitCopy
				int q = j;//保存当前j值
				for (; szBuffer[i] != 0; i++) {
					ExitCopy[j++] = szBuffer[i];
					NameFile[p++] = szBuffer[i];
				}//给临时变量ExitCopy添加上文件名,将文件名保存进NameFile,用于CurrentPath
				NameFile[p] = 0;//处理结尾
				ExitCopy[j] = 0;
				j = q;//让j变会原来值以确保下次可以从文件名结尾赋值
				wchar_t * TmpCurrentPathD = GetCurrentPath(L"MyResource\\");//exe所在绝对路径
				wcscat_s(TmpCurrentPathD, MAX_PATH, NameFile);//给路径添加文件名
				if (!CopyFile(ExitCopy, TmpCurrentPathD, FALSE))//CopyFile失败返回0
					return 0;//失败退出
				if (szBuffer[++i] == 0)//如果szBuffer下一位还是0则说明没有选中文件了结束循环
					break;
			}
			RefreshList(hListview);//刷新listitem显示列表
			break;
		}
		case ID_MENU_FLAG_ENGLISH: {//点击菜单Switch to English
			EnglishOrChinese = false;//转换成英文
			EditFontController(SizeFont-(float)5);
			EnableMenuItem(hMeStartM, ID_MENU_FLAG_ENGLISH, MF_GRAYED);//将英文设为灰色
			EnableMenuItem(hMeStartM, ID_MENU_FLAG_CHINESE, MF_ENABLED);//将中文设为可用
			DrawMenuBar(hWnd);
			break;
		}
		case ID_MENU_FLAG_CHINESE: {//点击菜单Switch to English
			EnglishOrChinese = true;//转换成中文
			EditFontController(SizeFont);
			EnableMenuItem(hMeStartM, ID_MENU_FLAG_ENGLISH, MF_ENABLED);//将英文设为可用
			EnableMenuItem(hMeStartM, ID_MENU_FLAG_CHINESE, MF_GRAYED);//将中文设为灰色
			break;
		}
		case R_DELETE: {
			wchar_t * TmpCurrentPathE = GetCurrentPath(L"MyResource\\");//exe所在绝对路径
			wcscat_s(TmpCurrentPathE,MAX_PATH, SELECTEDTXT);
			DeleteFile(TmpCurrentPathE);
			RefreshList(hListview);//刷新listitem显示列表
			SECFLAG = false;
			wcharTXT[0] = 0;
			SetDlgItemText(hWnd, ChoiceText, L"");
			break;
		}
		case R_DELETEALL: {
			wchar_t * TmpCurrentPathF = GetCurrentPath(L"MyResource");//exe所在绝对路径
			char *filePath = ConvertLPWSTRToLPSTR(TmpCurrentPathF);
			wchar_t * TmpCurrentPathG = GetCurrentPath(L"MyResource\\");//exe所在绝对路径
			vector<string> files;
			getFiles(filePath, "txt", files);
			int size = files.size(),pos;
			string s;
			for (int i = 0; i < size; i++){
				wchar_t ExitCopy[MAX_PATH] = { 0 };//初始化 选择文件路径的临时变量
				wchar_t *tmppath = ConvertLPSTRtoLPWSTR(filePath);
				wcscpy_s(ExitCopy, MAX_PATH, TmpCurrentPathG);//将ExitFile内容赋值给ExitCopy
				pos = files[i].find_last_of('\\');
				s = (string)(files[i].substr(pos + 1));
				wchar_t * pUnicode = ConvertLPSTRtoLPWSTR(s.c_str());
				wcscat_s(ExitCopy, MAX_PATH, pUnicode);//
				DeleteFile(ExitCopy);
				delete[] tmppath;
				delete[] pUnicode;
			}
			RefreshList(hListview);//刷新listitem显示列表
			SECFLAG = false;
			wcharTXT[0] = 0;
			SetDlgItemText(hWnd, ChoiceText, L"");
			delete[] filePath;
			break;
		}
		case MENU_WEB: {
			ShellExecute(NULL, NULL, L"http://www.roofso.com/", NULL, NULL, SW_SHOWNORMAL);
			break;
		}
		case MENU_About: {
			MSGBOXPARAMS mbp;
			mbp.cbSize = sizeof(MSGBOXPARAMS);
			mbp.hwndOwner = hWnd;
			mbp.hInstance = hInstanceMain;
			mbp.lpszText = L"RoofType is a game for fun.Brief and Green is its characteristic.At first I just want to excercise myself,but I think why not make a software.It also has a lot BUG,we will make it better together.\nWEB:www.roofso.com\nAuthor:Caeser";
			mbp.lpszCaption = L"About RoofType";
			mbp.dwStyle = MB_USERICON;
			mbp.lpszIcon = MAKEINTRESOURCE(roofsologo);
			mbp.dwContextHelpId = 0;
			mbp.lpfnMsgBoxCallback = NULL;
			mbp.dwLanguageId = 0;
			MessageBoxIndirect(&mbp);
			break;
		}
		case StartButton: {
			if (SECFLAG) {
				ShowWindow(hWndGameView, SW_SHOW);//GameView对话框已经创建,将它显示出来
				ShowWindow(hWndStart, SW_HIDE);
				SetDlgItemText(hWndGameView, TxtContent, SELECTEDTXT);//对该对话框的EditControl设置Text
				SendMessage(hWndProgressBar, PBM_SETPOS, 0, 0);
				InitTxt();
				TxtInfo.MoveAddress = 0;
				TxtInfo.ViewStart = 0;
				TxtInfo.ViewEnd = 60;
				TxtInfo.PartBuffer[0] = 0;
				NUMBEREDIT = 1;
				MOVE = 0;
				ErrorCount = 0;
				RdviewFile();
				SendMessage(hWndProgressBar, PBM_SETRANGE32, 0, TxtInfo.TXTSIZE);//MAKELPARAM(0, TxtInfo.size)
				SendMessage(hWndProgressBar, PBM_SETSTEP, (WPARAM)1, 0);
				SetFocus(hWndEdit[0]);
			}else 
				MessageBox(hWnd, L"Please choose text!", L"Tipe", MB_OK);
			break;
		}
		default:
			break;
		}
		break;
	}
	case WM_INITDIALOG: {
		// 设置ListView的列  
		LVCOLUMN vcl;
		vcl.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
		// 第一列  
		vcl.pszText = L"Title";//列标题  
		vcl.cx = 260;//列宽  
		vcl.iSubItem = 2;//子项索引,第一列无子项  
		SendMessage(hListview, LVM_INSERTCOLUMN, 0, (long)&vcl);//消息//ListView_InsertColumn(hListview, 0, &vcl);//宏	
		SendMessage(hListview, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);//更改item样式
		RefreshList(hListview);//刷新listitem显示列表
		hWndGameView = 0;
		CreateDialog(hInstanceMain, MAKEINTRESOURCE(ID_DIG_GAMEVIEW), NULL, DlgGame);//创建GameView对话框,但是隐藏它,并且返回
		EditFontController(SizeFont);//设置输入框字体大小
		hWndProgressBar = GetDlgItem(hWndGameView, UpgBar);
		hWndPgIdex = GetDlgItem(hWndGameView, PgIndex);
		g_Edit[0] = (WNDPROC)SetWindowLong(hWndEdit[0], GWL_WNDPROC, (LONG)EditProc1);
		g_Edit[0] = (WNDPROC)SetWindowLong(hWndEdit[1], GWL_WNDPROC, (LONG)EditProc1);
		g_Edit[0] = (WNDPROC)SetWindowLong(hWndEdit[2], GWL_WNDPROC, (LONG)EditProc1);
		SetMenu(hWnd, LoadMenu(hInstanceMain, MAKEINTRESOURCE(ID_MENU_STARTMENU)));
		hMeStartM = GetMenu(hWnd);
		break;
	}
	case WM_NOTIFY:{
		switch (LOWORD(wParam)){
		case ListBox: {
			if (((LPNMHDR)lParam)->code == NM_CLICK) {//ITEMCHANGED
				LVITEM litem;
				wchar_t buf[MAXLEN];
				buf[0] = 0;
				int iItem = ((LPNMITEMACTIVATE)lParam)->iItem;
				int iSubItem = ((LPNMITEMACTIVATE)lParam)->iSubItem;
				if (iItem != -1) {
					litem.iSubItem = 0;
					litem.pszText = buf;
					litem.cchTextMax = MAXLEN;
					SendMessage(hListview, LVM_GETITEMTEXT, iItem, (long)&litem);
					wcscpy_s(SELECTEDTXT, MAXLEN, litem.pszText);
					SetDlgItemText(hWnd, ChoiceText, litem.pszText);
					SECFLAG = true;
				}else {
					if (!SECFLAG) 
						MessageBox(hWnd, L"Please choose text!", L"Tipe", MB_OK);
				}
			}else
				if (((LPNMHDR)lParam)->code == NM_DBLCLK) {
					if (SECFLAG) {
						int p = GetLastError();
						ShowWindow(hWndGameView, SW_SHOW);//GameView对话框已经创建,将它显示出来
						SetDlgItemText(hWndGameView, TxtContent, SELECTEDTXT);//对该对话框的EditControl设置Text
						SendMessage(hWndProgressBar, PBM_SETPOS, 0, 0);
						InitTxt();
						TxtInfo.MoveAddress = 0;
						TxtInfo.ViewStart = 0;
						TxtInfo.ViewEnd = 60;
						TxtInfo.PartBuffer[0] = 0;
						NUMBEREDIT = 1;
						MOVE = 0;
						ErrorCount = 0;
						RdviewFile();
						SendMessage(hWndProgressBar, PBM_SETRANGE32, 0, TxtInfo.TXTSIZE);//MAKELPARAM(0, TxtInfo.size)
						SendMessage(hWndProgressBar, PBM_SETSTEP, (WPARAM)1, 0);
						SetFocus(hWndEdit[0]);
						ShowWindow(hWndStart, SW_HIDE);
					}
				}else if (((LPNMHDR)lParam)->code == NM_RCLICK) {
					LVITEM litem;
					wchar_t buf[MAXLEN];
					int iItem = ((LPNMITEMACTIVATE)lParam)->iItem;
					int iSubItem = ((LPNMITEMACTIVATE)lParam)->iSubItem;
					if (iItem != -1) {
						litem.iSubItem = 0;
						litem.pszText = buf;
						litem.cchTextMax = MAXLEN;
						SendMessage(hListview, LVM_GETITEMTEXT, iItem, (long)&litem);
						wcscpy_s(SELECTEDTXT, MAXLEN, litem.pszText);
						SetDlgItemText(hWnd, ChoiceText, litem.pszText);
						SECFLAG = true;
						HMENU TMPmenu1 = LoadMenu(hInstanceMain, MAKEINTRESOURCE(ID_MENU_RIGHTCLICK));
						TMPmenu1 = GetSubMenu(TMPmenu1, 0);
						POINT TMPp;
						GetCursorPos(&TMPp);
						//ScreenToClient(hWnd, &TMPp);
						TrackPopupMenu(TMPmenu1, TPM_LEFTALIGN | TPM_RIGHTBUTTON, TMPp.x, TMPp.y, 0, hWnd, NULL);

					}
				}
		}//case ListBox
		}//switch (LOWORD(wParam))
		break;
	}
	default:
		break;
	}
	return FALSE;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
	//主函数,从这里开始执行,调用DialogBox函数MAKEINTRESOURCE(IDD_DIALOG1),括号内是对话框的名称
	MeasureStringIntervel = 0;
	TxtInfo.MoveAddress = 0;
	TxtInfo.ViewStart = 0;
	TxtInfo.ViewEnd = 60;
	TxtInfo.PartBuffer[0] = 0;
	hAndleTimer = 0;//事件句柄
	hInstanceMain = hInstance;
	wcharTXT[0] = 0;
	SELECTEDTXT = wcharTXT;
	ErrorCount = 0;
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
	EnglishOrChinese = true;//中英转换标志为中文
	DialogBox(hInstance, MAKEINTRESOURCE(ID_MENU_STARTMENU), NULL, DlgMain);
	GdiplusShutdown(gdiplusToken);
	return 0;
}

Constant.h



#include"Header.h"HINSTANCE hInstanceMain;//打开游戏界面用到的句柄LPWSTR SELECTEDTXT=NULL;//已选择文本信息BOOL SECFLAG=false;//是否已选择文本wchar_t wcharTXT[MAXLEN];//保存文本信息缓冲区HWND hWndGameView;//打字游戏界面句柄HWND hWndEdit[3];//文本控件句柄HWND hWndProgressBar;//进度条句柄HWND hWndPgIdex;//显示进度条半分比HWND hWndStart;//开始界面句柄HANDLE hAndleTimer;//计时线程句柄wchar_t TimePane[8];//显示时间int CountSecond;//用于计算时间GdiplusStartupInput gdiplusStartupInput;//绘图ULONG_PTR           gdiplusToken;//绘图WNDPROC g_Edit[1];//EditControl回调BOOL FlagBack = false;//判断退格符RECT AimRect;//更新用的矩形区域Color GreyFont(145, 145, 145);//No.1Color BlueFont(0, 0, 255);//No.2Color RedFont(220, 20, 60);//No.3const int GreyNUMBER = 1;//灰色字体的FLAGconst int BlueNUMBER = 2;//蓝色字体的FLAGconst int RedNUMBER = 3;//红色字体的FLAGconst int ChineseBYTE = 2;//调整字体显示的偏移量const int EnglishBYTE = 1;//调整字体显示的偏移量int NUMBEREDIT = 1;//当前获得焦点的文本控件IDfloat SizeFont = 30.0f;//字体大小const float PointX = 46.0f;//EditControl在Dlag上的Y轴const float PointY = 100.0f;//EditControl在Dlag上的Y轴const float INTERVAL = 110.0f;//两个EditControl间隔int ColorFlage[][20] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,						 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,						 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};//显示在文本控件字符【中文】int ErrorCount;long RECTX = 54L;//跟新矩形区域的X值long RECTA = 30L;//更新矩形区域的位移值int MOVE = 0;//记录当前输入量struct TXTINFO{
	int ViewStart;	int ViewEnd;	int MoveAddress;	wchar_t *TXTCONTENT;	wchar_t PartBuffer[20];	int TXTSIZE;
}TxtInfo;
BOOL EnglishOrChinese;//中英转换HMENU hMeStartM;//STARTVIEW的菜单float MeasureStringIntervel;//文字间距

Header.h



#include<Windows.h>#include<stdio.h>#include "resource.h"#include <string>#include <io.h>#include <vector>#include"commctrl.h"#include <objidl.h>#include <gdiplus.h>#include <sstream>#include<tchar.h>#include "mmsystem.h"//导入声音头文件  #pragma comment(lib,"winmm.lib")//导入声音头文件库using namespace Gdiplus;#pragma comment (lib,"Gdiplus.lib")#define MAXLEN 1024using namespace std;char* ConvertLPWSTRToLPSTR(LPWSTR lpwszStrIn);wchar_t* ConvertLPSTRtoLPWSTR(const char * lpStrIn);BOOL CALLBACK DlgMain(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);void getFiles(string path, string exd, vector<string>& files);void RowGrow(int & source);






0人推荐
随时随地看视频
慕课网APP