C++ 纯WIN32 API编程 悦读器实战示例

 /* 最后修改:2020-09-21 14:04
《C++编程示例大全》 作者:张国鹏

本例功能:C++ 纯WIN32 API编程 悦读器实战示例
软件下载:http://lovegp.cn/gpbook.exe


本书撰写及整理:张国鹏 2020年6月22日

c++win32程序编译环境搭建

使用语言:C++11
编辑工具:Notepad++ v7.8.5 下载地址:https://notepad-plus-plus.org/downloads/
编译工具:tdm-gcc-5.1.0-3(32位)下载地址:https://jmeubank.github.io/tdm-gcc/

安装好以上软件即搭建完成!

注意事项:本书所载代码均为ANSI格式,切勿转为UTF-8格式,否则可能造成不可预料的结果!


Notepad++快速运行代码:按F5,输入以下指令,即可编译并运行C++ WIN32程序:
方式一:cmd /k cd /d "$(CURRENT_DIRECTORY)" & g++ -std=gnu++11 "$(FILE_NAME)" -o "$(NAME_PART)" &  "$(NAME_PART).exe
方式二:cmd /k cd /d "$(CURRENT_DIRECTORY)" & g++ -std=gnu++11 "$(FILE_NAME)" -o "$(NAME_PART)"  -static-libgcc -lgdi32 -lcomdlg32 -lgdiplus -lwininet -lwinmm -lwinspool & "$(NAME_PART).exe

如果程序含有windows.h以外的库,则用方式二编译即可。
如果不需要CMD窗口出现,编译指令加上这句:-mwindows

编译指令加上这句:-std=gnu++11,即采用c++11编译

声明:书中所有例子部份为本人亲自码出,部份自网上收集整理,如有涉及版权,请联系作者,Email:[email protected]
修改日志:
    2020-09-21 22:03 增加了ftp上传下载文件时显示进度条,采取线程技术进行进度显示;
*/

 /* 最后修改:2020-09-21 14:04
《C++编程示例大全》 作者:张国鹏

本例功能:C++ 纯WIN32 API编程 悦读器实战示例
软件下载:http://lovegp.cn/gpbook.exe


本书撰写及整理:张国鹏 2020年6月22日

c++win32程序编译环境搭建

使用语言:C++11
编辑工具:Notepad++ v7.8.5 下载地址:https://notepad-plus-plus.org/downloads/
编译工具:tdm-gcc-5.1.0-3(32位)下载地址:https://jmeubank.github.io/tdm-gcc/

安装好以上软件即搭建完成!

注意事项:本书所载代码均为ANSI格式,切勿转为UTF-8格式,否则可能造成不可预料的结果!


Notepad++快速运行代码:按F5,输入以下指令,即可编译并运行C++ WIN32程序:
方式一:cmd /k cd /d "$(CURRENT_DIRECTORY)" & g++ -std=gnu++11 "$(FILE_NAME)" -o "$(NAME_PART)" &  "$(NAME_PART).exe
方式二:cmd /k cd /d "$(CURRENT_DIRECTORY)" & g++ -std=gnu++11 "$(FILE_NAME)" -o "$(NAME_PART)"  -static-libgcc -lgdi32 -lcomdlg32 -lgdiplus -lwininet -lwinmm -lwinspool & "$(NAME_PART).exe

如果程序含有windows.h以外的库,则用方式二编译即可。
如果不需要CMD窗口出现,编译指令加上这句:-mwindows

编译指令加上这句:-std=gnu++11,即采用c++11编译

声明:书中所有例子部份为本人亲自码出,部份自网上收集整理,如有涉及版权,请联系作者,Email:[email protected]。
修改日志:
	2020-09-21 22:03 增加了ftp上传下载文件时显示进度条,采取线程技术进行进度显示;
*/

#include    //GetModuleFileName, GetCurrentDirectory,GetWindowsDirectory, GetSystemDirectory
#include 
#include 
#include //wininet.lib ftp http等要用的头文件,同时在GCC时,要这样链接:gcc -o a a.o resource.o -static-libgcc -lgdi32 -lcomdlg32 -lwininet,编译前要将wininet.lib文件找到,并拷到GCC\LIB目录下才可正常编译!
#include //不用这个头文件也行噢 Commdlg.h 文件里封装了 Windows 公用对话框(比如打开文件,保存文件,打印相关等对话框)的 API,包含了这个头文件以后,就可以在单元中使用公用对话框相关的函数和结构定义等。
#include //winmm.lib-PlaySound播放声音要用到 不用这个头文件也行噢
#include "resource.h"
#include //wprintf, printf,sprintf
#include //这是支持打印的头文件,库文件是:winspool.lib,要把这个文件复制到d:\gcc\lib,编译时:gcc -o a a.o resource.o -static-libgcc -lgdi32 -lcomdlg32 -lwininet -lwinspool
#include 
#include 
#include 
#include //进程操作

#include  //MSSQL数据库操作 这个应该是必须的, 链结时需要odbc32.lib
#include  
#include  

/*这是VC的预编译语句,在GCC里是不能用的 
#pragma comment(lib, "wininet.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "comdlg32.lib") */

using namespace std;//注意一定要写这句

//控件ID

#define ID_TIMER1 10011
#define ID_TIMER2 10012

#define IDD_TEXT1 1002
#define IDD_TEXT2 1003
#define IDD_TEXT3 1004
#define IDD_TEXT4 1005
#define IDD_TEXT5 10051
#define IDD_TEXT6 10052
#define IDD_TEXT7 10053
#define IDD_TEXT8 10054
#define IDD_TEXT9 10055
#define IDD_TEXT10 10056
#define IDD_TEXT11 10057
#define IDD_TEXT12 10058
#define IDD_TEXT13 10058


#define IDD_EDIT1 1006
#define IDD_EDIT2 1007
#define IDD_EDIT3 10071
#define IDD_EDIT4 10072
#define IDD_EDIT5 10073
#define IDD_EDIT7 10074
#define IDD_EDIT8 10075
#define IDD_EDIT9 10076
#define IDD_EDIT10 10077
#define IDD_EDIT11 10078

#define IDD_LISTBOX1 1008
#define IDD_LISTBOX2 1009

#define IDD_BUTTON1 10091
#define IDD_BUTTON2 1010
#define IDD_BUTTON3 1011
#define IDD_BUTTON4 1012
#define IDD_BUTTON5 1013
#define IDD_BUTTON6 1014
#define IDD_BUTTON7 1015
#define IDD_BUTTON8 1016
#define IDD_BUTTON9 1017
#define IDD_BUTTON10 1018

#define IDD_TALK2_BROUPBOX1 2001
#define IDD_TALK2_BROUPBOX2 20011
#define IDD_TALK2_LISTBOX1 2002
#define IDD_TALK2_LISTBOX2 20021
#define IDD_TALK2_TEXT1  2003
#define IDD_TALK2_TEXT2  20031
#define IDD_TALK2_BUTTON1  2004
#define IDD_TALK2_BUTTON2  2005
#define IDD_TALK2_EDIT1  2006

#define IDD_TALK3_MEMO1  2007
#define IDD_TALK3_BUTTON1  2008

#define IDD_TALK4_BROUPBOX1  2009
#define IDD_TALK4_TEXT1  2010
#define IDD_TALK4_TEXT2  2011
#define IDD_TALK4_EDIT1  2012
#define IDD_TALK4_EDIT2  2013
#define IDD_TALK4_BUTTON1  2014
#define IDD_TALK4_BUTTON2  2015
#define IDD_TALK4_BUTTON3  2016

#define IDD_TALK5_LISTBOX1  2017

#define IDD_TALK6_MEMO1  2018

#define IDD_TALK7_LISTBOX1  2019
#define IDD_TALK7_TEXT1  2020
#define IDD_TALK7_EDIT1  2021

/托盘程序所用参数定义///
#define WM_TRAY (WM_USER + 100)//托盘消息
#define WM_TASKBAR_CREATED RegisterWindowMessage(TEXT("TaskbarCreated"))
#define IDI_TRAY	9100//ico


NOTIFYICONDATA nid;		//托盘属性
HMENU hMenu;			//托盘菜单
//HWND MAIN_hwnd;
/托盘程序所用参数定义///






//控件句柄
HWND KJ_EDIT1;
HWND KJ_EDIT2;
HWND KJ_EDIT3;
HWND KJ_EDIT4;
HWND KJ_EDIT5;
HWND KJ_EDIT6;
HWND KJ_EDIT7;
HWND KJ_EDIT8;
HWND KJ_EDIT9;
HWND KJ_EDIT10;
HWND KJ_EDIT11;

HWND KJ_LISTBOX1;
HWND KJ_LISTBOX2;

HWND KJ_TEXT1;
HWND KJ_TEXT2;
HWND KJ_TEXT3;
HWND KJ_TEXT4;
HWND KJ_TEXT5;
HWND KJ_TEXT6;
HWND KJ_TEXT7;
HWND KJ_TEXT8;
HWND KJ_TEXT9;
HWND KJ_TEXT10;
HWND KJ_TEXT11;
HWND KJ_TEXT12;
HWND KJ_TEXT13;

HWND KJ_BUTTON1;
HWND KJ_BUTTON2;
HWND KJ_BUTTON3;
HWND KJ_BUTTON4;
HWND KJ_BUTTON5;
HWND KJ_BUTTON6;
HWND KJ_BUTTON7;
HWND KJ_BUTTON8;
HWND KJ_BUTTON9;
HWND KJ_BUTTON10;

HWND KJ_TALK2_BROUPBOX1;
HWND KJ_TALK2_BROUPBOX2;
HWND KJ_TALK2_LISTBOX1;
HWND KJ_TALK2_LISTBOX2;
HWND KJ_TALK2_TEXT1;
HWND KJ_TALK2_TEXT2;
HWND KJ_TALK2_BUTTON1;
HWND KJ_TALK2_BUTTON2;
HWND KJ_TALK2_EDIT1;

HWND KJ_TALK3_MEMO1;
HWND KJ_TALK3_BUTTON1;

HWND KJ_TALK4_BROUPBOX1;
HWND KJ_TALK4_TEXT1;
HWND KJ_TALK4_TEXT2;
HWND KJ_TALK4_EDIT1;
HWND KJ_TALK4_EDIT2;
HWND KJ_TALK4_BUTTON1;
HWND KJ_TALK4_BUTTON2;
HWND KJ_TALK4_BUTTON3;

HWND KJ_TALK5_LISTBOX1;

HWND KJ_TALK6_MEMO1;

HWND KJ_TALK7_LISTBOX1;
HWND KJ_TALK7_TEXT1;
HWND KJ_TALK7_EDIT1;




//全局变量//.


HWND MAIN_hwnd,talk1,talk2,talk3,talk4,talk5,talk6,talk7,talk8,talk9,talk10,about;						//定义窗口类句柄

RECT r;
LOGFONT LogFont;//字体变量

static HFONT hFont,hOldFont,hFont1,hFont2; 
static int cxChar,cyChar,cxChar1,cyChar1;//字符的宽度和高度
static int cxClient; //得到客户区宽度
static int cyClient; //得到客户区高度	

	
bool canedit=false;
int CaretPosx=0, CaretPosy=0;//光标显示的坐标
int CaretPoshang=0, CaretPoslie=0;//光标在文本的行与列位置
int showx1=0,showx2=0,showy=0;//文本显示的的左上角坐标初始值


wstring bookstr;//调入内存的电子书内容
string FileName="";//电子书全称
vector showstr;//当前屏幕正在显示的字符串数组
vector printstr;//当前为打印准备的字符串数组
vector booklist;//保存书本清单


char IniFullPath[MAX_PATH];//用于存放INI文件全路径
char ztname[20];//字体名称

int beginwz,endwz,currentwz;//一页中开始位置beginwz及结束位置endwz,当前光标的位置currentwz
int Lie=0,Hang=0,HJJ=20,wz=0;//列、行、行间距、阅读位置
int ztdx=20;	//字体大小
int ll=1;//显示模式,1=一栏式,2=两栏模式,3=两栏背景图模式

DWORD bjs=0,zts=12632256;//16777215白色;

char inputstr[MAX_PATH];//查找书籍里内容

LONG Oldtalk2editProc,Oldtalk4editProc,oldtalk4buttonproc,Oldtalk6memoProc;

string booknr;//读取网上书籍存临时放在这里
string bookname;//临时书籍名
string bookid="-1";//当前书本ID
string urlpage="1";//书籍清单第几页
string username,password;//用户名及密码
char searchstr[50];

string bjtpath;//背景图路径

char hz[2];int hzi=0;
int workcx=500;//工作区宽度
int workcy=500;//工作区高度
bool havemove=false;//编辑状态下,保存有没有选择文字的移动
int selbhang,selblie,selehang,selelie;//被选中的文本开始行、列及结束行、列
bool haveedit=false;

int BookPreview=1;

int zbj=50;//左右边距
int sbj=50;//上下边距
float sfbl=1;//缩放比例

int printztdx=26;
//线程用的参数
int yx1=0;
DWORD jdtzs=0,jdtss=0;

RECT mrect_one,mrect_two,mrect_tree;//上中下,左中右部份坐标
HINSTANCE hinst;
//自定义函数


// 将指定尺寸的窗口居中显示
void ZGP_windowstoclient(HWND hwnd,int FORMx,int FORMy)
{
	// 将指定尺寸的窗口居中显示
	//使用示例:ZGP_windowstoclient(hwnd,500,500);
	
	//int cx = GetSystemMetrics(SM_CXSCREEN);			//获取屏幕宽度
	//int cy = GetSystemMetrics(SM_CYSCREEN);			//获取屏幕高度
	RECT rt;
	SystemParametersInfo(SPI_GETWORKAREA,   0,   &rt,   0);    // 获得桌面工作区大小

	int cx=rt.right-rt.left;
	int cy=rt.bottom-rt.top;
	int FORMleft = cx - FORMx;
	int FORMtop = cy - FORMy;
	FORMleft = FORMleft / 2;					//新建窗口居中显示
	FORMtop = FORMtop /2;	

	MoveWindow(hwnd,FORMleft,FORMtop,FORMx,FORMy,TRUE);	
} 


//判断目录是否存在
bool dirExists(string dirName_in)
{
  DWORD ftyp = GetFileAttributesA(dirName_in.c_str());
  if (ftyp == INVALID_FILE_ATTRIBUTES)
    return false;  //something is wrong with your path!

  if (ftyp & FILE_ATTRIBUTE_DIRECTORY)
    return true;   // this is a directory!

  return false;    // this is not a directory!
}

//结束指定ID的进程 
BOOL KillProcessById(DWORD pID)
{ 
    HANDLE Hwnd; 
    bool ret = FALSE; 
    Hwnd = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE,0,pID); 
    if (Hwnd) 
    { 
       if (TerminateProcess(Hwnd, 0)) 
       { 
           ret = true; 
       } 
    } 
    return ret; 
} 

//结束指定进程 
void EndProcess(string processstr)
{
	int pid;
	string exefile;
	PROCESSENTRY32 pe32;
	//再使用这个结构体前先定义它的大小
	pe32.dwSize=sizeof(pe32);
	//给系统内的所有进程拍一个快照
	HANDLE hProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	if (hProcessSnap==INVALID_HANDLE_VALUE)
	{
		printf("Create ToolHelp32Snaphhot调用失败!\n");
		return;
	}
	BOOL bMore=::Process32First(hProcessSnap,&pe32);
	while(bMore)
	{
		bMore=::Process32Next(hProcessSnap,&pe32);
		exefile=pe32.szExeFile;
		if (processstr.find(exefile)!=-1)
			pid =pe32.th32ProcessID;
			KillProcessById(pid);
		}
	::CloseHandle(hProcessSnap);


}


//根据文件路径获取文件名称
string getFileNameByFilePath(string filePath){
	int pos = filePath.find_last_of('\\');
	return filePath.substr(pos + 1);
}
 
void createStringReg(HKEY hRoot,char *szSubKey,char* valueName,char *Data) 
{ 
    HKEY hKey; 
    //打开注册表键,不存在则创建它 
    long lRet=RegCreateKeyEx(hRoot,szSubKey,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hKey,NULL); //KEY_ALL_ACCESS
    if (lRet!=ERROR_SUCCESS) 
    { 
		MessageBox(NULL,"操作注册表失败!-打开注册表键","提示",0);
        return ; 
    } 
 
    //修改注册表键值,没有则创建它 
    lRet=RegSetValueEx(hKey,valueName,0,REG_SZ,(BYTE*)Data,strlen(Data)); 
     if (lRet!=ERROR_SUCCESS) 
     { 
         MessageBox(NULL,"操作注册表失败!-修改注册表键值","提示",0);
         return ; 
     } 
    RegCloseKey(hKey); 
} 

//添加开机启动到注册表
void addToAutoRun(string filePath){
	string name = getFileNameByFilePath(filePath);
	createStringReg(HKEY_LOCAL_MACHINE, (char *)"Software\\Microsoft\\Windows\\CurrentVersion\\Run", (char *)name.c_str(), (char *)filePath.c_str());
} 


//判断字符是否是ASCII码字符
bool isAscll(string str)
{
	char *pszStr=(char *)str.c_str();
	if ((pszStr[0] & 0x80 ) == 0x80) 

	{
		return false;
	}else
	{
		return true;
	}
}
void movechinese()
{
					string s=showstr[CaretPoshang];
					int fz1=0;
					int i=0;
					while (s.find("	")!=-1)
					{
						i++;
						fz1=s.find("	");
						s.erase(fz1,1);
					}
					showstr[CaretPoshang]=s;
					string s1;	
/* 					s1=s[CaretPoslie];
					if (isAscll(s1))
					{
						printf("isAscll:%s\n",s1.c_str());
					}else
					{
						s1=s1+s[CaretPoslie+1];
						printf("not isAscll:%s\n",s1.c_str());
						printf("s:%s\n",s.substr(CaretPoslie).c_str());
					} */
					
					
					
					if (CaretPoslie>0 && CaretPoslie<=s.length()-1)
					{

						int count=0;
						int i=0;
						while (iHang-1)
		{
			CaretPosy=showy+(CaretPoshang-Hang)*(cyChar+HJJ);//showy是页面的上距
			CaretPosx=showx2+CaretPoslie*cxChar;//showx2是第2页的页边距-两栏模式
		}else
		{
			CaretPosy=showy+CaretPoshang*(cyChar+HJJ);
			CaretPosx=showx1+CaretPoslie*cxChar;//showx1是第1页的页边距-两栏模式
		}
		movechinese();//判断当前光标位置是不是在汉字的中间,如果是,则光标左移一位
		//InvalidateRect(MAIN_hwnd,NULL,FALSE);//刷新显示结果 TRUE重画时将擦除背景。false重画时不擦除背景
		SetCaretPos (CaretPosx, CaretPosy) ; //将光标设置到指定位置
		
 		//显示行、列信息
		HDC hdc=GetDC(MAIN_hwnd);
		hFont1=CreateFont((char*)"宋体",15);//用于显示信息栏
		HBRUSH hbrush1 = CreateSolidBrush(bjs);//画刷的着色黑色
		SelectObject(hdc,hFont1);//选择字体
		SelectObject( hdc, hbrush1 );//选择画刷
		SetBkMode(hdc,TRANSPARENT);// 设置TextOut文本背景色模式为透明	
		//得到当前字体的高度和宽度
		TEXTMETRIC tm ;
		GetTextMetrics (hdc, &tm) ;
		int cxChar1 = tm.tmAveCharWidth;
		int cyChar1 = tm.tmHeight + tm.tmExternalLeading ;
		SetTextColor(hdc, zts );//设置字体着色8454143
	
SetTextColor(hdc, zts );//设置字体着色8454143
			char ls1[MAX_PATH];
			double zs=(double)endwz/bookstr.length()*100;	
			//获取书名
			char ls2[MAX_PATH];
			int fz=FileName.rfind('\\');//string.rfind  从字符串右边开始找字符,返回位置
			int fz1=FileName.find('.');
			string zs1;
			if (fz1==-1)
			{
				zs1=FileName.substr(fz+1);  // s2 = "is i"			
			}
			else
			{
				zs1=FileName.substr(fz+1,FileName.size()-fz-1-4);  // s2 = "is i"	
			}
			sprintf(ls2,"%s",(char*)zs1.c_str());//书名
			if (canedit)
			{	
				sprintf(ls1,"阅:%.2f%%《%s》行:%d,列:%d 总字数:%d 用户:%s",zs,ls2,CaretPoshang,CaretPoslie,bookstr.size(),username.c_str());
			}else
			{	
				sprintf(ls1,"阅:%.2f%%《%s》用户:%s",zs,ls2,username.c_str());
			}			
			
			int js=strlen(ls1);
			HRGN mrgn;
			mrgn=CreateRectRgn(0,cyClient-18,cxClient,cyClient-18+cyChar1);//376创建一个矩形区域

			FillRgn(hdc,mrgn,hbrush1);//用指定的画刷填充矩形区域	
			//显示信息
			if (ll==3)
			{	
				TextOut(hdc,40,cyClient-18,ls1,js);		//输出到窗口的文本	
			}
			if (ll==1 or ll==2)
			{
				TextOut(hdc,5,cyClient-18,ls1,js);		//输出到窗口的文本	
			}


		DeleteObject(hFont1) ;//必须要删除,不然内存会被吃光		
		DeleteObject(hbrush1) ;//必须要删除,不然内存会被吃光	
		ReleaseDC(MAIN_hwnd,hdc); 
		
	}
}

//编辑BOOKSTR里内容,并刷新显示;
void editbookstr()
{
					wstring bookstrbegin;//变量bookstr的前面部份=bookstr.substr(0,beginwz);
					wstring bookstrend;//变量bookstr的后面部份=bookstr.substr(endwz);
					wstring bookstredit;//当前页面正在编辑的字符
					haveedit=true;
					//for 这部分代码主要是连接当前显示的所有字符,并放入变量BOOKSTREDIT中
					for (int i=0;i=bookstr.length()-1)
					{
						bookstr=bookstredit;
						
					}					
					
					
					//当前位置处于于中间页的情况,总页数>2以上
					if (beginwz>0 && endwz2以上
					if (beginwz>0 && endwz>=bookstr.length()-1)
					{
						bookstrbegin=bookstr.substr(0,beginwz);
													
						bookstr=bookstrbegin+bookstredit;	
						
					}	
					
					

}






//建立托盘图标
void InitTray(HINSTANCE hInstance, HWND hWnd)
{
								/托盘程序所用参数定义///
								/* 
								#define WM_TRAY (WM_USER + 100)//托盘消息
								#define WM_TASKBAR_CREATED RegisterWindowMessage(TEXT("TaskbarCreated"))
								#define IDI_TRAY	9100//ico


								NOTIFYICONDATA nid;		//托盘属性
								HMENU hMenu;			//托盘菜单
								//HWND MAIN_hwnd;
								/托盘程序所用参数定义/// */	
	nid.cbSize = sizeof(NOTIFYICONDATA);
	nid.hWnd = hWnd;
	nid.uID = IDI_TRAY;
	nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP ;//这个不能用| NIF_INFO;
	nid.uCallbackMessage = WM_TRAY;
	nid.hIcon = (HICON) LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 32, 32, LR_SHARED); //也可以用这种方法
	//nid.hIcon = LoadIcon(hInstance,"IDI_ICON1"); //必须要用这种形式,不然不会显示出图标
	lstrcpy(nid.szTip, "悦读器 设计:张国鹏");
 
	hMenu = CreatePopupMenu();//生成托盘菜单
	//为托盘菜单添加两个选项
	AppendMenu(hMenu, MF_STRING, 20, TEXT("关于"));
	AppendMenu(hMenu, MF_STRING, 21, TEXT("退出"));
 
	Shell_NotifyIcon(NIM_ADD, &nid);
}



BOOL Ftp_SaveToFile(const char *pszFileName, BYTE *pData, DWORD dwDataSize)
{
	HANDLE hFile = CreateFile(pszFileName, GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
		FILE_ATTRIBUTE_ARCHIVE, NULL);
	if (INVALID_HANDLE_VALUE == hFile)
		return FALSE;

	DWORD dwRet = 0;
	WriteFile(hFile, pData, dwDataSize, &dwRet, NULL);
	CloseHandle(hFile);
	return TRUE;
}
//运用线程,可以防止程序假死,将大量的长时间的运算工作采取这种模式较好
DWORD WINAPI xc3(LPVOID lpParamter)
{
	HWND hwnd = (HWND) lpParamter;    //进度条的窗口句柄
	HDC hdc=GetDC(hwnd);
				//创建绘画设备 
	HPEN hpen = CreatePen(PS_SOLID, 1, 8421504);//255,100,255
	HBRUSH hbrush1 = CreateSolidBrush(255);//画刷的着色黑色	
	HBRUSH hbrush2 = CreateSolidBrush(16744576);//画刷的着色黑色	
	hFont=CreateFont((char*)"宋体",15);//用于显示信息栏
	SelectObject(hdc, hpen);
	SelectObject(hdc, hbrush2 );
	SelectObject(hdc,hFont);//选择字体	
	GetClientRect (hwnd, &r);
	RECT r1;
	r.right=r.right-2;
	r.left=r.left+2;
	int cxForm=r.right-r.left;//得到界面的宽度
	int cyForm=r.bottom-r.top;//得到界面的高度
    r.top=r.bottom-20;
	r.bottom=r.bottom-1;
	r1=r;
	SetTextColor(hdc, 65535);//设置字体着色
	SetBkMode(hdc,TRANSPARENT);// 设置TextOut文本背景色模式为透明
	DWORD old_jdtss=0;
	while(yx1==1)
	{	
		if (old_jdtss!=jdtss)
		{
			FillRect(hdc,&r1,hbrush2);//用背景画刷以矩形填充整个窗口
			r.right=r.left+cxForm*((double)jdtss/jdtzs);
			FillRect(hdc,&r,hbrush1);//用背景画刷以矩形填充整个窗口
			DrawText(hdc,inputstr,strlen(inputstr),&r1,DT_SINGLELINE | DT_CENTER | DT_VCENTER);
			Sleep(10);
			old_jdtss=jdtss;
		}
		//TextOut(hdc,10,r.bottom-20,inputstr,strlen(inputstr));
		//UpdateWindow(hwnd);	
	}
	FillRect(hdc,&r1,hbrush1);//用背景画刷以矩形填充整个窗口
	DrawText(hdc,inputstr,strlen(inputstr),&r1,DT_SINGLELINE | DT_CENTER | DT_VCENTER);
	DeleteObject(hpen);//删除画笔
	DeleteObject(hbrush1);//删除画笔
	DeleteObject(hbrush2);//删除画笔
	DeleteObject(hFont);//删除画笔
	ReleaseDC(hwnd,hdc);
    return 0L;
}
//ftp下载文件不带进度模式
BOOL ftp_down_file(const char *server, int port, const char *username, const char *password, 
					 const char *szLocalFileName, const char *szFtpFileName,bool debug)
{
	HINTERNET net_session = 0;   
	HINTERNET ftp_session = 0;
	if (debug) printf("正在连接网络.....\n");
	net_session = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); 
	if(0 == net_session) 
	{
		if (debug) printf("[%s]不能连接网络!\n", __FUNCTION__);
		InternetCloseHandle(net_session);
		return FALSE;
	}


	if (debug) printf("正在连接FTP服务器.....\n");
	ftp_session = InternetConnect(net_session, server, port, username, password,INTERNET_SERVICE_FTP, 0, 0);//连接FTP服务器
	if(0 == ftp_session)
	{
		if (debug) printf("[%s]不能连接FTP服务器\n", __FUNCTION__);
		InternetCloseHandle(net_session);
		InternetCloseHandle(ftp_session);			
		return FALSE;
	}
	
	if (debug) printf("开始下载文件...\n");
	bool zs=FtpGetFile(ftp_session,szFtpFileName, szLocalFileName, FALSE,FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY, 0 );//INTERNET_FLAG_TRANSFER_BINARY  FTP_TRANSFER_TYPE_ASCII
   	InternetCloseHandle(ftp_session); 
	InternetCloseHandle(net_session);
	if (debug) printf("已关闭所有连接.....\n");
	return zs;
	
		
		/*
		InternetConnect参数说明编辑
hInternetSession:由InternetOpen返回的句柄。
sServerName:连接的ip或者主机名
nServerPort:连接的端口。如0,则为默认端口。
sUsername :用户名,如无置null
sPassword :密码,如无置null。
lService:使用的服务类型,可以使用以下
INTERNET_SERVICE_FTP = 1:连接到一个 FTP 服务器上
INTERNET_SERVICE_GOPHER = 2
INTERNET_SERVICE_HTTP = 3:连接到一个 HTTP 服务器上
lFlags :文档传输形式及缓存标记。一般置0。待补充。
ftp下:134217728=被动连接,vb有说法是x8000000。
lContext:当使用回叫信号时, 用来识别应用程序的前后关系。
返回值编辑
成功返回非0。如果返回0。要InternetCloseHandle释放这个句柄。
		*/			
		/*
		BOOLAPI FtpGetFileA(
  HINTERNET hConnect,//FTP句柄
  LPCSTR    lpszRemoteFile,//FTP上的文件 
  LPCSTR    lpszNewFile,//本地要保存的文件
  BOOL      fFailIfExists,//如果TRUE,将文件存在时则下载取消,如果FALSE则直接履盖
  DWORD     dwFlagsAndAttributes,//FILE_ATTRIBUTE_NORMAL
  DWORD     dwFlags,//FTP_TRANSFER_TYPE_BINARY
  DWORD_PTR dwContext//0
);
		*/
//示例FtpGetFile( hConnection, szFtpFileName, szLocalFileName, FALSE,FILE_ATTRIBUTE_NORMAL, dwTransferType, 0 ) 
}

//ftp下载文件带进度模式
BOOL ftp_down_file1(HWND hwnd,const char *server, int port, const char *username, const char *password, 
					 const char *szLocalFileName, const char *szFtpFileName,bool debug)
{
	HINTERNET net_session = 0;   
	HINTERNET ftp_session = 0;
	HINTERNET ftp_file = 0;
	BYTE *pDownloadData = NULL;//存放下载文件的缓冲区
	DWORD dwDownloadDataSize = 0;//要下载的文件大小
	DWORD dwBufferSize = 4096;//下载缓冲区大小
	BYTE *pBuf = NULL;//下载缓冲区
	DWORD dwBytesReturn = 0;
	DWORD dwOffset = 0;//偏移量
	BOOL bRet = FALSE;
	
	char temp[50];
	double zs=0;
	
	if (debug) printf("正在连接网络.....\n");
	net_session = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); 
	if(0 == net_session) 
	{
		if (debug) printf("[%s]不能连接网络!\n", __FUNCTION__);
		InternetCloseHandle(net_session);
		return false;
	}


	if (debug) printf("正在连接FTP服务器.....\n");
	ftp_session = InternetConnect(net_session, server, port, username, password,INTERNET_SERVICE_FTP, 0, 0);//连接FTP服务器
	if(0 == ftp_session)
	{
		if (debug) printf("[%s]不能连接FTP服务器\n", __FUNCTION__);
		InternetCloseHandle(net_session);
		InternetCloseHandle(ftp_session);			
		return false;
	}
	
	if (debug) printf("开始下载文件...\n");
	//打开FTP文件,文件操作和本地操作相似
	ftp_file=FtpOpenFile(ftp_session,szFtpFileName,GENERIC_READ,FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_RELOAD,0);
	//获取文件大小
	dwDownloadDataSize=FtpGetFileSize(ftp_file,NULL);
	sprintf(temp,"该文件大小为:%dKB,确定要下载吗?",dwDownloadDataSize/1024);
	
	if (MessageBox(MAIN_hwnd,temp,"提示",MB_YESNO|MB_ICONQUESTION)==IDNO )
	{
		InternetCloseHandle(ftp_session); 
		InternetCloseHandle(net_session);
		if (debug) printf("已关闭所有连接.....\n");
		return false;
	}	
	
	
	//printf("文件大小为:%d\n",dwDownloadDataSize);
	// 申请动态内存
	pDownloadData = new BYTE[dwDownloadDataSize];

	RtlZeroMemory(pDownloadData, dwDownloadDataSize);
	pBuf = new BYTE[dwBufferSize];
	RtlZeroMemory(pBuf, dwBufferSize);
	jdtzs=dwDownloadDataSize;
	jdtss=0;
	// 接收数据
	//InvalidateRect(hwnd,NULL,TRUE);//刷新显示结果 TRUE重画时将擦除背景。false重画时不擦除背景
	yx1=1;
	memset(inputstr, 0, MAX_PATH);//一定要清掉内存,不然会.......	
	HANDLE hThread1	= CreateThread(NULL, 0, xc3, hwnd, 0, NULL);//创建线程	
	// 接收数据
	do
	{
		bRet = InternetReadFile(ftp_file, pBuf, dwBufferSize, &dwBytesReturn);
		if (FALSE == bRet)
		{
			// 释放内存
			delete[]pDownloadData;
			pDownloadData = NULL;
			InternetCloseHandle(ftp_session); 
			InternetCloseHandle(net_session);
			if (debug) printf("已关闭所有连接.....\n");
			yx1=0;
			return false;			

		}
		RtlCopyMemory((pDownloadData + dwOffset), pBuf, dwBytesReturn);
		dwOffset = dwOffset + dwBytesReturn;
		zs=(double)dwOffset/dwDownloadDataSize*100;
		sprintf(inputstr,"下载进度:%.2f%%\n",zs);
		SetWindowText(hwnd,inputstr);
		jdtss=dwOffset;
		//printf("%s\n",inputstr);
	} while (dwDownloadDataSize >dwOffset);
	


	// 将数据保存为文件
	Ftp_SaveToFile(szLocalFileName, pDownloadData, dwDownloadDataSize);
	// 释放内存
	delete[]pDownloadData;
	pDownloadData = NULL;

	//关闭句柄
	InternetCloseHandle(ftp_session); 
	InternetCloseHandle(net_session);
	if (debug) printf("已关闭所有连接.....\n");
	yx1=0;
	return true;
}



//ftp上传文件不带进度模式 
BOOL ftp_upload_file(const char *server, int port, const char *username, const char *password, 
					 const char *localfile, const char *remotefile,bool debug)
 
{
	HINTERNET net_session = 0;   
	HINTERNET ftp_session = 0;

		if (debug) printf("正在连接网络.....\n");
		net_session = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); 
		if(0 == net_session) 
		{
			if (debug) printf("[%s]不能连接网络!\n", __FUNCTION__);
			InternetCloseHandle(net_session);
			return FALSE;
		}

		if (debug) printf("正在连接FTP服务器.....\n");
		ftp_session = InternetConnect(net_session, server, port, username, password, 
			INTERNET_SERVICE_FTP, 0, 0);//连接FTP服务器
		if(0 == ftp_session)
		{
			if (debug) printf("[%s]不能连接FTP服务器\n", __FUNCTION__);
			InternetCloseHandle(ftp_session);			
			return FALSE;
		}
		
		if (debug) printf("开始上传文件...\n");
		bool zs=FtpPutFile(ftp_session, localfile, remotefile,INTERNET_FLAG_TRANSFER_BINARY, 0);//INTERNET_FLAG_TRANSFER_BINARY  FTP_TRANSFER_TYPE_ASCII
    	InternetCloseHandle(ftp_session); 
		InternetCloseHandle(net_session);
		if (debug) printf("已上传文件%s,连接已关闭...\n",remotefile);
	
		return zs;
		/*
		参数说明编辑
hInternetSession:由InternetOpen返回的句柄。
sServerName:连接的ip或者主机名
nServerPort:连接的端口。如0,则为默认端口。
sUsername :用户名,如无置null
sPassword :密码,如无置null。
lService:使用的服务类型,可以使用以下
INTERNET_SERVICE_FTP = 1:连接到一个 FTP 服务器上
INTERNET_SERVICE_GOPHER = 2
INTERNET_SERVICE_HTTP = 3:连接到一个 HTTP 服务器上
lFlags :文档传输形式及缓存标记。一般置0。待补充。
ftp下:134217728=被动连接,vb有说法是x8000000。
lContext:当使用回叫信号时, 用来识别应用程序的前后关系。
返回值编辑
成功返回非0。如果返回0。要InternetCloseHandle释放这个句柄。
		*/
}


//ftp上传文件带进度模式
BOOL ftp_upload_file1(HWND hwnd,const char *server, int port, const char *username, const char *password, 
					 const char *localfile, const char *remotefile,bool debug)
 
{
	HINTERNET net_session = 0;   
	HINTERNET ftp_session = 0;
	HINTERNET hFTPFile = NULL;
	DWORD dwBytesReturn = 0;
	DWORD UploadDataSize = 0;
	BYTE *pUploadData = NULL;
	DWORD dwRet, bRet = 0;	
	DWORD dwBufferSize = 4096;//上传缓冲区大小
	BYTE *pBuf = NULL;//上传缓冲区

	DWORD dwOffset = 0;//偏移量	
	double zs=0;

		if (debug) printf("正在连接网络.....\n");
		net_session = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); 
		if(0 == net_session) 
		{
			if (debug) printf("[%s]不能连接网络!\n", __FUNCTION__);
			InternetCloseHandle(net_session);
			return FALSE;
		}

		if (debug) printf("正在连接FTP服务器.....\n");
		ftp_session = InternetConnect(net_session, server, port, username, password, 
			INTERNET_SERVICE_FTP, 0, 0);//连接FTP服务器
		if(0 == ftp_session)
		{
			if (debug) printf("[%s]不能连接FTP服务器\n", __FUNCTION__);
			InternetCloseHandle(ftp_session);			
			return FALSE;
		}
		
		if (debug) printf("开始上传文件...\n");
		hFTPFile = FtpOpenFile(ftp_session, remotefile, GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_RELOAD, 0);

			// 打开文件
			HANDLE hFile = CreateFile(localfile, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | 
				FILE_SHARE_WRITE, NULL, OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE, NULL);
			if (INVALID_HANDLE_VALUE == hFile)
			{
			
				InternetCloseHandle(ftp_session); 
				InternetCloseHandle(net_session);			
				return FALSE;
			}
			// 获取文件大小
			UploadDataSize = GetFileSize(hFile, NULL);
			// 读取文件数据
			pUploadData = new BYTE[UploadDataSize];
			ReadFile(hFile, pUploadData, UploadDataSize, &dwRet, NULL);
			UploadDataSize = dwRet;
			CloseHandle(hFile); // 一定注意在函数退出之前对句柄进行释放。

	// 申请动态内存
	pBuf = new BYTE[dwBufferSize];
	RtlZeroMemory(pBuf, dwBufferSize);
	DWORD dwupBufferSize = 0;//上传缓冲区大小	
	jdtzs=UploadDataSize;
	jdtss=0;
	// 接收数据
	//InvalidateRect(hwnd,NULL,TRUE);//刷新显示结果 TRUE重画时将擦除背景。false重画时不擦除背景
	yx1=1;
	memset(inputstr, 0, MAX_PATH);//一定要清掉内存,不然会.......	
	//inputstr
	HANDLE hThread1	= CreateThread(NULL, 0, xc3, hwnd, 0, NULL);//创建线程	
	do
	{
		if ((UploadDataSize-dwOffset)>=dwBufferSize)
		{
			dwupBufferSize=dwBufferSize;
			
		}else
		{
			dwupBufferSize=UploadDataSize-dwOffset;
		}
		RtlZeroMemory(pBuf, dwBufferSize);//清除缓冲区数据
		RtlCopyMemory(pBuf,(pUploadData+dwOffset),dwupBufferSize);//复制缓冲区数据

		// 上传数据
		bRet = InternetWriteFile(hFTPFile, pBuf, dwupBufferSize, &dwBytesReturn);
		if (FALSE == bRet)
		{
			// 释放内存
			delete[]pUploadData;
			
			InternetCloseHandle(ftp_session); 
			InternetCloseHandle(net_session);
			yx1=0;
			return false;			

		}
		dwOffset = dwOffset + dwBytesReturn;
		zs=(double)dwOffset/UploadDataSize*100;
		sprintf(inputstr,"上传进度:%.2f%%\n",zs);
		SetWindowText(hwnd,inputstr);
		jdtss=dwOffset;
		
		//InvalidateRect(hwnd,NULL,FALSE);
		//TextOut(hdc,10,r.bottom-20,inputstr,strlen(inputstr));
		
	} while (dwOffset

你可能感兴趣的:(windows,c++)