如何对网页输入框进行编程
飘飘白云(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![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
if (SUCCEEDED(hr))
{
5
VARIANT_BOOL vIsTextEdit = VARIANT_FALSE;
6
pElement->get_isTextEdit(&vIsTextEdit);
7![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (vIsTextEdit == VARIANT_TRUE)
{
8
BSTR bTagName;
9
pElement->get_tagName(&bTagName);
10![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
11![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
char chTag[MAX_PATH] =
{ '\0' };
12
WideCharToMultiByte(CP_ACP, 0, bTagName, -1, chTag,
13![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
14
MAX_PATH, NULL, NULL);
15
_strupr_s(chTag, MAX_PATH);
16
if(lstrcmpA(chTag, "INPUT") == 0 || lstrcmpA(chTag,
17![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
18![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
"TEXTAREA") == 0)
{
19
VARIANT attr;
20
VariantInit(&attr);
21![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
22
BSTR bstrTemp;
23
bstrTemp = SysAllocString(L"readonly");
24
hr = pElement->getAttribute(bstrTemp, 0, &attr);
25![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (SUCCEEDED(hr))
{
26
if (attr.vt == VT_BOOL && attr.boolVal ==
27![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
28![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
VARIANT_TRUE)
{
29
// read only
30
return false;
31
}
32![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
33
IHTMLInputTextElement* pInputTextElement;
34
hr = pElement->QueryInterface
35![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
36
(IID_IHTMLInputTextElement, (void**)(&pInputTextElement));
37![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (SUCCEEDED(hr))
{
38
BSTR bstrType;
39
pInputTextElement->get_type(&bstrType);
40![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
char chType[MAX_PATH] =
{ '\0' };
41
WideCharToMultiByte(CP_ACP, 0, bstrType, -1,
42![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
43
chType, MAX_PATH, NULL, NULL);
44
_strupr_s(chType, MAX_PATH);
45![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
55
VariantClear(&attr);
56
}
57
}
58![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
59
pElement->Release();
60
pElement = N
此外你还可以通过调用IHTMLDocument2的调用execCommand函数来控制对网页的操作,比如复制,剪切等等。(The world浏览器的编辑模式查看网页,我猜就是用这个办法),下面的是这个ExecCommand函数是对IHTMLDocument2的execCommand函数的简单封装。其中cmdStr可以为:L"Paste", L"Cut", L"Copy", L"Undo", L"Delete"等。
1
void ExecCommand(LPCWSTR cmdStr)
2![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
3![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (m_WebDocument == 0 || cmdStr == NULL)
{
4
return;
5
}
6![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
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
}