开发MFC界面爬取图片工具三(结合MFC界面时遇到的问题及解决方法)

引言

此处主要记录关于爬取百度图片模块与MFC界面融合时所遇到的问题,以及当中涉及的一些知识点做一下总结。

开发中涉及到的一些问题及解决方法

1.引入头文件问题

在mfc中,将CHttp类导入后,还需要引入头文件,一般头文件的引入要在stdafx.h中的最下方引入,否则有些文件会出现未定义标识符等错误。

#include "CHttp.h"
#include<algorithm>
#include <string>
using namespace std;

2.接收内容的格式转换问题(CString转string,CString转int)

CString转string示例如下:

//使用CString类型接收搜索内容并转换成string类型
	CString strText;
	m_text.GetWindowTextW(strText);
	string text = CW2A(strText.GetString());

CString转化为int类型示例如下:

//使用CString 接收编辑框内容
	CString strFistPage;
	m_fistPage.GetWindowTextW(strFistPage);
//将CString转化为int类型
	int fistPage = _wtoi(strFistPage);

在主窗口类中的头文件中声明变量接收内容

	//需要线程中使用的变量
	string text;			//转换后的文本
	int fistPage;			//转换后的首页
	int lastPage;			//转换后的尾页
	string savePath;		//转换后的路径
	CWinThread *pThread;	//定义线程句柄
	//用于接收编辑框的变量
	CString strText, strFistPage, strLastPage, strSavaPath, strThreads;

3.CString类型字符串中的字符替换问题

此处将所接受的保存路径中的字符"\“替换为”/",是为了后续函数URLDownloadToFile中的保存路径格式正确,否则下载时路径会出现问题

//接收保存路径并将其转换成string类型
	m_savaPath.GetWindowTextW(strSavaPath);
	strSavaPath.Replace(_T("\\"), _T("/"));		

4.创建线程问题

在此处创建线程是为了防止在下载图片时主线程堵塞,导致界面卡顿无法移动等现象。创建一个线程就比较好。
而在mfc中创建线程调用窗口类函数的过程中遇到了很多问题,开始使用的createthread函数,一直无法实现,此函数主要用于控制台应用程序。如果要在mfc中创建线程,一般应使用AfxBeginThread函数创建。
参考链接:https://blog.csdn.net/u014568921/article/details/44262645
https://www.cnblogs.com/renyuan/p/3430894.html
http://www.360doc.com/content/14/0507/09/8236462_375415995.shtml

(1)创建下载线程

线程函数的类型是规定好的不能是类函数
具体示例如下:

 pThread = AfxBeginThread(ThreadProc,this);	//参数1线程函数名,参数2this表示此窗口指针(通过此指针可以控制控件变量)

而pThread 则是此线程的句柄,在主窗口类的头文件中定义(为了在其他按钮控件中也能使用此句柄来控制线程,故在主窗口类的头文件中定义此线程句柄)

CWinThread *pThread;	//定义线程句柄

而线程函数ThreadProc实现如下

int code = 0;				//用来接收线程状态值
//定义爬取线程
UINT __cdecl ThreadProc(LPVOID lpParameter){
	code = 1;//将先程状态值设为1,表明线程正在进行
	CspiderBaiDuImgDlg *pThisGlg = (CspiderBaiDuImgDlg*)lpParameter;
	pThisGlg->StartCatchBaiDu(pThisGlg->text, pThisGlg->savePath, pThisGlg->fistPage, pThisGlg->lastPage);		//通过指针调用主窗口类中的成员函数及成员变量
	code = 0;	//线程结束时再变为0
	return 0;
}

此处使用code作为线程状态值,为了后面的暂停、恢复、停止等功能实现时显示当前状态。

(2)创建判断线程

在初始化函数中创建判断线程

	创建一个判断线程,判断执行线程是否还在执行
	m_status.SetWindowTextW(_T("当前无任务进行"));
	CWinThread *pJudge = AfxBeginThread(ThreadJudge, this);

判断线程函数如下:

//定义判断爬取线程是否工作的线程(未能成功实现)
UINT __cdecl ThreadJudge(LPVOID lpParameter){
	CspiderBaiDuImgDlg *pThisGlg = (CspiderBaiDuImgDlg*)lpParameter;
	while(1){
		//获取线程pThread的执行状态,如果
		//若为真表明线程正在执行
		if (code == 1){
			pThisGlg->m_status.SetWindowTextW(_T("正在下载,请等候. . ."));
		}
		else if (code == 2){
			pThisGlg->m_status.SetWindowTextW(_T("下载已暂停"));
		}
		else{
			pThisGlg->m_status.SetWindowTextW(_T("当前无任务进行"));
		}
		Sleep(1000*1);		//隔1秒进行一次判断
	}

	return 0;
}

5.如何实现编辑框追加文本问题

参考链接:https://blog.csdn.net/plum2003/article/details/8651726
https://blog.csdn.net/visualeleven/article/details/6214725
示例代码如下:

int iLen = m_result.GetWindowTextLength();		//获取输出结果编辑框中文本的长度
		m_result.SetSel(iLen, iLen, TRUE);		//设置光标位置为编辑框的文本的最后一位
m_result.ReplaceSel(_T("获取html页面失败\r\n"), FALSE);	//添加所要输出的字符串

6.URLDownloadToFile函数中参数格式问题(string转换为LPCWSTR)

参考链接:https://www.cnblogs.com/dzqdzq/archive/2013/04/09/3010665.html

使用此函数时,需要注意的是参数的格式

//下载文件stringToLPCWSTR
HRESULT hr = URLDownloadToFile(NULL, buffer, imgsavepath, 0, NULL);

在downLoadImage函数中,是使用string类型来接收url地址及保存地址的。所以此处要将string类型的变量变为LPCWSTR类型的变量。方式如下所示:

string savepath = savepathM + "/" + name + to_string(fistPage) + "-" + to_string(i+1) + ".jpg";									//此处使用数字对其重命名
		size_t len1 = savepath.length();
		wchar_t* imgsavepath = new wchar_t[len1];
		int nmlen1 = MultiByteToWideChar(CP_ACP, 0, savepath.c_str(), len1 + 1, imgsavepath, len1);

7.获取已下载文件大小问题

参考链接:https://blog.csdn.net/zanda_/article/details/90544856
示例如下:

FILE* fp = fopen(savepath.c_str(), "r");	//savepath是string类型的,即保存路径如"G:/爬取图片/img/1.jpg"
fseek(fp, 0, SEEK_END);
size_t size = ftell(fp);
fclose(fp);

CString sizeImg;
sizeImg.Format(_T("下载完成 [%4dKB] | "), (size/1000));	//此处将size 转为CString类型的方便显示在编辑框内

8.修改MFC图标问题

参考链接:https://blog.csdn.net/u011555996/article/details/90717837
https://www.cnblogs.com/tianxiafeiyu/p/9129849.html
https://blog.csdn.net/langb2014/article/details/50644792

  1. 在网上下载ico图标文件,一般下载下来的是jpg格式的,不能使用重命名将其后缀名修改为.ico,否则在导入图片时会报错
  2. 需要转换文件格式,这里有一在线转换图标格式链接:
    https://www.aconvert.com/cn/icon/png-to-ico/
    使用此链接可转换格式,将其命名为spider.ico
  3. 将此ico图片放在res资源文件夹下
  4. 右击解决方案中的.rc文件,点击查看代码
    找到下方代码,并将其中的相对路径修改如下
IDR_MAINFRAME           ICON                    "res\\spider.ico"
  1. 修改后,再次运行可能出现debug和realease编译生成的程序图标都没有变化情况,具体参考链接:https://blog.csdn.net/langb2014/article/details/50644792
    重建图标缓存即可
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吾名招财

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值