ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 6655|回复: 3

一次性地提取word中的图片

[复制链接]

TA的精华主题

TA的得分主题

发表于 2006-3-10 20:34 | 显示全部楼层 |阅读模式
终于可以一次性地提取word中的图片了,但这里存出来的图片,并不是真正的bitmap图像,而是增强型的图元文件,确切地说,是wmf格式的. Public BeforeShapes As Integer Private Declare Function OpenClipboard Lib "user32" (ByVal hWnd As Long) As Long Private Declare Function CloseClipboard Lib "user32" () As Long Private Declare Function GetClipboardData Lib "user32" (ByVal uFormat As Long) As Long Private Declare Function CopyEnhMetaFileA Lib "gdi32" (ByVal hemfSrc As Long, ByVal lpszFile As String) As Long Private Declare Function DeleteEnhMetaFile Lib "gdi32" (ByVal hDC As Long) As Long Private Declare Function SetBitmapBits Lib "gdi32" (ByVal hDC As Long) As Long Sub Mysavepicture() Dim i As Shape, Bmpname As String, k As InlineShape For Each i In ActiveDocument.Shapes If i.Type <> msoTextBox Then i.Select Selection.Copy j = j + 1 Bmpname = "c:\" & j & ".bmp" OpenClipboard 0 DeleteEnhMetaFile CopyEnhMetaFileA(GetClipboardData(14), Bmpname) ' 14 CloseClipboard End If Next For Each k In ActiveDocument.InlineShapes k.Select Selection.Copy j = j + 1 Bmpname = "c:\" & j & ".bmp" OpenClipboard 0 DeleteEnhMetaFile CopyEnhMetaFileA(GetClipboardData(14), Bmpname) ' 14 CloseClipboard Next End Sub

TA的精华主题

TA的得分主题

发表于 2006-3-13 15:49 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

有3点疑问:

1.到底是将图存为什么格式,如果不是BMP格式,为何要将文件的扩展名取为BMP呢?

2.楼主说的提取的图片到底是指点阵图还是矢量图?对WORD中绘制的几何图等有效吗?如果只能处理点阵图似乎意义不大。

3.楼主的代码是VB代码吧,在VBA中不能编译。

TA的精华主题

TA的得分主题

 楼主| 发表于 2006-3-15 11:59 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

就楼主的问题:

①是将图存为bmp格式的,因为它是最常见的图片格式,从CopyEnhMetaFileA可以看到,它的实际格式是wmf格式的,可以将生成的图片的后缀名改为wmf试试。

②是指提取word中的 InlineShape与 Shape,都可以提取,从If i.Type <> msoTextBox Then可以看到,如果不加限制的话,连文本框也可提取出来。

③上面的代码是正宗的VBA,当然也是VB,只是引用了API函数。

我发现用好API函数,可以为word解决很多的问题。

API的简介:

作为一个编程初学者来说,API函数也许是一个时常耳闻却感觉有些神秘的东西。单看它的复杂语法,就足令人望而生畏,但是任何事物在我们深入了解它之前,总是会有这种感觉的。我们这篇API入门教程的目的,就是要把API函数的来龙去脉告诉大家,破除对API函数的畏惧,使它成为我们编程的好助手。

  大家可能在许多书上看到过API的英文全称(Application Programming Interface),WIN32 API也就是MicrosoftWindows 32位平台的应用程序编程接口。对这个定义的理解,需要追溯到操作系统的发展历史上,当WINDOWS操作系统开始占据主导地位的时候,开发WINDOWS平台下的应用程序成为人们的需要。而在WINDOWS程序设计领域处于发展的初期,WINDOWS程序员所能使用的编程工具唯有API函数,这些函数是WINDOWS提供给应用程序与操作系统的接口,他们犹如“积木块”一样,可以搭建出各种界面丰富,功能灵活的应用程序。所以可以认为API函数是构筑整个WINDOWS框架的基石,在它的下面是WINDOWS的操作系统核心,而它的上面则是所有的华丽的WINDOWS应用程序。

但是,那时的WINDOWS程序开发还是比较复杂的工作,程序员必须熟记一大堆常用的API函数,而且还得对WINDOWS操作系统有深入的了解。然而随着软件技术的不断发展,在WINDOWS平台上出现了很多优秀的可视化编程环境,程序员可以采用“即见即所得”的编程方式来开发具有精美用户界面和功能强大的应用程序。

  这些优秀可视化编程环境操作简单、界面友好(诸如VB、VC++、DELPHI等),在这些工具中提供了大量的类库和各种控件,它们替代了API的神秘功能,事实上这些类库和控件都是构架在WIN32 API函数基础之上的,是封装了的API函数的集合。它们把常用的API函数的组合在一起成为一个控件或类库,并赋予其方便的使用方法,所以极大的加速了WINDOWS应用程序开发的过程。有了这些控件和类库,程序员便可以把主要精力放在程序整体功能的设计上,而不必过于关注技术细节。

  实际上如果我们要开发出更灵活、更实用、更具效率的应用程序,必然要涉及到直接使用API函数,虽然类库和控件使应用程序的开发简单的多,但它们只提供WINDOWS的一般功能,对于比较复杂和特殊的功能来说,使用类库和控件是非常难以实现的,这时就需要采用API函数来实现。

  这也是API函数使用的场合,所以我们对待API函数不必刻来研究每一个函数的用法,那也是不现实的(能用的到的API函数有几千个呢)。正如某位大虾所说:API不要去学,在需要的时候去查API帮助就足够了。

一、在VB中声明API函数有两种方法:如果我们只在某个窗体中使用API函数,我们可以在窗体代码的General部分声明它:

  声明的语法是:
  Private Declare Function ...
  Private Declare Sub.....
  这里必须采用Private声明,因为这个API函数只能被一个窗体内的程序所调用。

  如果我们的程序有多个窗体构成,而且我们需要在多个窗体中使用同一个API函数,就需要在模块中声明了。
  先添加一个模块(如图示),
  然后采用如下语法声明:
  Public Declare Function....
  Public Declare Sub....
  Public声明的含义是把API函数作为一个公共函数或过程,在一个工程中的任何位置(包括所有的窗体和模块)都能直接调用它。 声明完毕我们就能在程序中使用此API函数了。

  二、可采用以下几种方式使用API函数,以SetWindowPos函数为例:
  (1)忽略函数返回值的调用:
    SetWindowPos Form1.hWnd, -2 ,0 ,0 ,0, 0, 3
  注意此时函数的参数是不加括号的。
  (2)Call方法调用:
    Call SetWindowPos(Form1.hWnd, -2, 0, 0, 0, 3)
  注意这里需要加上括号,但我们不取回函数的返回值。
  (3)取得函数返回值的调用:
    MyLng = SetWindowPos(Form1.hWnd, -2, 0, 0, 0, 3)
  此时需要加上括号,而且我们必须事先定义一个变量(变量的类型与函数返回值类型相同)来存储API函数的返回值。

  三、几个问题的说明:

  (1)声明中的Lib 和 Alias 是怎么回事
  一般情况下WIN32API函数总是包含在WINDOWS系统自带的或是其它公司提供的动态连接库DLL中,而Declare语句中的Lib关键字就用来指定DLL(动态连接库)文件的路径,这样VB才能找到这个DLL文件,然后才能使用其中的API函数。如果我们只是列出DLL文件名而不指出其完整的路径的话,VB会自动到.EXE文件所在目录、当前工作目录、WINDOWS\SYSTEM目录、WINDOWS目录下搜寻这个DLL文件。所以如果所要使用DLL文件不在上述几个目录下的话,我们应该指明其完整路径。
  Alias用于指定API函数的别名,如果我们调用的API函数要使用字符串(参数中包含String型)的话,Alias关键字是必须的。这是因为在ANSI和Unicode字符集中同一API函数的名称可能是不一样的,为了保证不出现声明错误,我们使用Alias关键字指出API函数的别名,一般来说在WIN9X平台下我们把API函数名后加一个大写A作为别名即可。

  (2)常见的API参数类型的说明
  API函数的参数中最常见的是长整Long型数据类型,例如API中的句柄、一些特定的常量、函数的返回值都是此类型 的值;另外几种常见的参数类型有:整型Integer、Byte型、String型等。

  (3)声明中的ByVal是作什么用的
  这跟VB的参数传递方式有关,在默认情况下VB是通过地址传递方式传递函数的参数、而有些API函数要求必须采用传值方式来传递函数参数(这两种参数传递方式是不同的,前者传递的是一个指针,而后者要求是参数真实的值)。这样就会发生错误,解决的办法是在API函数参数声明的前面加上ByVal关键字,这样VB就采用传值方式传递参数了。

  (4)怎样得到完整的API函数声明
  VB自带了API文本查看器API TEXT VIEWER,我们可以在其中找到API函数的完整声明,然后把它粘贴到程序中即可。

按照通常的划分标准,WIN32 API函数分为七大类:

  1、窗口管理类:这类API函数向应用程序提供了一些创建和管理用户界面的方法,我们可以使用它们来做出程序的界面。
  2、窗口通用控制类:系统SHELL提供了一些控制,使用这些控制可以使窗口具有与众不同的外观,通用控制是由通用控制库COMCTL32.DLL提供的。
  3、SHELL特性类:应用程序可以使用它们来增强系统SHELL各方面的功能。
  4、图形设备接口(GDI):提供绘图、图形处理、使用显示设备等一系列的API函数。
  5、系统服务类:为计算机提供了访问计算机资源以及底层操作的手段。
  6、国际特性类:有助于我们编写国际化的应用程序,提供Unicode字符集和多语种支持。
  7、网络服务类:允许网络上的不同计算机之间的不同应用程序之间进行通讯,用于在各计算机上创建和管理共享资源的连接。

  上面的分类对于我们来说还是显得宽泛了一些,所以本节以后的各节会采用小分类的方法,也就是按具体功能的划分为大家介绍一些常用的API函数的用法。

附API函数用法: yRSIwtjt.rar (163.83 KB, 下载次数: 44)
[此贴子已经被作者于2006-3-15 12:05:44编辑过]

TA的精华主题

TA的得分主题

发表于 2006-3-19 11:21 | 显示全部楼层
我在WINXP+OFFICE 2000上试了一下,是能提取图,但插入的剪贴画和在WORD中手绘的图提取质量好像很低,可能是以屏幕分辨率提取的,字节数都非常小. 请看附件. KcWjjU1H.rar (37.42 KB, 下载次数: 55) [em09]
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-16 10:29 , Processed in 0.035819 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表