如何对网页输入框进行编程
飘飘白云(kesalin@gmail.com) 2009.04.23
假如网页中有如下两个输入框(多行输入框和单行只读输入框),在程序中该怎样来取得输入框的内容和相关属性,或控制用户操作呢?
<textarea name="text"cols="32" rows="4">Multiline editbox</textarea><br />
<input type="text" name="url" value="Readonly editbox" readonly /><br />
因为网页中输入框不是一般的EDIT控件,因此不能取得这些输入框的句柄。要实现这个功能,只能通过WebBrowser控件的有关COM接口了。因此要首先取得WebBrowser接口,这个过程可以参考:
如何从一个 HWND 获取 IHTMLDocument 2接口,大意如下:
This article shows how to get the IHTMLDocument2 interface from a HWND. If Microsoft Active Accessibility (MSAA) is installed, you can send the WM_HTML_GETOBJECT message to the document's window (with the window class "Internet Explorer_Server") and then pass the result from SendMessage to an MSAA function, ObjectFromLresult, to get a fully marshaled IHTMLDocument2 pointer.
本文介绍如何从一个 HWND 获取 IHTMLDocument 2 接口。 如果安装了 Microsoft Active Accessibility (MSAA) ,你可以发送 WM_HTML_GETOBJECT 消息到该文档的窗口 (使用窗口类"Internet Explorer_Server"),然后将结果从 SendMessage 传给 MSAA 函数 ObjectFromLresult ,这样就获得IHTMLDocument 2 指针。
假设我们已经取得了IHTMLDocument 2 指针,下面我们用这个IHTMLDocument2指针进行一些操作。下面的代码示范了判断当前焦点窗口是否是输入框,然后取得输入框的相关属性和内容(盗取网页秘码就是这么干的),并且修改其内容。
1 IHTMLDocument2* doc;//GetWebDocument();
2 IHTMLElement* pElement;
3 HRESULT hr = doc->get_activeElement(&pElement);
4 if (SUCCEEDED(hr)){
5 VARIANT_BOOL vIsTextEdit = VARIANT_FALSE;
6 pElement->get_isTextEdit(&vIsTextEdit);
7 if (vIsTextEdit == VARIANT_TRUE){
8 BSTR bTagName;
9 pElement->get_tagName(&bTagName);
10
11 char chTag[MAX_PATH] = { '\0' };
12 WideCharToMultiByte(CP_ACP, 0, bTagName, -1, chTag,
13
14MAX_PATH, NULL, NULL);
15 _strupr_s(chTag, MAX_PATH);
16 if(lstrcmpA(chTag, "INPUT") == 0 || lstrcmpA(chTag,
17
18"TEXTAREA") == 0) {
19 VARIANT attr;
20 VariantInit(&attr);
21
22 BSTR bstrTemp;
23 bstrTemp = SysAllocString(L"readonly");
24 hr = pElement->getAttribute(bstrTemp, 0, &attr);
25 if (SUCCEEDED(hr)){
26 if (attr.vt == VT_BOOL && attr.boolVal ==
27
28VARIANT_TRUE){
29 // read only
30 return false;
31 }
32
33 IHTMLInputTextElement* pInputTextElement;
34 hr = pElement->QueryInterface
35
36(IID_IHTMLInputTextElement, (void**)(&pInputTextElement));
37 if (SUCCEEDED(hr)){
38 BSTR bstrType;
39 pInputTextElement->get_type(&bstrType);
40 char chType[MAX_PATH] = { '\0' };
41 WideCharToMultiByte(CP_ACP, 0, bstrType, -1,
42
43chType, MAX_PATH, NULL, NULL);
44 _strupr_s(chType, MAX_PATH);
45 if (lstrcmpA(chType, "PASSWORD") == 0){
46 BSTR bstrOld;
47 BSTR bstrNew;
48 bstrNew = SysAllocString(L"Change text");
49 pInputTextElement->get_value(&bstrOld);
50 pInputTextElement->put_value(bstrNew);
51 }
52 }
53 }
54
55 VariantClear(&attr);
56 }
57 }
58
59 pElement->Release();
60 pElement = N
此外你还可以通过调用IHTMLDocument2的调用execCommand函数来控制对网页的操作,比如复制,剪切等等。(The world浏览器的编辑模式查看网页,我猜就是用这个办法),下面的是这个ExecCommand函数是对IHTMLDocument2的execCommand函数的简单封装。其中cmdStr可以为:L"Paste", L"Cut", L"Copy", L"Undo", L"Delete"等。
1void ExecCommand(LPCWSTR cmdStr)
2{
3 if (m_WebDocument == 0 || cmdStr == NULL) {
4 return;
5 }
6
7 ATL::CComBSTR cmdBStr(cmdStr);
8 ATL::CComVariant vNull;
9 VARIANT_BOOL bOK;
10 HRESULT hRslt = m_WebDocument->execCommand(
11 cmdBStr,
12 VARIANT_FALSE,
13 vNull,
14 &bOK);
15}