简单版小说搜索阅读(64位程序)
本帖最后由 htpidk 于 2020-7-18 15:48 编辑今天发现之前写的一个64位小说搜索与阅读程序,代码写的比较挫,不过把写的过程中遇到的一些坑注释出来了,大家以后可以避免这种情况,程序用到了miniblink(github上找的到)和我自己写的一个SDK的界面库,也不算界面库,只是简单的封装了12种常用的组件
#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_DATAFindFileData;
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={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={0};
GetCurrentDirectory(100,directory);
std::string directorystring=directory;
directorystring=directorystring+"\\"+name.c_str();
char* lujing=const_cast<char*>(directorystring.c_str());//文件路径
wchar_t wlujing={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.cElements;
//char haha={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;
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;
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.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=const_cast<char*>(m3.str(1).c_str());
//pppianzhang=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=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,
000000013FC13494 48 8D 8C 24 50 01 00 00 lea rcx,
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 ,rax
000000013FC134A9 48 8B 8C 24 58 04 00 00 mov rcx,qword ptr
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
000000013FC134BE 48 8B 15 B3 A5 02 00 mov rdx,qword ptr
000000013FC134C5 48 89 04 CA mov qword ptr ,rax
000000013FC134C9 48 8D 8C 24 C0 00 00 00 lea rcx,
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;
ZeroMemory(lianjie,50);
strcpy(lianjie,m3.str(1).c_str());//m3.str(1).c_str()在这句命令后,m3.str(1)生成的临时string对象就销毁了,不过无所谓了,复制到申请的内存里了
if(pplianjie!=NULL){
delete pplianjie;
pplianjie=0;
//删除之前申请的内存再进行下面的赋值
}
pplianjie=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;
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.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*;//存放篇章对应的链接
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);
}
C++ ,哈哈。用这个写小说搜索程序,有劲。 我要做伸手党。。 阅读达人 可以把界面优化一下还是不错的 佩服 C++写这个不累吗??
页:
[1]