找回密码
 注册帐号
查看: 2679|回复: 10

[编程技巧] %%易语言API高级技巧%%(1)

[复制链接]
发表于 2010-3-10 10:29:12 | 显示全部楼层 |阅读模式
1,使用指针
易语言中出于安全、方便考虑,没有直接提供指针,这在进行一些高级操作时不是很方便,虽然有一些第三方支持库可以取出变量指针(比如我的eLib++ 注:该支持库系Delphi开发,本人已开放源代码,你可以到易语言下载区看看)但是仅仅为了这个操作就带上一个支持库不太值得。其实用一个API,加上一些技巧就可以欺骗windows和易语言,让它们告诉你一个变量的指针。
这个API是lstrcpyn。用过C开发Windows下的程序的朋友可能对这个API比较熟悉,就是字符串拷贝。在windows下取代C标准库函数strncpy的。字符串拷贝怎么能取得变量指针呢?秘密就在这个API的返回值:
看看MSDN:“If the function succeeds, the return value is a pointer to the buffer”
该函数把第二个参数指定的字符串复制到第一个参数指定的字符串,第三个参数指定复制的长度。如果复制成功,返回第一个参数(缓冲区buffer)的地址。看到了吗?它返回第一个参数的地址!!那么我们把需要取地址的变量给它的第一个参数,然后想办法让它复制成功,它不就返回了那个变量的地址了吗?

定义一个DLL命令如下:
Dll命令:取文本指针
返回值类型:整数型
在Dll库中的命令名:lstrcpyn
     参数:欲取其指针的文本  数据类型:文本型  <传址>
     参数:欲取其指针的文本  数据类型:文本型  <传址>
     参数:保留  数据类型:整数型  备注:0

这样调用:
文本1 = “abcdefg”
指针1 = 取文本指针 (文本1, 文本1, 0)

把文本1复制到自身,复制长度为0字节(也就是什么都不复制),然后返回文本1的指针。就这么简单。先告诉windows我要复制一个文本到某个内存地址,但同时告诉它我什么都不复制,它实际上帮你取出了这个文本的指针。

上面的例子是取文本的指针,其他类型的变量也一样的,因为在API内部(其实是在内存中)什么类型的变量都表现为一块内存区域,原理是一样的。但是易语言是强制类型的语言,所以这次要骗骗易语言了,呵呵,再定义这个API的一个新版本,把它的参数定义成你想要的类型就可以了。

Dll命令:取整数指针
返回值类型:整数型
在Dll库中的命令名:lstrcpyn
     参数:欲取其指针的整数  数据类型:整数型  <传址>      备注:一定要传址
     参数:欲取其指针的整数  数据类型:整数型  <传址>      备注:一定要传址.重复一次
     参数:保留  数据类型:整数型  备注:0


2,特殊的结构用字节集代替
Window98及其后的操作系统提供了一个非常棒的API :GradientFill,利用这个API可以方便地画出渐变的效果。
这个API倒不是很麻烦,参考MSDN我们很快就可以在易语言中定义出这个DLL命令:(以渐变填充矩形为例)


Dll命令:GradientFill
返回值类型:逻辑型
Dll库文件名:Msimg32.dll
在Dll库中的命令名:GradientFill
     参数:hDC   数据类型:整数型
     参数:pVertex     数据类型:TRIVERTEX
     参数:dwNumVertex       数据类型:整数型
     参数:pMesh       数据类型:GRADIENT_RECT
     参数:dwNumMesh   数据类型:整数型
     参数:dwMode      数据类型:整数型
 楼主| 发表于 2010-3-10 10:29:39 | 显示全部楼层
其中TRIVERTEX 和GRADIENT_RECT时自定义的数据类型:

自定义数据类型:TRIVERTEX
     成员:x     数据类型:整数型
     成员:y     数据类型:整数型
     成员:Red   数据类型:短整数型
     成员:Green  数据类型:短整数型
     成员:Blue   数据类型:短整数型
     成员:Alpha  数据类型:短整数型

自定义数据类型:GRADIENT_RECT
     成员:UpperLeft   数据类型:整数型
     成员:LowerRight  数据类型:整数型


根据MSDN的说明,根本没有问题,但是如果你调用这个函数,你不会成功的。为什么?我告诉你原因在TRIVERTEX的定义上。你也许会说,这个没有问题啊,MSDN上定义如下:
typedef struct _TRIVERTEX {
LONG        x;
Long        y;
COLOR16     Red;
COLOR16     Green;
COLOR16     Blue;
COLOR16     Alpha;
}TRIVERTEX, *PTRIVERTEX;

C语言的LONG 和Long在windows 32位下是32位,对应于易语言“整数型”,COLOR16为十六位,对应于易语言的“短整数型”没有问题啊!那如果我再告诉你,易语言中的自定义数据类型的成员均是四字节对齐的,你该理解了吧。是的,易语言中的自定义数据类型的成员均是四字节对齐的,如果不足四字节,会自动对齐到四字节的。具体到上面的定义,Red,Green,Blue,Alpha虽然被定义为“短整数型”但是在易语言内部,它们均被扩充为“整数型”了。这就是问题的根源。解决的办法就是用字节集代替自定义数据结构。易语言的字节集不存在四字节对齐的问题。


Dll命令:GradientFill
返回值类型:逻辑型
Dll库文件名:Msimg32.dll
在Dll库中的命令名:GradientFill
     参数:hDC   数据类型:整数型
     参数:pVertex     数据类型:字节集
     ……            ………………..

这样定义就可以了。为了方便地生产所需要的字节集数据,我有定义了一个子程序:

子程序:TRIVERTEX到字节集
返回值类型:字节集
备注:由于内存对齐的原因,必须把TRIVERTEX类型转换为字节集才可以调用API成功

参数:VertEX      数据类型:TRIVERTEX     <数组>

局部变量:元素个数      数据类型:整数型
局部变量:变量    数据类型:整数型
局部变量:数据    数据类型:字节集

元素个数 = 取数组成员数 (VertEX)
计次循环首 (元素个数, 变量)
   数据 = 数据 + 到字节集 (VertEX [变量].x)
   数据 = 数据 + 到字节集 (VertEX [变量].y)
   数据 = 数据 + 到字节集 (VertEX [变量].Red)
   数据 = 数据 + 到字节集 (VertEX [变量].Green)
   数据 = 数据 + 到字节集 (VertEX [变量].Blue)
   数据 = 数据 + 到字节集 (VertEX [变量].Alpha)
计次循环尾 ()
返回 (数据)
其他具有类似特征(参数或结构中有非四字节的)的API都可以用上述的方法来变通解决。

评分

参与人数 1魅力 +9 收起 理由
累了 + 9 辛苦了

查看全部评分

发表于 2010-3-11 19:36:41 | 显示全部楼层
puv我是初学者,还没那么深。。。不过先看看,相信会有用的。。。
发表于 2010-3-24 14:57:39 | 显示全部楼层
我来看看,真不错的
发表于 2010-3-26 20:10:08 | 显示全部楼层
ip ip 学习了,不错,谢谢了!!!1
发表于 2010-3-28 19:36:35 | 显示全部楼层
还是不太看得懂
发表于 2010-4-11 08:19:18 | 显示全部楼层
这很高级啊 。除了要研究上手外,还要多熟练练
发表于 2010-4-14 19:40:11 | 显示全部楼层
学习了!顶个!
发表于 2011-11-28 11:21:44 | 显示全部楼层
刚开始学,看不懂啊!哎~~~~~
回复 支持 反对

使用道具 举报

发表于 2011-12-4 19:59:25 | 显示全部楼层
- -。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2011-12-9 15:13:23 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

QQ|Archiver|手机版|小黑屋|依人网络官方网站 ( 陕ICP备19025998号-1 )

GMT+8, 2024-3-29 19:00 , Processed in 0.052278 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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