need the drop location of drag & drop in a Word/Excel/PPT document

D

David Thielen

Hi;

We've got an issue where we have to know where in a document a drop
from a drag & drop will occur. We know when the drop is occuring
because we are dropping our own IDataObject object and so Word is
calling our IDataObject.ClipboardText() method.

And we can return "" if we want nothing to happen at that point. But
we need to know where in the document this drop will occur. How can we
get that?

thanks - dave

david@[email protected]
Windward Reports -- http://www.WindwardReports.com
me -- http://dave.thielen.com

Cubicle Wars - http://www.windwardreports.com/film.htm
 
J

Ji Zhou [MSFT]

Hello Dave,

Thanks for using Microsoft Newsgroup Support Service!

To enable or disable items on ribbon according to which Word document is
presented to user, it is recommended to use the Application.WindowActivate
event as the following:

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
this.Application.WindowActivate += new
Microsoft.Office.Interop.Word.ApplicationEvents4_WindowActivateEventHandler(
Application_WindowActivate);
}

void Application_WindowActivate(Microsoft.Office.Interop.Word.Document Doc,
Microsoft.Office.Interop.Word.Window Wn)
{
Globals.Ribbons.Ribbon1.button1.Enabled = false;
}

This event fires when any document window is activated. The following is
the related document in the MSDN:
http://msdn.microsoft.com/en-us/library/aa211901(office.11).aspx

Please let me know whether this works for your scenario.


Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Ji Zhou [MSFT]

Hello Dave,

Please ignore my last reply. It is supposed to be post in your another
thread
"Microsoft.Office.Interop.Word.ApplicationEvents3_Event.DocumentChange not
always firing". I have repost it there. I am sorry for the inconvenience
taken to you.


Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Ji Zhou [MSFT]

Hello Dave,

First I want to make sure I understand this issue correctly. From the
description, we create our own IDataObject object. When we drag an instance
of our IDataObject object into Word document, Word will call our
IDataObject.ClipboardText() method. The issue is that in the
IDataObject.ClipboardText() method, we cannot know where the drop action
occurs, right? If I have misunderstood, please feel free to correct me.

After some research, I find a workaround with a Timer. Using a timer is not
a robust solution in this scenario, I know. So, I am still working on this
issue to see if I can find a better solution. I also consulted the product
team to see whether they had any good ideas on this. I will let you know
when I have any new findings or get any results from the product team.

The following is the detailed information of the workaround I mentioned
above. First, we can create a timer and use its Enable property to control
how its Tick event fires. Every time we drag an IDataObject object into the
Word document, Word will call the IDataObject.GetData() method. There, we
set the timer's Enable property to true. So, the Tick event will fire. In
the Tick event's handle function, we call Application.DoEvents() to ensure
all the messages in the message queue are processed. Consequently, at this
time the IDataObject object is already pasted into the Word document. So,
we can easily get the drop location from Word.Application.Selection.Start.
If the drop location is where we want to perform the drop action, we do
nothing, if not, we call Application.ActiveDocument.Undo() method to cancel
the drop action.

As far as I test, the following codes work fine on my side:
class myDataObject: IDataObject
{
Timer t;

public myDataObject(String s)
{
t = new Timer();
t.Enabled = false;
t.Interval = 1;
t.Tick += new EventHandler(t_Tick);
this.SetData(s);
}

void t_Tick(object sender, EventArgs e)
{
t.Enabled = false;
Application.DoEvents();
if (Globals.ThisAddIn.Application.Selection.Start == 4)
{
object time = 1;
Globals.ThisAddIn.Application.ActiveDocument.Undo(ref time);
}
}

public object GetData(string format, bool autoConvert)
{
t.Enabled = true;
return Clipboard.GetData("String");
}

public void SetData(object data)
{
Clipboard.SetData("String", data);
}

......
}

And I use this line of codes to trigger the drag and drop:
this.label1.DoDragDrop(new
myDataObject(this.label1.Text),DragDropEffects.Copy);

Hope it helps!


Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

David Thielen

Ouch - that strikes me as a solution that will be buggy. I hope the
product team can provide a better solution.

thanks - dave


Hello Dave,

First I want to make sure I understand this issue correctly. From the
description, we create our own IDataObject object. When we drag an instance
of our IDataObject object into Word document, Word will call our
IDataObject.ClipboardText() method. The issue is that in the
IDataObject.ClipboardText() method, we cannot know where the drop action
occurs, right? If I have misunderstood, please feel free to correct me.

After some research, I find a workaround with a Timer. Using a timer is not
a robust solution in this scenario, I know. So, I am still working on this
issue to see if I can find a better solution. I also consulted the product
team to see whether they had any good ideas on this. I will let you know
when I have any new findings or get any results from the product team.

The following is the detailed information of the workaround I mentioned
above. First, we can create a timer and use its Enable property to control
how its Tick event fires. Every time we drag an IDataObject object into the
Word document, Word will call the IDataObject.GetData() method. There, we
set the timer's Enable property to true. So, the Tick event will fire. In
the Tick event's handle function, we call Application.DoEvents() to ensure
all the messages in the message queue are processed. Consequently, at this
time the IDataObject object is already pasted into the Word document. So,
we can easily get the drop location from Word.Application.Selection.Start.
If the drop location is where we want to perform the drop action, we do
nothing, if not, we call Application.ActiveDocument.Undo() method to cancel
the drop action.

As far as I test, the following codes work fine on my side:
class myDataObject: IDataObject
{
Timer t;

public myDataObject(String s)
{
t = new Timer();
t.Enabled = false;
t.Interval = 1;
t.Tick += new EventHandler(t_Tick);
this.SetData(s);
}

void t_Tick(object sender, EventArgs e)
{
t.Enabled = false;
Application.DoEvents();
if (Globals.ThisAddIn.Application.Selection.Start == 4)
{
object time = 1;
Globals.ThisAddIn.Application.ActiveDocument.Undo(ref time);
}
}

public object GetData(string format, bool autoConvert)
{
t.Enabled = true;
return Clipboard.GetData("String");
}

public void SetData(object data)
{
Clipboard.SetData("String", data);
}

......
}

And I use this line of codes to trigger the drag and drop:
this.label1.DoDragDrop(new
myDataObject(this.label1.Text),DragDropEffects.Copy);

Hope it helps!


Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.


david@[email protected]
Windward Reports -- http://www.WindwardReports.com
me -- http://dave.thielen.com

Cubicle Wars - http://www.windwardreports.com/film.htm
 
J

Ji Zhou [MSFT]

Hello Dave,

I did some more research on this issue, but still did not find any direct
way to get the drop location. I am writing to let you know we can use the
WindowSelectionChange event instead, in my above workaround. It will be
better than the Timer.

I attach the WindowSelectionChange event handler in GetData function of
IDataObject. And in the WindowSelectionChange handle, I test if the
Selection is where I want to drop the data, if yes, do nothing, if no, I
call Application.Undo() to roll back the drop action.

The modified codes are as follows:

public object GetData(string format, bool autoConvert)
{
if (format == "Rich Text Format")
{
app.WindowSelectionChange += new
Microsoft.Office.Interop.Word.ApplicationEvents4_WindowSelectionChangeEventH
andler(app_WindowSelectionChange);
return Clipboard.GetData("String");
}
return null;
}

void app_WindowSelectionChange(Microsoft.Office.Interop.Word.Selection Sel)
{
app.WindowSelectionChange -= new
Microsoft.Office.Interop.Word.ApplicationEvents4_WindowSelectionChangeEventH
andler(app_WindowSelectionChange);
if (Globals.ThisAddIn.Application.Selection.Start == 4)
{
object time = 1;
Globals.ThisAddIn.Application.ActiveDocument.Undo(ref time);
}
}


Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Ji Zhou [MSFT]

Hello Dave,

I got the following idea from the product team. We can call the
Word.Window.RangeFromPoint(int x, int y) to get a range object from a point
specified by the screen position coordinate pair. The detailed information
about the RangeFromPoint() method is available in this document
http://msdn.microsoft.com/en-us/library/bb209544.aspx

Thus, the following approach comes out. Firstly, we call the native Windows
API function GetMessagePos() to get the mouse's position. With the mouse
position, we call the RangeFromPoint to get the drop location range.

The codes worked on my side are as follows. It only lets users drop the
content at the fourth location in the whole Word document.
public partial class NativeMethods
{
[System.Runtime.InteropServices.DllImportAttribute("user32.dll",
EntryPoint = "GetMessagePos")]
public static extern int GetMessagePos();
}

public object GetData(string format, bool autoConvert)
{
Point p = new Point(NativeMethods.GetMessagePos());
Word.Range range =
Globals.ThisAddIn.Application.ActiveWindow.RangeFromPoint(
p.X, p.Y) as Word.Range;
if (range.Start == 4)
{
return Clipboard.GetData("String");
}
else
{
return "";
}
}

Please let me know if you have any other concerns on this. I am glad to be
of any future assistance.


Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

David Thielen

Oh WOW - this is wonderful. THANK YOU. Please also thank the person on
the product team who gave you this idea. This is a life-saver.

thanks - dave

ps - Are you guys getting a chance to enjoy the Olympics at all?


Hello Dave,

I got the following idea from the product team. We can call the
Word.Window.RangeFromPoint(int x, int y) to get a range object from a point
specified by the screen position coordinate pair. The detailed information
about the RangeFromPoint() method is available in this document
http://msdn.microsoft.com/en-us/library/bb209544.aspx

Thus, the following approach comes out. Firstly, we call the native Windows
API function GetMessagePos() to get the mouse's position. With the mouse
position, we call the RangeFromPoint to get the drop location range.

The codes worked on my side are as follows. It only lets users drop the
content at the fourth location in the whole Word document.
public partial class NativeMethods
{
[System.Runtime.InteropServices.DllImportAttribute("user32.dll",
EntryPoint = "GetMessagePos")]
public static extern int GetMessagePos();
}

public object GetData(string format, bool autoConvert)
{
Point p = new Point(NativeMethods.GetMessagePos());
Word.Range range =
Globals.ThisAddIn.Application.ActiveWindow.RangeFromPoint(
p.X, p.Y) as Word.Range;
if (range.Start == 4)
{
return Clipboard.GetData("String");
}
else
{
return "";
}
}

Please let me know if you have any other concerns on this. I am glad to be
of any future assistance.


Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.


david@[email protected]
Windward Reports -- http://www.WindwardReports.com
me -- http://dave.thielen.com

Cubicle Wars - http://www.windwardreports.com/film.htm
 
J

Ji Zhou [MSFT]

Yes, I usually watch some plays after my work time. I love the NBA and the
American Dream Team VIII. It equips so many great players this year. I
believe they will be the champion. The Olympic Games bridges different
culture. It is so great that it can be hold in Beijing this year. Wish you
can also enjoy your favorite sport games in the Olympics.

Have a nice day, Dave!

Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top