I need to capture drag and Drop Events of WebBrowser Control in WinForm C#. Is there any way ?
问题:
回答1:
My Workarond:
use a boolean member variable to detect if you call navigate from inside code or navigating is called from ouside code. Implement the "Navigating" (BeforeNavigating) event and check if it was a call from outside.
Example:
call navigate from inside:
private void NavigateLocal(string htmlFileName)
{
this.localNavigate = true;
this.webBrowser.Navigate(htmlFileName);
}
event method:
private void WebBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
if (this.localNavigate)//inside call
{
this.localNavigate = false;
}
else //call from outside
{
this.DoDragDrop(e.Url.ToString());
}
}
回答2:
"Fix" i use is to let the browser tell you it's being draged, pop over a picture with a screen shot, and handle the normal c# events.
[ComVisible(true)]
public class Communicator
{
private static frmMain m_mainWindow = null;
public Communicator(frmMain mainWindow)
{
m_mainWindow = mainWindow;
}
public void exit()
{
m_mainWindow.Close();
}
public void DragStarted(object e)
{
m_mainWindow.DoDragEnterFromScript();
}
}
private void frmMain_Load(object sender, EventArgs e)
{
webBrowser1.ObjectForScripting = new Communicator(this);;
webBrowser1.Navigate(@"about:blank");
}
public void DoDragEnterFromScript()
{
// Is this an executable, shortcut or batch?
Rectangle rect = new Rectangle(0, 0, webBrowser1.Size.Width, webBrowser1.Size.Height);
Bitmap bmp = new Bitmap(rect.Width, rect.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Graphics g = Graphics.FromImage(bmp);
Point ptCon;
ptCon = webBrowser1.PointToScreen(new Point(0, 0));
g.CopyFromScreen(ptCon, new Point(0, 0), webBrowser1.Size, CopyPixelOperation.SourceCopy);
pictureBox2.BackgroundImage = bmp;
//pictureBox2.BackColor = Color.Red;
webBrowser1.Visible = false;
pictureBox2.Visible = true;
pictureBox2.Location = new Point(0, 0);
pictureBox2.Size = webBrowser1.Size;
}
public void frmMain_DragEnter(object sender, DragEventArgs e)
{
if (!e.Data.GetDataPresent(DataFormats.FileDrop))
return;
string[] arrfiles = (string[])e.Data.GetData(DataFormats.FileDrop);
// SUCCESS
}
And in the html file
var holder = document.getElementsByTagName('body')[0];
holder.ondragover = function () {
window.external.DragStarted(event);
return true;
};
Dont forget to hide the picturebox after DragLeave / DragDrop
回答3:
Does the standard way of doing drag and drop not work?
http://www.codeproject.com/KB/cs/dragdrop.aspx
回答4:
WebBrowser Customization You can also look into IDocHostUIHandler::GetDropTarget if you want to control what the WebBrowser Control does during drag-and-drop operations.
The easiest way to hook up an implementation of IDocHostUIHandler is to hook up the ICustomDoc interface and all its SetUIHandler method (see http://www.codeproject.com/csharp/advhost.asp). This method has memory leak though. Another method is to skip Windows Form's webbrowser class and use the ActiveX host support directly.
回答5:
The best way I've found is to handle the Navigating
event in the control through the host. When you drop files on the control, this event fires and you can pick up the file names at that time. The trick is that you have to know what constitutes a legal navigation (ie. a document that is navigated directly vs. a file that is dropped). Most applications that handle drop events are using a specific document or set of known documents that this shouldn't be a problem.
Another option is to handle the drop operation via window.ondrop
inside of the HTML document with JavaScript code, but you can only pick up the file data and filename, not the full path.
For more info on both approaches take a look at this blog post: https://weblog.west-wind.com/posts/2017/Mar/10/Dragging-and-Dropping-Images-and-Files-into-the-Web-Browser-Control