回 帖 发 新 帖 刷新版面

主题:TianyaReader 1.0

自己写好的一个程序,是用来上天涯看故事的,天涯那回帖太乱了,又不设“只看楼主”功能,有时想看故事也不方便,所以自己就写了个这样的东西。

这东西没什么技术含量。不多说了,有兴趣的看看。今天回家过清明,俺先跑了。

[img]http://file.pfan.cn/upfile/20080403061459.rar[/img]

整个Project下载:[url]http://file.pfan.cn/upfile/200804070922610.rar[/url]

核心源代码:
[code=c]
DWORD WINAPI ThreadProc_Go(LPARAM lpParameter)
{
    EnableWindow(GetDlgItem(m_hDlg, IDOK), FALSE);
    EnableWindow(GetDlgItem(m_hDlg, IDC_URL), FALSE);
    CoInitialize(NULL);

    while (true)
    {
        MSXML2::IXMLHTTPRequestPtr ixh = NULL;
        ixh.CreateInstance(__uuidof(XMLHTTPRequestPtr));// (TEXT("MSXML2.XMLHTTP"));
        _variant_t varAsync(false);
        ixh->open(_bstr_t(TEXT("GET")), _bstr_t(m_url), varAsync);
        ixh->send();
        if (ixh->status != 200)
        {
            MessageBox(m_hDlg, TEXT("载入页面错误"), NULL, MB_OK);
            break;
        }
        VARIANT varBody;
        ixh->get_responseBody(&varBody);
        
        BOOL ret = _DealWithPage((LPCSTR)varBody.parray->pvData);
        SafeArrayDestroy(varBody.parray);
        if (!ret)
            break;
    }

    CoUninitialize();
    EnableWindow(GetDlgItem(m_hDlg, IDOK), TRUE);
    EnableWindow(GetDlgItem(m_hDlg, IDC_URL), TRUE);

    return 0;
}

BOOL _DealWithPage(LPCSTR pstr)
{
    BOOL    fAnyNextPage = FALSE;
    int        CurPageTipItems = 0;

    LPCSTR    cpCurItem = pstr;
    LPCSTR    cp1 = NULL;
    LPCSTR    cp2 = NULL;

    //TCHAR tc1[10];
    //wsprintf(tc1, TEXT("%d\n"), m_cPages);
    //OutputDebugString(tc1);
    //if (m_cPages == 44)
    //    DebugBreak();

    if (m_cPages == 1)
    {
        //find out title
        cp1 = strstr(pstr, "<TITLE>") + 7;
        cp2 = strstr(pstr, "</TITLE>");
        int n = (int)(cp2 - cp1);
        char szTitle[256];
        strncpy(szTitle, cp1, n);
        szTitle[n] = '\0';
        strcat(szTitle, " - Tianya Reader 1.0");
        SetWindowTextA(m_hDlg, szTitle);

        //find out whether current page is first one
        cp1 = strstr(pstr, "<table><tr><td>分页链接:<font color=black>[1]</font>");
        if (cp1 == NULL)
        {
            MessageBox(m_hDlg, TEXT("找不到分页信息,请确定链接是帖子的第一页"), NULL, MB_OK);
            return FALSE;
        }

        //find out the author mark
        cp1 = strstr(pstr, "作者:<a href=http://cache.tianya.cn/browse/Listwriter.asp?vwriter=");
        if (cp1 == NULL)
        {
lnCannotGetAuthorMark:
            MessageBox(m_hDlg, TEXT("找不到作者信息"), NULL, MB_OK);
            return FALSE;
        }
        cp1 = strstr(cp1, "target=_blank>");
        if (cp1 == NULL)
            goto lnCannotGetAuthorMark;
        cp2 = strstr(cp1, "</a>") + 4;
        strncpy(m_author, cp1, cp2 - cp1);
        m_author[cp2-cp1] = '\0';
    }

    cp1 = strstr(pstr, ">下一页</a>");
    if (cp1 == NULL)
        goto lnCurPage;        //the last page
    cp2 = cp1;
    while (*(cp1--) != '=');
    cp1 += 2;
    strncpy(m_url, cp1, cp2 - cp1);
    fAnyNextPage = TRUE;


lnCurPage:

    //TCHAR tc2[10];
    //wsprintf(tc2, TEXT("%d\n"), m_cTipItems);
    //OutputDebugString(tc2);
    //if (m_cTipItems == 15)
    //    DebugBreak();

    const char    FIRSTITEMHEADER[] = "<DIV class=content style=\"WORD-WRAP:break-word;;\">";
    const int    FIH_LEN = sizeof(FIRSTITEMHEADER) - 1;

    cp1 = strstr(cpCurItem, m_author);
    if (cp1 == NULL)
        goto lnOK;    //no other items
    cp1 = strstr(cp1, "</TD></TR></table>") + 18 + 2;    // + mark_len + CrLf_len
    //remove FIH if any
    if (CurPageTipItems == 0 && 
        strncmp(cp1, FIRSTITEMHEADER, FIH_LEN) == 0)
        cp1 += FIH_LEN + 2;

    cp2 = strstr(cp1, "<TABLE cellspacing=");
    if (cp2 == NULL)
    //    cp2 += 2;    //remove \r\n
    //else
        cp2 =strstr(cp1, "</DIV>");
    int n = (int)(cp2 - cp1);

    int nMissSum = 0;
    LPSTR &pCurTipItem = m_TipItems[m_cTipItems++];
    pCurTipItem = new char[n + 1];
    for (int i=0; i<n; i++)
    {
        if (cp1[i] != '<')
            pCurTipItem[i-nMissSum] = cp1[i];
        else
        {
            if (strncmp(cp1 + i, "<br>", 4) == 0)
            {
                pCurTipItem[i-nMissSum+0] = '\r';
                pCurTipItem[i-nMissSum+1] = '\n';
                i += 3;
                nMissSum += 2;
            }
            else
                pCurTipItem[i-nMissSum] = cp1[i];
        }
    }
    pCurTipItem[n-nMissSum] = '\0';

    TCHAR szChapter[56];
    wsprintf(szChapter, TEXT("%d-%d"), m_cPages, ++CurPageTipItems);
    HWND hwndList = GetDlgItem(m_hDlg, IDC_TIPLIST);
    ListBox_AddString(hwndList, szChapter);
    if (m_cTipItems == 1)
    {
        ListBox_SetCurSel(hwndList, 0);
        PostMessage(m_hDlg, WM_COMMAND, 
            MAKEWPARAM(IDC_TIPLIST, LBN_SELCHANGE), (LPARAM)hwndList);
    }

    if (m_cTipItems == 1000)
    {
        MessageBox(m_hDlg, TEXT("作者回帖数超过1000"), NULL, MB_OK);
        return FALSE;
    }

    cpCurItem = cp2;
    goto lnCurPage;

lnOK:

    if (fAnyNextPage)
    {
        m_cPages++;
        return TRUE;
    }

    return FALSE;
}
[/code]

回复列表 (共6个回复)

沙发

几时才清明?你这就走,属于溜号行为。哈哈哈哈

板凳

[img]http://file.pfan.cn/upfile/200804030938903.zip[/img]

有点错误!

3 楼

修正了一些逻辑上的BUG

上传了源代码(整个工程,VC++2005)

楼上说的错误不知道是怎么发生的?能重现一下当时的操作吗?(估计是网络载入页面问题)

个人认为,这个小程序用来学VC是挺不错的,哈哈

4 楼

[quote]几时才清明?你这就走,属于溜号行为。哈哈哈哈[/quote]
家离这有点远,所以...呵呵

5 楼

可怜我就没得回家,也不能上坟!
强烈抗议资本家的压榨。

6 楼

错误以修复。是。的确是载入页面时的错误。

虽然不是用HTML对象来读。
但是信息处理,还是值得学习。
不用一条从头到尾的选择语句,= =;,欣慰。

我来回复

您尚未登录,请登录后再回复。点此登录或注册