Winforms 确定C中AxAcroPDF对象中的当前页面#
Adobe AxAcroPDF控件没有返回当前页码的功能。我只是在做一个个人实用程序,所以我有幸选择了一种我想分享的黑客方法。。。它是用网络上的零碎碎片拼凑在一起的。它使用User32.dll中的Windows本机函数枚举控件的子项,并在工具栏中查找与页码对应的文本框。然后使用SendMessage调用读取其中的文本。此方法枚举adobe pdf viewer的子组件,并在工具栏中查找文本框。其中一个文本框是页码,一个是当前缩放值。内容中不带“%”的文本框将作为页码文本框。使用SendMessage函数检索文本框的内容 您可能需要首先在查看器组件上调用SetToolbarVisible(true),以确保工具栏(以及文本框)可见 这是一个非常糟糕的黑客解决方案,当Adobe更新查看器时,它可能很容易崩溃。如果Adobe能够添加一个“getCurrentPage”方法,这样就可以避免所有这一切,那将是一件好事Winforms 确定C中AxAcroPDF对象中的当前页面#,winforms,pdf,axacropdf,Winforms,Pdf,Axacropdf,Adobe AxAcroPDF控件没有返回当前页码的功能。我只是在做一个个人实用程序,所以我有幸选择了一种我想分享的黑客方法。。。它是用网络上的零碎碎片拼凑在一起的。它使用User32.dll中的Windows本机函数枚举控件的子项,并在工具栏中查找与页码对应的文本框。然后使用SendMessage调用读取其中的文本。此方法枚举adobe pdf viewer的子组件,并在工具栏中查找文本框。其中一个文本框是页码,一个是当前缩放值。内容中不带“%”的文本框将作为页码文本框。使用SendMessa
//you can get the handle parameter for this method as: yourPDFControl.Handle
public static string GetPageNumber(IntPtr adobeViewerHandle)
{
//get a list of all windows held by parent
List<IntPtr> childrenWindows = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(childrenWindows);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(adobeViewerHandle, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
//now have a list of the children, look for text boxes with class name "Edit"
for (int i = 0; i < childrenWindows.Count; i++)
{
int nRet;
// Pre-allocate 256 characters, the maximum class name length.
StringBuilder ClassName = new StringBuilder(256);
//Get the window class name
nRet = GetClassName(childrenWindows.ElementAt(i), ClassName, ClassName.Capacity);
if (ClassName.ToString().CompareTo("Edit") == 0)
{
IntPtr resultPointer = Marshal.AllocHGlobal(200);
StringBuilder text = new StringBuilder(20);
NativeMethods.SendMessage(childrenWindows.ElementAt(i), 0x000D, text.Capacity, text); //0x000D is WM_GETTEXT message
if (text.ToString().Contains("%")) //we don't want the text box for the PDF scale (e.g. 66.7% zoomed etc.)
{
continue;
} else
{
return text.ToString(); // the only other text box is the page number box
}
}
}
//Note I return as a string because PDF supports page labels, "I", "ii", "iv" etc. or even section labels "A", "B". So you're not guaranteed a numerical page number.
return "0";
}
private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
GCHandle gch = GCHandle.FromIntPtr(pointer);
List<IntPtr> list = gch.Target as List<IntPtr>;
if (list == null)
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
list.Add(handle);
return true;
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool EnumChildWindows(IntPtr window,
EnumWindowProc callback,
IntPtr i);
internal delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern int GetWindowText(IntPtr hWnd,
StringBuilder lpString,
int nMaxCount);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern bool SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
//您可以将此方法的handle参数设置为:yourPDFControl.handle
公共静态字符串GetPageNumber(IntPtr adobeViewerHandle)
{
//获取父级持有的所有窗口的列表
List childrenWindows=新建列表();
GCHandle listHandle=GCHandle.Alloc(childrenWindows);
尝试
{
EnumWindowProc childProc=新的EnumWindowProc(EnumWindow);
EnumChildWindows(adobeViewerHandle、childProc、GCHandle.ToIntPtr(listHandle));
}
最后
{
if(listHandle.IsAllocated)
Free();
}
//现在有一个孩子的列表,查找类名为“Edit”的文本框
对于(int i=0;i
此方法枚举adobe pdf viewer的子组件,并在工具栏中查找文本框。其中一个文本框是页码,一个是当前缩放值。内容中不带“%”的文本框将作为页码文本框。使用SendMessage函数检索文本框的内容
您可能需要首先在查看器组件上调用SetToolbarVisible(true),以确保工具栏(以及文本框)可见
这是一个非常糟糕的黑客解决方案,当Adobe更新查看器时,它可能很容易崩溃。如果Adobe能够添加一个“getCurrentPage”方法,这样就可以避免所有这一切,那将是一件好事
//you can get the handle parameter for this method as: yourPDFControl.Handle
public static string GetPageNumber(IntPtr adobeViewerHandle)
{
//get a list of all windows held by parent
List<IntPtr> childrenWindows = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(childrenWindows);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(adobeViewerHandle, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
//now have a list of the children, look for text boxes with class name "Edit"
for (int i = 0; i < childrenWindows.Count; i++)
{
int nRet;
// Pre-allocate 256 characters, the maximum class name length.
StringBuilder ClassName = new StringBuilder(256);
//Get the window class name
nRet = GetClassName(childrenWindows.ElementAt(i), ClassName, ClassName.Capacity);
if (ClassName.ToString().CompareTo("Edit") == 0)
{
IntPtr resultPointer = Marshal.AllocHGlobal(200);
StringBuilder text = new StringBuilder(20);
NativeMethods.SendMessage(childrenWindows.ElementAt(i), 0x000D, text.Capacity, text); //0x000D is WM_GETTEXT message
if (text.ToString().Contains("%")) //we don't want the text box for the PDF scale (e.g. 66.7% zoomed etc.)
{
continue;
} else
{
return text.ToString(); // the only other text box is the page number box
}
}
}
//Note I return as a string because PDF supports page labels, "I", "ii", "iv" etc. or even section labels "A", "B". So you're not guaranteed a numerical page number.
return "0";
}
private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
GCHandle gch = GCHandle.FromIntPtr(pointer);
List<IntPtr> list = gch.Target as List<IntPtr>;
if (list == null)
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
list.Add(handle);
return true;
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool EnumChildWindows(IntPtr window,
EnumWindowProc callback,
IntPtr i);
internal delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern int GetWindowText(IntPtr hWnd,
StringBuilder lpString,
int nMaxCount);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern bool SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
//您可以将此方法的handle参数设置为:yourPDFControl.handle
公共静态字符串GetPageNumber(IntPtr adobeViewerHandle)
{
//获取父级持有的所有窗口的列表
List childrenWindows=新建列表();
GCHandle listHandle=GCHandle.Alloc(childrenWindows);
尝试
{
EnumWindowProc childProc=新的EnumWindowProc(EnumWindow);
EnumChildWindows(adobeViewerHandle、childProc、GCHandle.ToIntPtr(listHandle));
}
最后
{
if(listHandle.IsAllocated)
Free();
}
//现在有一份