吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2944|回复: 5
收起左侧

[C&C++ 转载] 简单版小说搜索阅读(64位程序)

[复制链接]
htpidk 发表于 2020-7-18 15:39
本帖最后由 htpidk 于 2020-7-18 15:48 编辑

今天发现之前写的一个64位小说搜索与阅读程序,代码写的比较挫,不过把写的过程中遇到的一些坑注释出来了,大家以后可以避免这种情况,程序用到了miniblink(github上找的到)和我自己写的一个SDK的界面库,也不算界面库,只是简单的封装了12种常用的组件

[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);
}


捕获.PNG

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

goldli 发表于 2020-7-18 15:47
C++ ,哈哈。用这个写小说搜索程序,有劲。
quzhaojia 发表于 2020-7-18 16:47
zhaoya_n 发表于 2020-7-18 17:41
sktter 发表于 2020-7-21 16:42
可以把界面优化一下还是不错的
flyfishlll 发表于 2020-7-22 09:53
佩服 C++写这个  不累吗??
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 03:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表