oracle dbsm output,测试C++代码与WebBrowser HTML的互动

testWebBrowserDlg.h

// testWebBrowserDlg.h : 头文件

//

#pragma once

#include "explorer1.h"

#import "C:\windows\system32\mshtml.tlb" // location of mshtml.tlb

#include

#include

#include

#include

/*

标题:测试C++代码与WebBrowser HTML的互动

Author:Kagula

Date:2014-08-20

版本号:3

Test Env: Windows8.1、VS2013 Update2

内容:

[1]如何拿到html中的elements,取得它的属性!

[2]如何响应element激发的事件

[3]如何修改指定element的属性

[4]如何Render内存中的html字符串

参考资料

[1]《MFC中针对WebBrowser控件增加link链接点击事件监控》

http://www.mworkbox.com/wp/work/509.html

[2]《IWebBrowser2 interface》

http://msdn.microsoft.com/en-us/library/aa752127(VS.85).aspx

[3]《Handling HTML Element Events》

http://msdn.microsoft.com/en-us/library/bb508508(v=vs.85).aspx

[4]《如何从 VC web 浏览器应用程序中调用脚本函数》

http://support.microsoft.com/kb/q185127

[5]《Loading HTML content from a Stream》

http://msdn.microsoft.com/en-us/library/ie/aa752047%28v=vs.85%29.aspx

[6]《How do I get the font color from a piece of HTML source code?》

http://stackoverflow.com/questions/7402347/how-do-i-get-the-font-color-from-a-piece-of-html-source-code

[7]《How to create a sink interface in a MFC-based COM client》

http://support.microsoft.com/default.aspx?scid=kb;en-us;181845

[8]《How To Use the Microsoft WebBrowser Control to Render HTML from Memory》

http://www.nuonsoft.com/blog/2010/03/24/how-to-use-the-microsoft-webbrowser-control-to-render-html-from-memory/comment-page-1/

[9]《How do I get the font color from a piece of HTML source code?》

http://stackoverflow.com/questions/7402347/how-do-i-get-the-font-color-from-a-piece-of-html-source-code

[10]《Using the WebBrowser control, simplified》

http://www.codeproject.com/Articles/3919/Using-the-WebBrowser-control-simplified

[11]《Microsoft Internet Explorer 5.5 behaviors》

http://msdn.microsoft.com/en-us/magazine/cc301528.aspx

[12]《Using IHTMLEditDesigner》

http://www.codeproject.com/Articles/6546/Using-IHTMLEditDesigner

[13]《MFC C++ WebBrowser Control load HTML from a string》

http://stackoverflow.com/questions/9179179/mfc-c-webbrowser-control-load-html-from-a-string

[14]VC++ webbrowser函数使用范例

[15]《【webbrowser使用】_webbrowser使用的相关文章,教程,源码》

http://www.xuebuyuan.com/zt/12577882.html

*/

namespace kagula

{

struct ConnectionInfo

{

IDispatch* dispatch;

IID iid;

DWORD cookie;

ConnectionInfo() {}

ConnectionInfo(IDispatch *dispatch, IID iid, DWORD cookie)

{

this->dispatch = dispatch, this->iid = iid, this->cookie = cookie;

}

};

}

// CtestWebBrowserDlg 对话框

class CtestWebBrowserDlg : public CDialogEx

{

// 构造

public:

CtestWebBrowserDlg(CWnd* pParent = NULL);// 标准构造函数

// 对话框数据

enum { IDD = IDD_TESTWEBBROWSER_DIALOG };

protected:

virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV 支持

// 实现

protected:

HICON m_hIcon;

// 生成的消息映射函数

virtual BOOL OnInitDialog();

afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

afx_msg void OnPaint();

afx_msg HCURSOR OnQueryDragIcon();

DECLARE_MESSAGE_MAP()

public:

CExplorer1 m_webBrowser;

void SetElementAttribute(MSHTML::IHTMLDocument2Ptr htmlDoc,CString elementID,CString attributeName,CString value);

std::map m_mapElem2EventCookie;//用于释放Connection

void ReleaseHTMLConnection();

void DemoGetElement(LPDISPATCH pDisp, VARIANT* URL);

void DemoGetAllLinkElement(LPDISPATCH pDisp, VARIANT* URL);

void OnClick(MSHTML::IHTMLEventObj *pEvtObj);

void OnLostFocus(MSHTML::IHTMLEventObj *pEvtObj);

void WriteHTML(const wchar_t* html);

afx_msg void OnBnClickedMemoryRender();

//added new three map macros

DECLARE_EVENTSINK_MAP()

DECLARE_DISPATCH_MAP()

DECLARE_INTERFACE_MAP()

void BeforeNavigate2Explorer1(LPDISPATCH pDisp, VARIANT* URL, VARIANT* Flags, VARIANT* TargetFrameName, VARIANT* PostData, VARIANT* Headers, BOOL* Cancel);

void DocumentCompleteExplorer1(LPDISPATCH pDisp, VARIANT* URL);

afx_msg void OnBnClickedBtnSetspecifiedelementattr();

virtual void OnOK();

virtual void OnCancel();

};

testWebBrowserDlg.cpp

// testWebBrowserDlg.cpp : 实现文件

//

#include "stdafx.h"

#include "testWebBrowser.h"

#include "testWebBrowserDlg.h"

#include "afxdialogex.h"

#include

#include

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

// CtestWebBrowserDlg 对话框

CtestWebBrowserDlg::CtestWebBrowserDlg(CWnd* pParent /*=NULL*/)

: CDialogEx(CtestWebBrowserDlg::IDD, pParent)

{

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

void CtestWebBrowserDlg::DoDataExchange(CDataExchange* pDX)

{

CDialogEx::DoDataExchange(pDX);

DDX_Control(pDX, IDC_EXPLORER1, m_webBrowser);

}

BEGIN_MESSAGE_MAP(CtestWebBrowserDlg, CDialogEx)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

ON_BN_CLICKED(IDC_BTN_RENDERSTRING, &CtestWebBrowserDlg::OnBnClickedMemoryRender)

ON_BN_CLICKED(IDC_BTN_SETSPECIFIEDELEMENTATTR, &CtestWebBrowserDlg::OnBnClickedBtnSetspecifiedelementattr)

END_MESSAGE_MAP()

// CtestWebBrowserDlg 消息处理程序

BOOL CtestWebBrowserDlg::OnInitDialog()

{

CDialogEx::OnInitDialog();

// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动

// 执行此操作

SetIcon(m_hIcon, TRUE);// 设置大图标

SetIcon(m_hIcon, FALSE);// 设置小图标

// TODO: 在此添加额外的初始化代码

EnableAutomation();//没有这行代码会导致GetIDispatch(FALSE)失败!

//m_webBrowser.Navigate(L"D:\\Workspace\\testWebBrowser\\testWebBrowser\\test.html",NULL,NULL,NULL,NULL);

m_webBrowser.Navigate(L"about:blank", NULL, NULL, NULL, NULL);

return TRUE; // 除非将焦点设置到控件,否则返回 TRUE

}

void CtestWebBrowserDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

CDialogEx::OnSysCommand(nID, lParam);

}

// 如果向对话框添加最小化按钮,则需要下面的代码

// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,

// 这将由框架自动完成。

void CtestWebBrowserDlg::OnPaint()

{

if (IsIconic())

{

CPaintDC dc(this); // 用于绘制的设备上下文

SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);

// 使图标在工作区矩形中居中

int cxIcon = GetSystemMetrics(SM_CXICON);

int cyIcon = GetSystemMetrics(SM_CYICON);

CRect rect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2;

int y = (rect.Height() - cyIcon + 1) / 2;

// 绘制图标

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CDialogEx::OnPaint();

}

}

//当用户拖动最小化窗口时系统调用此函数取得光标

//显示。

HCURSOR CtestWebBrowserDlg::OnQueryDragIcon()

{

return static_cast(m_hIcon);

}

//测试:Render内存中的HTML

void CtestWebBrowserDlg::OnBnClickedMemoryRender()

{

m_webBrowser.Navigate(L"app://mymemory.page",NULL,NULL,NULL,NULL);

}

BEGIN_EVENTSINK_MAP(CtestWebBrowserDlg, CDialogEx)

ON_EVENT(CtestWebBrowserDlg, IDC_EXPLORER1, 250, CtestWebBrowserDlg::BeforeNavigate2Explorer1, VTS_DISPATCH VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PBOOL)

ON_EVENT(CtestWebBrowserDlg, IDC_EXPLORER1, 259, CtestWebBrowserDlg::DocumentCompleteExplorer1, VTS_DISPATCH VTS_PVARIANT)

END_EVENTSINK_MAP()

/* 第二步:处理所有种类元素的事件 */

BEGIN_INTERFACE_MAP(CtestWebBrowserDlg, CCmdTarget)

INTERFACE_PART(CtestWebBrowserDlg, DIID_HTMLElementEvents2, Dispatch)

END_INTERFACE_MAP()

/* 第三步: 某种事件(元素类型无关)和哪个响应函数连*/

BEGIN_DISPATCH_MAP(CtestWebBrowserDlg, CCmdTarget)

DISP_FUNCTION_ID(CtestWebBrowserDlg, "HTMLELEMENTEVENTS2_ONCLICK", DISPID_HTMLELEMENTEVENTS2_ONCLICK, CtestWebBrowserDlg::OnClick, VT_EMPTY, VTS_DISPATCH)

DISP_FUNCTION_ID(CtestWebBrowserDlg, "HTMLELEMENTEVENTS2_ONFOCUSOUT", DISPID_HTMLELEMENTEVENTS2_ONFOCUSOUT, CtestWebBrowserDlg::OnLostFocus, VT_EMPTY, VTS_DISPATCH)

END_DISPATCH_MAP()

void CtestWebBrowserDlg::BeforeNavigate2Explorer1(LPDISPATCH pDisp, VARIANT* URL, VARIANT* Flags, VARIANT* TargetFrameName, VARIANT* PostData, VARIANT* Headers, BOOL* Cancel)

{

CString strURL(URL->bstrVal);

*Cancel = FALSE;

if (strURL == _T("about:blank"))

{

*Cancel = FALSE;

}

else

{

if (strURL.Find(_T("ThePageNeverReach.htm")) > 0 )

{//阻止跳转到指定页面!

*Cancel = TRUE;

return;

}

}

if (!(*Cancel))

{

//进入新页面之前,先释放掉事件连接

ReleaseHTMLConnection();

}

//演示,render内存中的html页面!

if (strURL.Find(_T("app://mymemory.page")) >= 0)

{

*Cancel = TRUE;

WriteHTML(L"

My Header

Some text below the header

");

return;

}

}

void CtestWebBrowserDlg::DocumentCompleteExplorer1(LPDISPATCH pDisp, VARIANT* URL)

{

//DemoGetElement(pDisp, URL);

DemoGetAllLinkElement(pDisp, URL);

}//end func

//演示:鼠标点击事件

void CtestWebBrowserDlg::OnClick(MSHTML::IHTMLEventObj *pEvtObj)

{

MSHTML::IHTMLElementPtr elem = pEvtObj->srcElement;

CString cstrID = elem->Getid();

CString cstrTag = elem->GettagName();//标签的名字

if (cstrID.GetLength()<=0)

{

return;

}

_variant_t name = elem->getAttribute(_T("name"), 0);

CString cstrName;

if (name.vt != VT_NULL)

{

cstrName = name;

}

_variant_t href = elem->getAttribute(_T("value"), 0);

CString cstrHref;

if (href.vt != VT_NULL)

{

cstrHref = href.bstrVal;

}

CString msg;

msg.Format(L"[id=%s][name=%s][tag=%s][value=%s]", cstrID.GetBuffer(),

cstrName.GetBuffer(), cstrTag.GetBuffer(), cstrHref.GetBuffer(MAX_PATH));

TRACE(msg);

}

//演示:响应 标签 失去焦点事件

void CtestWebBrowserDlg::OnLostFocus(MSHTML::IHTMLEventObj *pEvtObj)

{

MSHTML::IHTMLElementPtr elem = pEvtObj->srcElement;

CString cstrID = elem->Getid();

if (cstrID.GetLength()<=0)

{

return;

}

CString msg;

msg.Format(L"OnLostFocus cstrID = [%s]", cstrID.GetBuffer());

AfxMessageBox(msg);

}

//演示:拿到指定ID的标签元素,并打印它的属性

void CtestWebBrowserDlg::DemoGetElement(LPDISPATCH pDisp, VARIANT* URL)

{

IWebBrowser2Ptr webBrowser(pDisp);

IDispatchPtr htmlDocDisp;

(*webBrowser).get_Document(&htmlDocDisp);

MSHTML::IHTMLDocument2Ptr htmlDoc(htmlDocDisp);

MSHTML::IHTMLElementCollectionPtr elements;

(*htmlDoc).get_all(&elements);

IDispatchPtr disp;

_variant_t index(0L, VT_I4);

do

{

disp = (*elements).item(_variant_t("myFontTag"), index);

if (disp != NULL)

{

MSHTML::IHTMLElementPtr element(disp);

variant_t vtValue = element->getAttribute("color", 0);

CString cstr = vtValue;

TRACE(L"mytag标签的color属性为%s\n", cstr.GetBuffer(MAX_PATH));

++index.lVal;

}

} while (disp != NULL);

}

/*

拿到元素,并做链接

[1]《AfxConnectionAdvise》

http://msdn.microsoft.com/en-us/library/b9h84ebk.aspx

[2]《How to create a sink interface in a MFC-based COM client》

http://support.microsoft.com/default.aspx?scid=kb;en-us;181845

[3]《同Document建立Connection》

http://www.popkistopki.ru/ch08e.htm

*/

void CtestWebBrowserDlg::DemoGetAllLinkElement(LPDISPATCH pDisp, VARIANT* URL)

{

// Get the HTML document. //

IWebBrowser2Ptr webBrowser(pDisp);

IDispatchPtr htmlDocDisp;

(*webBrowser).get_Document(&htmlDocDisp);

MSHTML::IHTMLDocument2Ptr htmlDoc(htmlDocDisp);

if (htmlDoc == NULL) //URL属性为空

{

return;

}

//打印HTML页面内容

MSHTML::IHTMLElementPtr body = htmlDoc->Getbody();

variant_t html = body->parentElement->outerHTML;

//variant_t bodyHTML = body->GetouterHTML();

CString cstrBodyHTML = html;

TRACE(L"cstrBodyHTML.GetBuffer()========\n%s\n", cstrBodyHTML.GetBuffer());

//取HTML中的元素

DWORD dwCookie = 0;

// Get the collection of elements.

MSHTML::IHTMLElementCollectionPtr elements;

(*htmlDoc).get_all(&elements);

IDispatchPtr disp;

_variant_t index(0L, VT_I4);

do

{

//Get all elements

disp = (*elements).item(index, index);

if (disp != NULL)

{

// Examine their action attribute to determine what should be done.

IDispatchPtr element(disp);

MSHTML::IHTMLElementPtr elemTag(disp);

//第一步:建立Connection

DWORD dwCookie = 0;

BSTR name = NULL;

elemTag->get_tagName(&name);

if (name != NULL)

{

//is link!!!!

LPUNKNOWN pUnkSink = GetIDispatch(FALSE);

//关联全部类型元素

if (AfxConnectionAdvise(element, DIID_HTMLElementEvents2, pUnkSink, FALSE, &dwCookie))

{

kagula::ConnectionInfo ci(element.GetInterfacePtr(), DIID_HTMLElementEvents2, dwCookie);

m_mapElem2EventCookie[element.GetInterfacePtr()] = ci;

}

}//end if

++index.lVal;

}

} while (disp != NULL);

}

//释放同HTML的Connection

void CtestWebBrowserDlg::ReleaseHTMLConnection()

{

std::map::iterator itr;

for (itr = m_mapElem2EventCookie.begin(); itr != m_mapElem2EventCookie.end(); itr++)

{

//DIID_HTMLDocumentEvents、DIID_HTMLAnchorEvents2、DIID_HTMLButtonElementEvents

AfxConnectionUnadvise(itr->first, itr->second.iid, GetIDispatch(FALSE), FALSE, itr->second.cookie);

}

m_mapElem2EventCookie.clear();

}

//测试,设置当前页面指定元素的属性

void CtestWebBrowserDlg::OnBnClickedBtnSetspecifiedelementattr()

{

CComPtr spDisp = m_webBrowser.get_Application();

if (spDisp != NULL)

{

CComPtr spWeb;

HRESULT hr = spDisp->QueryInterface(IID_IWebBrowser2, (void**)&spWeb);

if (SUCCEEDED(hr))

{

IDispatchPtr htmlDocDisp;

spWeb->get_Document(&htmlDocDisp);

MSHTML::IHTMLDocument2Ptr htmlDoc(htmlDocDisp);

if (htmlDoc == NULL) //URL属性为空

{

return;

}

SetElementAttribute(htmlDoc, L"firstname", L"value", L"Marcia");

SetElementAttribute(htmlDoc, L"lastname",L"value", L"JohnDoe");

SetElementAttribute(htmlDoc, L"female",L"checked", L"1");

SetElementAttribute(htmlDoc, L"bike",L"checked", L"");

SetElementAttribute(htmlDoc, L"car",L"checked", L"1");

//演示,重定向到其它URL

//CComVariant varURL("http://www.intel.com");

//spWeb->Navigate2(&varURL, NULL, NULL, NULL, NULL);

}

}

}

void CtestWebBrowserDlg::SetElementAttribute(MSHTML::IHTMLDocument2Ptr htmlDoc, CString elementID, CString attributeName, CString value)

{

MSHTML::IHTMLElementCollectionPtr elements;

htmlDoc->get_all(&elements);

IDispatchPtr disp;

_variant_t index(0L, VT_I4);

do

{

disp = (*elements).item(_variant_t(elementID.GetBuffer()), index);

if (disp != NULL)

{

MSHTML::IHTMLElementPtr element(disp);

element->setAttribute(attributeName.GetBuffer(), value.GetBuffer(),0);

++index.lVal;

}

} while (disp != NULL);

}

/*测试render内存中的html*/

void CtestWebBrowserDlg::WriteHTML(const wchar_t* html)

{

IDispatch* pHtmlDoc = m_webBrowser.get_Document();

/*

在调用这段代码之前,如果你还没有url需要navigate,就必须在

OnInitDialog中插入下面的代码,否则拿不到document!

m_webBrowser.Navigate(L"about:blank",NULL,NULL,NULL,NULL);

*/

if (!pHtmlDoc)

return;

CComPtr doc2;

doc2.Attach((IHTMLDocument2*)pHtmlDoc);

if (!doc2)

return;

// Creates a new one-dimensional array

SAFEARRAY* psaStrings = SafeArrayCreateVector(VT_VARIANT, 0, 1);

if (!psaStrings)

return;

BSTR bstr = SysAllocString(html);

if (bstr)

{

VARIANT* param;

HRESULT hr = SafeArrayAccessData(psaStrings, (LPVOID*)¶m);

if (SUCCEEDED(hr))

{

param->vt = VT_BSTR;

param->bstrVal = bstr;

hr = SafeArrayUnaccessData(psaStrings);

if (SUCCEEDED(hr))

{

doc2->write(psaStrings);

doc2->close();

}

}

}

// SafeArrayDestroy calls SysFreeString for each BSTR!

if (psaStrings)

SafeArrayDestroy(psaStrings);

}

//退出前要释放链接

void CtestWebBrowserDlg::OnOK()

{

ReleaseHTMLConnection();

CDialogEx::OnOK();

}

void CtestWebBrowserDlg::OnCancel()

{

ReleaseHTMLConnection();

CDialogEx::OnCancel();

}

test.html

测试从H1标签能不能得到事件

测试能不能从font标签得到事件

测试禁止页面跳转

测试用户点击链接, C++后台得到消息!,并跳转到页面

First name:

Last name:

Password:

Male

Female

I have abdsmasterbike

I have a car

转载自:http://blog.csdn.net/lee353086/article/details/38537415

程序员的基础教程:菜鸟程序员

使用JUnit测试java代码

Junit 单元测试实验报告  一.实验环境 MyEclipse2014.Junit4.10 二.实验目的 学会单元测试,在MyEclipse中进行Junit测试 三.实验步骤 1.写出要测试的类 代 ...

前端测试框架Jest系列教程 -- Asynchronous&lpar;测试异步代码&rpar;

写在前面: 在JavaScript代码中,异步运行是很常见的.当你有异步运行的代码时,Jest需要知道它测试的代码何时完成,然后才能继续进行另一个测试.Jest提供了几种方法来处理这个问题. 测试异步 ...

&period;NET Core TDD 前传&colon; 编写易于测试的代码 -- 缝

有时候不是我们不想做单元测试, 而是这代码写的实在是没法测试.... 举个例子, 如果一辆汽车在产出后没完成测试, 那么没人敢去驾驶它. 代码也是一样的, 如果项目未能进行该做的测试, 那么客户就不敢 ...

&period;NET Core TDD 前传&colon; 编写易于测试的代码 -- 构建对象

该系列第1篇: 讲述了如何创造"缝".  "缝"(seam)是需要知道的概念. 本文是第2篇, 介绍的是如何避免在构建对象时写出不易测试的代码. 本文的概念性内 ...

&period;NET Core TDD 前传&colon; 编写易于测试的代码 -- 依赖项

第1篇: 讲述了如何创造"缝".  "缝"(seam)是需要知道的概念. 第2篇, 避免在构建对象时写出不易测试的代码. 本文是第3篇, 讲述依赖项和迪米特法则 ...

&period;NET Core TDD 前传&colon; 编写易于测试的代码 -- 全局状态

第1篇: 讲述了如何创造"缝".  "缝"(seam)是需要知道的概念. 第2篇, 避免在构建对象时写出不易测试的代码. 第3篇, 依赖项和迪米特法则. 本文是 ...

&period;NET Core TDD 前传&colon; 编写易于测试的代码 -- 单一职责

第1篇: 讲述了如何创造"缝".  "缝"(seam)是需要知道的概念. 第2篇, 避免在构建对象时写出不易测试的代码. 第3篇, 依赖项和迪米特法则. 第4篇 ...

php操作共享内存shmop类及简单使用测试(代码)

SimpleSHM 是一个较小的抽象层,用于使用 PHP 操作共享内存,支持以一种面向对象的方式轻松操作内存段.在编写使用共享内存进行存储的小型应用程序时,这个库可帮助创建非常简洁的代码.可以使用 3 ...

&period;NET Core TDD 前传&colon; 编写易于测试的代码 一 -- 缝

转载于: https://www.cnblogs.com/cgzl/p/9365955.html 有时候不是我们不想做单元测试, 而是这代码写的实在是没法测试.... 举个例子, 如果一辆汽车在产出后 ...

随机推荐

实现Launcher默认壁纸、选择壁纸定制化功能

需求功能说明:     该定制需求为在系统中增加一个新的分区如myimage,用以实现存放定制资源.例如在myimage下新建wallpaper文件夹用于存放定制的墙纸图片资源,当Launcher加载 ...

android-Activity&lpar;四大组件之一&rpar;

一.Activity理解 1.定义: 直译为活动,是Android定义四大应用组件之一,也是最重要的用的最多的: 用来提供一个能让用户操作并与之交互的界面 一个应用有多个界面也就是包含多个Activi ...

ubuntu启动eclipse时出错cannot open display

由于要学习hadoop,就在ubuntu下创建了一个hadoop用户,但是eclipse是在naomi用户下装的,在root和naomi用户下都能正常启动,但是一旦切换到hadoop用户,试着启动ec ...

MySQL驱动阅读------executeQuery查询的过程,基于JDBC-----5&period;1&period;26

Statement statement = connection.createStatement(); final ResultSet resultSet = statement.executeQue ...

haskell类型

一.源文件 介绍这个主要是因为下文很多代码写在源文件中,然后从ghci加载源文件进行测试. 创建一个文本文件,在其中输入,并保存为add.hs文件 -- file: add.hs add x y = ...

Grunt压缩图片

今天我们来说一下用Grunt来压缩图片和JS吧! 首先要安装插件: 这是压缩图片的; npm install --save-dev gulp-imagemin 这是压缩JS的: npm install ...

PAT &lpar;Basic Level&rpar; Practise (中文)-1021&period; 个位数统计 &lpar;15&rpar;

1021. 个位数统计 (15) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 给定一个k位整数N = dk-1 ...

Maven运行报错

在创建Maven项目时,出现报错:No goals have been specified for this build pom.xml文件加入 

UVa-156 Ananagrams&lpar;map映射&rpar;

#include #include #include #include ...

&lpar;转&rpar; C&num; Async与Await的使用

(转) C# Async与Await的使用 class Program { static void Main(string[] args) { Console.WriteLine("主线程测 ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值