我想实现一个带有自定义任务窗格的PowerPoint加载项,用户可以从中将复杂对象拖动到幻灯片上(这些对象将包含多个形状,例如圆形中的两个三角形或类似的东西)。
我设法通过在用户控件中调用DoDragDrop
并将所需文本作为方法的第一个参数传递,将简单文本框放到幻灯片上。但是我不知道是否可以将更多copmlex对象作为DoDragDrop
方法的数据参数传递给多个形状。
我尝试的另一种方法是使用空字符串调用DoDragDrop
(这样就不会将任何内容放到幻灯片上),并且在DoDragDrop
返回后我可以使用{{{}添加形状到幻灯片1}}方法,但我找不到获取鼠标指针当前位置的方法。
那么以某种方式可以调用DoDragDrop并将多个形状传递给它,或者在DoDragDrop返回后获取光标位置吗?
更新:我找到了PowerPoint 2013的解决方案,可以使用新的Globals.ThisAddIn.Application.ActiveWindow.View.Slide.AddShape
事件完成(但这不是一件容易的事,详情请参阅:http://social.msdn.microsoft.com/Forums/en-US/724f1737-afa5-4762-8740-5b3745e06f8a/afterdragdroponslide-event-in-ppt-2013?forum=isvvba)。< / p>
所以问题是PowerPoint 2010中可能存在同样的问题吗?
答案 0 :(得分:3)
使用DoDragDrop
第一个参数调用String.Empty
后,可以获取当前光标坐标。
获取坐标需要一些Win32样板:
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
}
class Win32API
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetCursorPos(out POINT lpPoint);
}
private POINT GetCursorPosition()
{
POINT point = new POINT();
Win32API.GetCursorPos(out point);
Win32API.ScreenToClient(new IntPtr(Globals.ThisAddIn.Application.ActiveWindow.HWND), ref point);
return point;
}
然后必须将这些坐标转换为幻灯片的坐标系(幻灯片的点大小与像素中屏幕上显示的大小不同)。< / p>
private POINT ConvertScreenPointToSlideCoordinates(POINT point)
{
// Get the screen coordinates of the upper-left hand corner of the slide.
POINT refPointUpperLeft = new POINT(
Globals.ThisAddIn.Application.ActiveWindow.PointsToScreenPixelsX(0),
Globals.ThisAddIn.Application.ActiveWindow.PointsToScreenPixelsY(0));
// Get the size of the slide (in points of the slide's coordinate system).
var slide = Globals.ThisAddIn.Application.ActiveWindow.View.Slide;
var slideWidth = slide.CustomLayout.Width;
var slideHeight = slide.CustomLayout.Height;
// Get the screen coordinates of the bottom-right hand corner of the slide.
POINT refPointBottomRight = new POINT(
Globals.ThisAddIn.Application.ActiveWindow.PointsToScreenPixelsX(slideWidth),
Globals.ThisAddIn.Application.ActiveWindow.PointsToScreenPixelsY(slideHeight));
// Both reference points have to be converted to the PowerPoint window's coordinate system.
Win32API.ScreenToClient(new IntPtr(Globals.ThisAddIn.Application.ActiveWindow.HWND), ref refPointUpperLeft);
Win32API.ScreenToClient(new IntPtr(Globals.ThisAddIn.Application.ActiveWindow.HWND), ref refPointBottomRight);
// Convert the point to the slide's coordinate system (convert the pixel coordinate inside the slide into a 0..1 interval, then scale it up by the slide's point size).
return new POINT(
(int)Math.Round((double)(point.X - refPointUpperLeft.X) / (refPointBottomRight.X - refPointUpperLeft.X) * slideWidth),
(int)Math.Round((double)(point.Y - refPointUpperLeft.Y) / (refPointBottomRight.Y - refPointUpperLeft.Y) * slideHeight));
}
执行拖放操作的代码:
DoDragDrop(String.Empty, DragDropEffects.Copy);
var point = GetCursorPosition();
var convertedPoint = this.ConvertScreenPointToSlideCoordinates(point);
// Insert something at the cursor's location:
var slide = Globals.ThisAddIn.Application.ActiveWindow.View.Slide;
slide.Shapes.AddShape(Microsoft.Office.Core.MsoAutoShapeType.msoShapeCloud, convertedPoint.X, convertedPoint.Y, 100, 100);