以编程方式更改IID_IHTMLInputFileElement值

时间:2018-11-26 12:18:32

标签: javascript html c++ visual-c++ mfc

我尝试了几天,以编程方式将文件路径放入CHtmlView控件(IE)的输入类型文件元素中。我已经尝试过了:

IHTMLInputFileElement* pInputElem = NULL;
hr = pElemDispatch->QueryInterface(IID_IHTMLInputFileElement, (void**)&pInputElem);
CString sFile(_T("C:\\Flaviu\\SomeFile.txt"));
BSTR bstrFilesAttribute = sFile.AllocSysString();
hr = pInputElem->put_value(bstrFilesAttribute); // hr is S_OK though
SysFreeString(bstrFilesAttribute);

但是没有用,我的意思是在输入文件上没有选择SomeFile.txt。

出于安全原因,我在多个站点上无法读取或编辑输入类型文件元素的值。

有人在某处提出了一个简单的解决方案:复制原始网页,编辑html源代码,并将输入类型文件元素替换为输入类型文本。我已经做了。我只需要解决表单上的“操作”属性:

原始html源代码:

<form name="uf" method="POST" action="/WS6ERT/SomeFile.do" enctype="multipart/form-data">
<div style="background-color: #c6c6c6; padding: 5px">
    <span>Choose file:</span> <span> <input type="file" name="linkdoc" size="75" value=""></span><span><input type="submit" value="Send"></span>
</div>
</form>

我做了一个副本,然后用输入类型文本替换了输入类型文件:

<form name="uf" method="POST" 
action="https://originalsite.com/WS6ERT/SomeFile.do" enctype="multipart/form-data">
<div style="background-color: #c6c6c6; padding: 5px">
    <span>Choose file::</span> <span> <input type="text" name="linkdoc"> 
</span><span><input type="submit" value="Send"></span>
</form>

重要标签属性:“ action = ” 当然,这与我在html源代码中编写的内容不正确,因为我的路径指向的是我未编辑的原始文件...

有没有办法解决这个问题?要以编程方式将文件路径放入CHtmlView视图上的输入类型文件中?还是如何克服这个问题?

最后编辑:我可以使用javascript设置文件吗?我在这里看到:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#attr-files可以在 files 属性中设置文件。但是我不知道该怎么做...

1 个答案:

答案 0 :(得分:0)

如果您拥有CHtmlView*的句柄,请使用CHtmlView::Navigate2CHtmlView::Navigate

除非html控件正忙于先前的请求,例如您已经提出了Navigate请求,并且html控件尚未完成对该请求的处理,否则这应该可以完成。在这种情况下,您可以覆盖CHtmlView::OnNavigateComplete2,这使您知道html控件已完成了先前的导航请求,并且可以接收新的请求。另外,您可以使用等待功能,使用下面显示的for循环来等待控件完成。

CString filename = _T("C:\\Test\\test.html");
CStringW content = LR"(<html><body>  content  </body></html>)";

//optional: in case the control is busy with previous request
for(int i = 0; i < 100; i++)
{
    MSG msg;
    while(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) 
        if(!AfxGetThread()->PumpMessage())
            break;
    CFile test;
    if(test.Open(filename, CFile::modeNoTruncate | CFile::modeWrite))
        break;
}

CFile fout;
if(fout.Open(filename, CFile::modeCreate | CFile::modeWrite))
{
    content = LR"(<html><body>  content UPDATE </body></html>)";
    CStringA utf8 = CW2A(content, CP_UTF8);
    fout.Write(utf8, utf8.GetLength());
    fout.Close();
    htmlview->Navigate(filename, 0, NULL);
}