[C++] 纯文本查看 复制代码
#include "xiaoshuo.h"
#include <regex>
HWND xswnd;
#import "C:\\Windows\\SysWOW64\\winhttpcom.dll" no_namespace
IWinHttpRequest* pwin=NULL;
Sedit g_edt,g_jianjieedt,g_textedt;
Slistbox g_pianzhanglist;
char** pppianzhang;//存放文章的篇章标题char*数组
char** pplianjie;//存放文章的篇章链接char*数组
char* wenzhangzhengwen;//文章正文
int wenzhangzhengwenlen;//文章正文长度
wkeWebView miniblinkwindow;//miniblink网页句柄
LRESULT __stdcall webproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp);//miniblink网页窗口消息子类化过程
LONG_PTR webbackcall;
void xianshi();//显示小说正文
void freelease();//销毁IWinHttpRequest对象
void createhtml(int xuhao){
WIN32_FIND_DATA FindFileData;
HANDLE hFind = FindFirstFile(g_edt.getbt(),&FindFileData);
if ((hFind=INVALID_HANDLE_VALUE) || !(FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)){
CreateDirectory(g_edt.getbt(),NULL);
}
FindClose(hFind);
char xuhaobuffer[6]={0};
std::string name=g_edt.getbt();
name=name+"\\";
sprintf(xuhaobuffer,"%d",xuhao);
name=name+xuhaobuffer+".html";
//MessageBox(NULL,name.c_str(),"bt",MB_OK);
FILE* ceshi=fopen(name.c_str(),"r");
if(ceshi==NULL){
FILE* hf=fopen(name.c_str(),"wb+");
fwrite(wenzhangzhengwen,wenzhangzhengwenlen,1,hf);
fclose(hf);
}else
fclose(ceshi);
char directory[100]={0};
GetCurrentDirectory(100,directory);
std::string directorystring=directory;
directorystring=directorystring+"\\"+name.c_str();
char* lujing=const_cast<char*>(directorystring.c_str());//文件路径
wchar_t wlujing[100]={0};
MultiByteToWideChar(CP_ACP,0,lujing,-1,wlujing,100);
//MessageBoxW(NULL,wlujing,L"d",MB_OK);
wkeLoadFileW(miniblinkwindow,wlujing);//wkeLoadFile不能正常加载路径有汉字的网页,只能用W版函数
}
void sousuo(){
if(strcmp("",g_edt.getbt())==0){
MessageBox(NULL,"请输入要搜索的文章名称","bt",MB_OK);
return;
}
g_pianzhanglist.deleteallstring();
std::string wenzhangname=g_edt.getbt();
wenzhangname="https://www.biduo.cc/search.php?q="+wenzhangname;
pwin->Open("GET",wenzhangname.c_str());//这个网站首页是GBK,搜索页是UTF8编码,坑
pwin->Send();
_variant_t xstext=pwin->ResponseBody;
char* text=(char*)(xstext.parray->pvData);
//char* hh=(char*)(pwin->ResponseBody.parray->pvData);
int len=pwin->ResponseBody.parray->rgsabound[0].cElements;
//char haha[100]={0};
//sprintf(haha,"%d",len);
//MessageBox(NULL,haha,"bt",MB_OK);
int widelen=MultiByteToWideChar(CP_UTF8,0,text,len,NULL,NULL);
wchar_t* pwtext=new wchar_t[widelen+1];
ZeroMemory(pwtext,2*(widelen+1));
MultiByteToWideChar(CP_UTF8,0,text,len,pwtext,widelen);
int ansilen=WideCharToMultiByte(CP_ACP,0,pwtext,widelen,NULL,NULL,NULL,FALSE);
char* ptext=new char[ansilen+1];
ZeroMemory(ptext,ansilen+1);
WideCharToMultiByte(CP_ACP,0,pwtext,widelen,ptext,ansilen,NULL,FALSE);
delete[] pwtext;
std::regex jianjiepipei("<p class=\"result-game-item-desc\">(.*?)</p>");//匹配小说简介
std::cmatch m;
std::regex_search((const char*)ptext,(const char*)(ptext+ansilen),m,jianjiepipei);//不需要用循环反复匹配,只匹配第一个就行
if(strcmp("",const_cast<char*>(m.str(1).c_str()))==0){
MessageBox(NULL,"没有找到此本小说","bt",MB_OK);
return;
}
g_jianjieedt.setbt(const_cast<char*>(m.str(1).c_str()));
std::regex lianjiepipei("<a cpos=\"title\" href=\"(.*?)\" title=\"");//匹配搜索到的小说链接
std::cmatch m2;
std::regex_search((const char*)ptext,(const char*)(ptext+ansilen),m2,lianjiepipei);//不需要用循环反复匹配,只匹配第一个就行
std::string lianjie=m2.str(1).c_str();
lianjie="https://www.biduo.cc"+lianjie;//这个网页是GBK编码
pwin->Open("GET",lianjie.c_str());
pwin->Send();
_variant_t pianzhang=pwin->ResponseBody;
char* pianzhangtext=(char*)pianzhang.parray->pvData;
int pianzhanglen=pianzhang.parray->rgsabound[0].cElements;
std::regex pianzhangpipei("<a href=\"(.*?)\" >(.*?)</a>");//匹配小说的篇章名字和对应的链接
std::cmatch m3;
int i=0;
char* kaishi=pianzhangtext;
std::regex_search((const char*)kaishi,(const char*)(pianzhangtext+pianzhanglen),m3,pianzhangpipei);
while(std::regex_search((const char*)kaishi,(const char*)(pianzhangtext+pianzhanglen),m3,pianzhangpipei)){
//pplianjie[i]=const_cast<char*>(m3.str(1).c_str());
//pppianzhang[i]=const_cast<char*>(m3.str(2).c_str());
/*
不能这样赋值,经过反汇编查看,m3.str(1)和m3.str(2)生成的是一个string临时对象,这个对象在调用完c_str()就调用析构函数
销毁了,导致c_str()返回的字符串指向了乱码,string类对象c_str()返回的字符串指针是直接指向内部数据的,不是new几个char内存
来存放的,string类对象改变后,原来用c_str()返回的字符串指针指向的内容也会改变
60: pplianjie[i]=const_cast<char*>(m3.str(1).c_str());
000000013FC13486 41 B8 01 00 00 00 mov r8d,1
000000013FC1348C 48 8D 94 24 C0 00 00 00 lea rdx,[rsp+0C0h]
000000013FC13494 48 8D 8C 24 50 01 00 00 lea rcx,[rsp+150h]
000000013FC1349C E8 AF 08 00 00 call std::tr1::match_results<char const * __ptr64,std::allocator<std::tr1::sub_match<char const * __ptr64> > >::str (13FC13D50h)
000000013FC134A1 48 89 84 24 58 04 00 00 mov qword ptr [rsp+458h],rax
000000013FC134A9 48 8B 8C 24 58 04 00 00 mov rcx,qword ptr [rsp+458h]
000000013FC134B1 E8 7A 06 00 00 call std::basic_string<char,std::char_traits<char>,std::allocator<char> >::c_str (13FC13B30h)
000000013FC134B6 48 63 8C 24 40 01 00 00 movsxd rcx,dword ptr [rsp+140h]
000000013FC134BE 48 8B 15 B3 A5 02 00 mov rdx,qword ptr [pplianjie (13FC3DA78h)]
000000013FC134C5 48 89 04 CA mov qword ptr [rdx+rcx*8],rax
000000013FC134C9 48 8D 8C 24 C0 00 00 00 lea rcx,[rsp+0C0h]
000000013FC134D1 E8 2A 06 00 00 call std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> > (13FC13B00h)
*/
char* lianjie=new char[50];
ZeroMemory(lianjie,50);
strcpy(lianjie,m3.str(1).c_str());//m3.str(1).c_str()在这句命令后,m3.str(1)生成的临时string对象就销毁了,不过无所谓了,复制到申请的内存里了
if(pplianjie[i]!=NULL){
delete pplianjie[i];
pplianjie[i]=0;
//删除之前申请的内存再进行下面的赋值
}
pplianjie[i]=lianjie;
g_pianzhanglist.insertstring(i,const_cast<char*>(m3.str(2).c_str()));//显示在列表框里后,m3.str(2)生成的临时string对象就销毁了,不过无所谓了,目的达到了,显示在列表框里就行
i++;
kaishi=(char*)m3.suffix().first;
}
}
void xianshi(){
if(g_pianzhanglist.getcount()==0){
return;
}
int currentselect=g_pianzhanglist.getcurrentselect();
char* lianjie=pplianjie[currentselect];
std::string wangzhan="https://www.biduo.cc";
std::string wzlianjie=wangzhan+lianjie;
pwin->Open("GET",wzlianjie.c_str());
pwin->Send();
_variant_t nr=pwin->ResponseBody;
wenzhangzhengwen=(char*)(nr.parray->pvData);
wenzhangzhengwenlen=nr.parray->rgsabound[0].cElements;
//g_textedt.setbt(nnr);
createhtml(currentselect);
}
int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd ){
Swindow wnd(hInstance,"classname","小说阅读",50,50,1500,800,NULL,&xswnd);
Sedit edt(hInstance,xswnd,50,20,300,25,1001,NULL);//用来输入搜索的小说名字
edt.setfont("四号",FALSE,"宋体");
g_edt=edt;
HANDLE jb=LoadImage(hInstance,MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,32,32,LR_DEFAULTCOLOR);
SendMessage(xswnd,WM_SETICON,ICON_SMALL,(LPARAM)jb);
Sbutton btn(hInstance,xswnd,"搜索",360,20,100,25,1002,NULL);
btn.setfont("四号",FALSE,"宋体");
btn.ButtonClick(sousuo);
Sedit jianjieedt(hInstance,xswnd,50,50,1400,50,1003,NULL);//用来放小说的简介
jianjieedt.setfont("四号",FALSE,"宋体");
g_jianjieedt=jianjieedt;
Slistbox pianzhanglist(hInstance,xswnd,50,120,400,650,1004,NULL);//用来放小说的篇章
pianzhanglist.setfont("四号",FALSE,"宋体");
pianzhanglist.selectchange(xianshi);
g_pianzhanglist=pianzhanglist;
wkeSetWkeDllPath(L"miniblink_x64.dll");
wkeInit();
miniblinkwindow=wkeCreateWebWindow(WKE_WINDOW_TYPE_CONTROL, xswnd, 460, 120, 1000, 640);
wkeLoadURL(miniblinkwindow, "www.baidu.com");
wkeShowWindow(miniblinkwindow, TRUE);
HWND webwindow=FindWindowEx(xswnd,0,"wkeWebWindow","wkeWebWindow");//窗口句柄不是上面的miniblinkwindow,miniblinkwindow是一个结构体的指针
webbackcall=SetWindowLongPtr(webwindow,GWLP_WNDPROC,reinterpret_cast<LONG_PTR>(webproc));
pplianjie=new char*[8000];//存放篇章对应的链接
ZeroMemory(pplianjie,8*8000);//64位程序,指针长度8个字节
CoInitialize(NULL);
CoCreateInstance(__uuidof(WinHttpRequest),NULL,CLSCTX_INPROC_SERVER,__uuidof(IWinHttpRequest),(LPVOID*)&pwin);
wnd.WillDestroy(freelease);
wnd.SEnd();
return 0;
}
void freelease(){
pwin->Release();
CoUninitialize();
}
LRESULT __stdcall webproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp){
if(msg==WM_KEYDOWN){
if(wp==VK_RIGHT){
if(g_pianzhanglist.getcurrentselect()<g_pianzhanglist.getcount()-1){
g_pianzhanglist.selectorcancelsome(g_pianzhanglist.getcurrentselect(),FALSE);
g_pianzhanglist.selectorcancelsome(g_pianzhanglist.getcurrentselect()+1,TRUE);
xianshi();
}else
MessageBox(NULL,"已经到了最后一章","bt",MB_OK);
}else if(wp==VK_LEFT){
if(g_pianzhanglist.getcurrentselect()>0){
g_pianzhanglist.selectorcancelsome(g_pianzhanglist.getcurrentselect(),FALSE);
g_pianzhanglist.selectorcancelsome(g_pianzhanglist.getcurrentselect()-1,TRUE);
xianshi();
}else
MessageBox(NULL,"已经是第一章","bt",MB_OK);
}
}
return CallWindowProc(reinterpret_cast<WNDPROC>(webbackcall),hwnd,msg,wp,lp);
}