1234567i怎样弹出i am loserr

查看: 3408|回复: 94
【新片首发】夏洛特烦恼(清晰修正画面版) Goodbye Mr Loser 2015 HDTC 720p MP4/中英双字/1.23G
注册时间14-07-10
最后登录70-01-01
TA的每日心情慵懒6&天前签到天数: 167 天[LV.7]常住居民III
发表于 15-10-04 16:54:50
导演: 闫非 / 彭大魔
编剧: 闫非 / 彭大魔
主演: 沈腾 / 马丽 / 尹正 / 艾伦 / 王智 / 田雨 / 宋阳 / 常远 / 李萍 / 李立群 / 张一鸣
类型: 喜剧 / 爱情
制片国家/地区: 中国大陆
语言: 汉语普通话
上映日期: (中国大陆)
片长: 104分钟
又名: Goodbye Mr. Loser
IMDb链接: tt5061814
昔日校花秋雅(王智 饰)的婚礼正在隆重举行,学生时代暗恋秋雅的夏洛(沈腾 饰)看着周围事业成功的老同学,心中泛起酸味,借着七分醉意大闹婚礼现场,甚至惹得妻子马冬梅(马丽 饰)现场发飙,而他发泄过后却在马桶上睡着了。梦里他重回校园,追求到他心爱的女孩、让失望的母亲重展笑颜、甚至成为无所不能的流行乐坛巨星……
  醉生梦死中,他发现身边人都在利用自己,只有马冬梅是最值得珍惜的……
百度网盘下载地址:(下载完成后去掉文件扩展名的数字1即可正常观看)链接:& &密码:
已有 45 人购买&
本主题需向作者支付 10 枚金币 才能浏览
注册时间14-05-06
最后登录70-01-01
TA的每日心情无聊1&小时前签到天数: 91 天[LV.6]常住居民II
发表于 6&天前
谢谢LZ分享~~~~~~~~~~~~~~
注册时间13-05-31
最后登录70-01-01
TA的每日心情开心16-02-03 09:43签到天数: 101 天[LV.6]常住居民II
发表于 16-01-15 09:14:16
夏洛特烦恼!!!!!!!!!!!!
[]: 一个袋子砸在了 zhaohui 头上,zhaohui 赚了 1 枚 金币.
注册时间15-05-18
最后登录70-01-01
TA的每日心情难过3&天前签到天数: 22 天[LV.4]偶尔看看III
发表于 15-12-19 21:38:48
好片&&看看谢谢
注册时间14-04-15
最后登录70-01-01
TA的每日心情擦汗15-12-08 21:35签到天数: 11 天[LV.3]偶尔看看II
发表于 15-11-26 04:49:41
谢谢楼主分享好电影
[]: 淘天下 捡了钱没交公 威望 降了 2 点 .
注册时间14-01-24
最后登录70-01-01
TA的每日心情慵懒7&天前签到天数: 74 天[LV.6]常住居民II
发表于 15-11-21 19:32:16
huif回复拿密码~~
注册时间14-06-12
最后登录70-01-01
TA的每日心情无聊16-01-16 23:42签到天数: 11 天[LV.3]偶尔看看II
发表于 15-11-20 17:59:37
不错的电影,下来收藏
注册时间15-02-07
最后登录70-01-01
TA的每日心情无聊16-01-30 10:43签到天数: 68 天[LV.6]常住居民II
发表于 15-11-19 23:54:53
听说很好笑 下来看看 3Q
注册时间13-08-19
最后登录70-01-01
TA的每日心情开心前天&02:36签到天数: 70 天[LV.6]常住居民II
发表于 15-11-16 03:27:08
感谢楼主分享。。。。。。。。。。。。。。。。。
注册时间15-02-07
最后登录70-01-01
TA的每日心情郁闷4&天前签到天数: 4 天[LV.2]偶尔看看I
发表于 15-11-14 20:52:31
支持一下支持支持一下支持
GMT+8, 16-02-11 14:01
Powered by
X3.2 Designed By当前访客身份:游客 [
我不做凡客很多年
:不够详细,原理没讲
:你在dll中申请了 内存 ,然后在 程序中释放的吧?...
:没有多余 今天按阁下的路线走了一遍 虽然费了点周...
今日访问:8
昨日访问:11
本周访问:36
本月访问:218
所有访问:13299
列表模式: |
有些时候,要写一些程序,在 JAVA 里面好难实现, 但如果使用其它编程语言却又比较容易时,我们不妨通过 JNI 来让不同语言的程序共同完成. JNI 的教程, 网上 C 的比较多,Java 也提供了 javah.exe 为 C 语言的 JNI 程序生成头文件, 如果你是一个 Delphi 编程员, 能否让 JAVA 与 Delphi 程序交互呢? 答案是肯定的,今天我们就来看一下一个简单的例子. Helloworld. 主要是来认识一下, JAVA 怎样调用 Delphi 程序的方法.
好的,我们先来创建一个类:
package alvinJNI;
class HelloWorld { static { System.loadLibrary(&DelphiAction&); //等一下我们就用Delphi来编一个程序,编好之后生成的文件就是 DelphiAction.dll 这是一个动态链接库文件,这个类里先在静态语句块中加载它 }
public native void printText(); //声明一个 native 的本地代码程序,我们使用的是 Delphi 来编写.注意:这个方法在这里只是声明,并没有定义方法体,因为这个方法我们要用 Delphi 来实现.
public static void main(String[] args) { //创建对象并调用里面的 native 方法. HelloWorld hw = new HelloWorld(); hw.printText(); }
类写完编译后,接下来的事情就由 Delphi 来解决了
我们运行 Delphi 后新建 DLL 工程: file-&new-&other,然后在 new 选项卡里面选择 Dll Wizard 就创建了一个新的工程了, 我们选择一个文件夹来保存工程 在保存工程后,我们需要下载 jni.pas 加入到我们的工程中,这是国外的高手写的程序单元,它方便我们的 Delphi 程序与 JAVA 交互. 可从下面地址下载到: 解压之后里面有两个文件,将其存放在工程的目录下
接下来我们编写 Delphi 代码:
library DelphiA //这里设置动态链接库的名称,因为我们刚才写 JAVA 类时是用 DelphiAction,所以这里了要设置为 DelphiAction
{ Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. 这里面都是注释,是自动生成的,可以删去 }
Uses JNI; //注意了,我们刚才下载了 JNI.pas 放在工程目录中,这里要在 Uses 里面声明,才能使用.
//下面我们来写一个函数,就是为 刚才 JAVA 类实现一个简单的方法 //因为要让 JAVA 能够调用到这个函数,所以这个函数的命名是非常讲究的,名称各段的分隔符是 _ 下划线 //本例的函数如下: 即 Java_包名_类名_类中的方法名 //函数必须设置为 stdcall procedure Java_alvinJNI_HelloWorld_printText(PEnv: PJNIE Obj: JObject);
begin //函数体非常简单,因为我们只是了解一下如何调用 Delphi 的函数. Writeln('您好!看到效果了吧。');
exports Java_alvinJNI_HelloWorld_printT //为函数做引出声明,这样才能真正的被调用到
代码完成,我们 Ctrl+F9 编译 DLL
生成 DelphiAction.dll 后,我们把他复制到 Java 工程目录 注意:上面的类是打包在 alvinJNI 包中 假如我们的 Java 工程是在 C:/test 那么刚才编译后的类必须放在 c:/test/alvinJNI/HelloWorld.class 而刚刚编译完成的 DelphiAction.dll就放在 c:/test/DelphiAction.dll 然后在 C:/test 目录中执行: java alvinJNI/HelloWorld 看看你的 Java 程序调用了 DelphiAction 是怎么样的效果.
呵呵,爽吧! 今天我们才做了一点点,只学了一下如何在 JAVA 调用 Delphi 和程序,在接下来,我会贴出更多的教程,以学习一些高级一点点的 JNI 知识.
现在难得来看一下自己的博客,今天好不容易找了个代理,顺便再继续之前的话题,就是 JAVA 与 Delphi 的交互了.
在上一篇中,我们说了如何用 Java 调用 Delphi 程序的一个方法,今天我们再深入一点,就是怎样提交参数个 Delphi 的方法,以动态的控制 Delphi 的方法. 下面,我们切入正题.
首先,我们定义如下的 Java 类:
//---------------------------------------------------------------------------------------------------------- package alvinJNI;
class HelloWorld { static { System.loadLibrary(&DelphiAction&); }
public native void printText(String str);
public static void main(String[] args) { HelloWorld hw = new HelloWorld(); hw.printText(&您好!看到效果了吧。&); }
} //----------------------------------------------------------------------------------------------------------
我们再像上次一样在 Delphi 中建立 DLL 工程,写下面的代码(有注释):
//---------------------------------------------------------------------------------------------------------- library DelphiA
//这一次我们要写的这个方法因为要接收一个 Java 传过来的参数,所以我们来说一下这个参数列表的问题 //参数列表中的第一个参数 PEnv 类型为 PJNIEnv, 它是 JNI.pas中定义的类型,我们好多工作要通过它来实现,可以把它看成是一个帮你的程序与 Java 沟通的桥梁. //参数列表中的第一个参数 obj 类型为 JObject.前面这两个参数是固定的,这第二个参数暂时我们还不会用到. //今天,我们还要给这个方法多加一个参数,用来接受 Java 传过来的参数. str: JString
procedure Java_alvinJNI_HelloWorld_printText(PEnv: PJNIE Obj: JO str: JString); //这回我们需要用到一个 TJNIEnv 对象,我们来声明 var JVM: TJNIE tmpStr: S
begin //实例化 JVM, 这个对象可以看成是 Java 的虚拟机.(自己的理解) JVM := TJNIEnv.Create(PEnv);
//参数提交过来的字符串,实际上是一个 JString 对象,我们在这里要用 JVM 来转化它. //我们调用 JVM 的 UnicodeJStringToString 函数就可以实现 JString 到 String 的转化了. tmpStr := JVM.UnicodeJStringToString(str);
Writeln(tmpStr);
//我们使用完 JVM 后,要将其释放. JVM.F
exports Java_alvinJNI_HelloWorld_printT //为函数做引出声明,这样才能真正的被调用到 end. //----------------------------------------------------------------------------------------------------------
我们现在就可以生成 DelphiAction.dll 将其放在 Java 工程目录下, 再执行 alvinJNI.HelloWorld 看看效果了.
好了,我们今天主要就是实现了一下,如何在 Java 调用 Delphi 的方法时,给其提交一个参数. 是不是很爽?
在上一篇中,我们说了如何用 Java 调用 Delphi 程序的一个方法并传递给其一个字符串参数,现在我们再来看一下如果传递的参数是其它基本类型,又要怎么做.
首先,我们先看一下如何传递 int 型参数,定义如下的 Java 类:
//---------------------------------------------------------------------------------------------------------- package alvinJNI;
class HelloWorld { static { System.loadLibrary(&DelphiAction&); }
public native void printText(int i);
public static void main(String[] args) { HelloWorld hw = new HelloWorld(); hw.printText(100); }
} //----------------------------------------------------------------------------------------------------------
我们再像上次一样在 Delphi 中建立 DLL 工程,写下面的代码(有注释):
//---------------------------------------------------------------------------------------------------------- library DelphiA
//我们给这个方法加的参数是: i: JInt procedure Java_alvinJNI_HelloWorld_printText(PEnv: PJNIE Obj: JO i: JInt); var tmpInt: I
begin //参数提交过来的 int 型数据,在这里是一个 JInt 数据,它其实就是一个 Integer 数据,它的使用更加方便 //它可以直接地参与 Interger 类型数据的运算,是不是很容易. tmpInt := i + 100; tmpInt := tmpInt - 100; Writeln(tmpInt);
exports Java_alvinJNI_HelloWorld_printT end. //----------------------------------------------------------------------------------------------------------
再看看效果吧,是不是成功了?
这里如果是 long 型参数,接收时要设为 JLong 类型,它也可以跟对应的整型数运算,我们常用它跟 Int64 一起运算 如果参数类型是 float ,接收参数时要设为 JFloat 类型,它也可以跟跟 Single 一起运算 如果参数类型是 double ,接收参数时要设为 JDouble 类型,它也可以跟跟 Delphi 中的 Double 型数据一起运算 如果参数类型是 boolean ,接收参数时要设为 JBoolean 类型,它也可以跟跟 Delphi 中的布尔型数据一起运算 如果参数类型是 short ,接收参数时要设为 JShort 类型,它也可以跟跟 SmallInt 型数据一起运算 如果参数类型是 byte ,接收参数时要设为 JByte 类型,它也可以跟跟 ShortInt 型数据一起运算 如果参数类型是 Object 的 Java 对象,接收时要设为 JObject 类型,它的用法比较复杂(涉及到对 Java 类和对象的操作),我们在以后再来学习. 如果参数类型是 Type[] 数组,接收参数时要设为 JObject 类型,因为 Java 是把数组作为对象看待的.它要以以下的方式来使用:
例如: 我们要给 Delphi 的方法传入一个 byte[] 型数组,在定义 Delphi 方法时参数声明为 bytearray: JObject
在方法中: var PByteArr: PJByte //PJByte 是 JNI.pas 定义的, 里面还有 PJBoolean, PJObject, PJInt 等.. JVM: TJNIE isCopy: B begin JVM:= TJNIEnv.Create(PEnv); isCopy := PByteArr := JVM.GetByteArrayElements(bytearray, isCopy); //调用这个方法,可以将取得参数 bytearray 的地址, isCopy 决定是否复制数组 //之后,我们可以通过 PByteArr 结合 inc(PByteArr) 这个指针来操作传过来的数组.
在上一篇中,我们说了如何用 Java 调用 Delphi 程序的一个方法并传递给其一个参数 现在我们再来看一下如果如果要调用的方法有返回值,又要怎么做.
首先,我们先定义如下的 Java 类:
//------------------------------------------------------------------------------ package alvinJNI;
class HelloWorld { static { System.loadLibrary(&DelphiAction&); }
public native String printText(String arg);
public static void main(String[] args) { HelloWorld hw = new HelloWorld(); System.out.println(hw.printText(&你好&)); }
} //-------------------------------------------------------------------------------
我们再像上次一样在 Delphi 中建立 DLL 工程,写下面的代码(有注释):
//------------------------------------------------------------------------------- library DelphiA
//今天,因为这个方法有返回值,所以不再是 procedure 过程,我们要变成 function 函数, 返回值类型为 JString function Java_alvinJNI_HelloWorld_printText(PEnv: PJNIE Obj: JO arg: JString): JS var tmpStr: S JVM: TJNIE tt: B begin JVM:= TJNIEnv.Create(PEnv);
//我们这里先把参数提交过来的 JString 转换成 Delphi 中的 String 后就可以使用了 tmpStr := '你想输出的字符串是: &' + JVM.UnicodeJStringToString(arg) + '&。';
//当字符串要转换成 JString 我们需要先对字符串进行 UTF8 编码后再转换成 PChar 再转换成 JString //这样才能保证返回的字符串在 JAVA 中不乱码 Result := JVM.StringToJString(pchar(UTF8Encode(tmpStr))); JVM.F
exports Java_alvinJNI_HelloWorld_printT end. //--------------------------------------------------------------------------------
再看看效果吧,是不是成功了?
这里如果返回值的类型是其它的其本类型,比如 JLong,JInt,JFloat,JDouble,JBoolean,JShort,JByte 这些类型的数据可以直接与 Delphi 中的数据运算,对应 Int64,Integer,Single,Double,Boolean,SmallInt,ShortInt 返回时可以直接给 Result 赋 Delphi 中的数值. 如: function Java_alvinJNI_HelloWorld_getInt(PEnv: PJNIE Obj: JObject): JI var tmp: I begin tmp := 10; Result :=
如果返回值的类型是 Object 的 Java 对象,返回 JObject 类型,它的用法我们在以后再来学习. 如果返回值的类型是 Type[] 数组,接收参数时要设为 JObject 类型,怎样创建这样的数组对象,我自己也还不知道,以后知道了我再来贴上 因为 Java 是把数组作为对象看待的.它要以以下的方式来使用:
例如: 我们要给 Delphi 的方法传入一个 byte[] 型数组,在定义 Delphi 方法时参数声明为 bytearray: JObject
在方法中: var PByteArr: PJByte //PJByte 是 JNI.pas 定义的, 里面还有 PJBoolean, PJObject, PJInt 等.. JVM: TJNIE isCopy: B begin JVM:= TJNIEnv.Create(PEnv); isCopy := PByteArr := JVM.GetByteArrayElements(bytearray, isCopy); //调用这个方法,可以将取得参数 bytearray 的地址, isCopy 决定是否复制数组 //之后,我们可以通过 PByteArr 结合 inc(PByteArr) 这个指针来操作传过来的数组.
之前,我们学了如何用 Java 调用 Delphi 程序的一个方法 如果在Delphi 程序在适当时候需要调用 Java 程序,又要怎么做呢?
首先,我们先定义如下的 Java 类:
//------------------------------------------------------------------------------ package alvinJNI;
class HelloWorld { static { System.loadLibrary(&DelphiAction&); } String str = &你好&;
public native void callPrintText(HelloWorld hw);
public void printText(String arg) { System.out.println(arg); }
public static void main(String[] args) { HelloWorld hw = new HelloWorld(); hw.callPrintText(hw); }
} //-------------------------------------------------------------------------------
我们再像上次一样在 Delphi 中建立 DLL 工程,写下面的代码(有注释):
//------------------------------------------------------------------------------- library DelphiA
//今天的这个程序稍微的复杂一点,因为要调用 Java 对象的方法,在这里可以学到对 JObject 的操作 procedure Java_alvinJNI_HelloWorld_callPrintText(PEnv: PJNIE Obj: JO arg: JObject); var JVM: TJNIE c: JC //类ID fid: JFieldID; //属性ID mid: JMethodID; //方法ID tmpStr: JS javaargs : array[0..0] of JV //调用方法时的参数 begin JVM := TJNIEnv.Create(PEnv);
{我们先来看下如何获得一个对象的某个属性值} {----------------------------------------} {我们对 Java 对象的操作要选获取这个对象的 ClassID,我们可以用下面的方法来取得.} c := JVM.GetObjectClass(arg);
{我们先来获取参数 HelloWorld arg 对象的 String str 这个属性的值 这里我们先要获得这个属性在它所在类中的属性 ID } fid := JVM.GetFieldID(c, 'str', 'Ljava/lang/S'); {上面调用的这个方法中的参数分别是: 所属类ID, 属性名, 属性类型签名 关于属性类型的签名,将在下面 '说明1' 给出}
{下面,我们就可以根据 属性ID 来获取属性值了, 这里我们会取得到 arg.str 这个字符串} tmpStr := JVM.GetObjectField(arg, fid); {上面的这个 JVM.GetObjectField(arg, fid) 用来获取属性值 参数分别是: 要取得其属性的对象, 要取得的属性的属性ID 这里取得的是一个 Java 的 String 对象,是 JString,其实它也就是 JObject 类型的} writeln('Delphi 输出的: ' + JVM.UnicodeJStringToString(tmpStr));
{我们再来看下如何调用一个 JObject 的方法, 这里我们要调用的是 arg.printText() 这个方法} {------------------------------------------------------------------------------------} //我们还是要用到上面的那个 类ID: c. //这一次我们要取得这个方法的 方法ID mid := JVM.GetMethodID(c, 'printText', '(Ljava/lang/S)V'); //上面调用的这个方法中的参数分别是: 所属类ID, 方法名, 方法(参数+返回值)类型签名 //关于方法(参数+返回值)类型的签名,将在下面 '说明2' 给出
//有了 方法ID 后我们就可以用这个ID来调用这个方法了,我们这里要调用的方法是: arg.printText(参数); //因为我们要调用的这个方法有参数, 调用 Java 方法的时候如果有参数,要建立参数数组,这里我们就来建立数组 javaargs[0].l := tmpS {这里这个 javaargs 是 JValue 类型. 它有点特殊,它的用法在下面 说明3 给出}
{有了 类象, 方法ID, 参数. 下面我们就可以调用 arg.printText(javaargs) 这个方法了,使用下面这个方法就可实现} JVM.CallObjectMethodA(arg, mid, @javaargs);
exports Java_alvinJNI_HelloWorld_callPrintT end.
//--------------------------------------------------------------------------------
到这里,我们已经可以从 Delphi 中获得 Java 对象的属性了, 还可以调用一个 Java 对象的方法,是不是很酷呢? 你学到了没?
###########################说明1############################### 现在,我们还要再了解一个获取 &属性ID& 时的那个签名 上面例子中: fid := JVM.GetFieldID(c, 'str', 'Ljava/lang/S'); 用的签名是: 'Ljava/lang/S' 因为刚刚要获得的属性是 java.lang.String 类型的,所以它的签名是: 'Ljava/lang/S' 如果,我们要获得的属性是其它类型,获取 属性ID 时又要怎样签名呢?下面给出一个对照表
byte -- B char --- C double -- D float -- F int -- I long -- J (注意:是J不是L) short -- S void -- V boolean - Z(注意:是Z不是B) class(类对象类型) - 'L'+完整类名+';' (包路径分隔符为: '/'. 如上面例子中的 String 对型, 签名为: 'Ljava/lang/S')
数组 type[] -- '['+type (例如 float[] 的签名就是 '[float') (如果是二维数组,如float[][],则签名为 '[[float')
############################说明2############################### 现在,我们还要再了解一个获取 &方法ID& 时的那个签名 上面例子中: mid := JVM.GetMethodID(c, 'printText', '(Ljava/lang/S)V'); 用的签名是: '(Ljava/lang/S)V' 方法ID 的签名,分为两部分 一部分是前面括号中的,是参数类型的签名 另一部分是括号后的,是返回值类型的签名 其中某个签数与返回值的类型签名与获取属性ID时的签名是一样的 上面要调用的方法只有一个参数,如果有多个参数时又怎样呢?
如: int getInt(long a, double b); 这样的 Java 方法要这样签名: '(JD)I' (注意:参数签名是连续的,没有分隔符, 这里第一个参数 long 签名为:J, 第二个参数签名为: D, 返回值类型 int 签名为: I) 说到这里,相信大家都会使用这个签名了
############################说明3############################### 在调用一个 Java 方法时, 如果这个方法有参数, 我们就要传递一个参数数组的地址给 Java 现在,我们还要再了解如何创建这样的一个参数数组 传递给 Java 方法的参数,类型均为 JValue. 它是一个packed record
如果,我们要调用的方法 void myMethod(int a, long b, String c); 有 3 个参数 那么 1.我们先要声明如下数组: var args : array[0..1] of JV 2.给数组赋值 args[0].i := 100; args[1].j := 100; args[2].l := JVM.StringToJString(pchar(UTF8Encode('开源中国社区 http://www.oschina.net'))); 3.调用 JVM.CallVoidMethodA(Java对象, 方法ID, @args);
JValue 是一个 packed record,它的定义如下: JValue = packed record case Integer of 0: (z: JBoolean); 1: (b: JByte ); 2: (c: JChar ); 3: (s: JShort ); 4: (i: JInt ); 5: (j: JLong ); 6: (f: JFloat ); 7: (d: JDouble ); 8: (l: JObject );
调用方法时,TJNIEnv 还有: CallObjectMethodA: function(Env: PJNIE Obj: JO MethodID: JMethodID; Args: PJValue): JO {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallBooleanMethodA: function(Env: PJNIE Obj: JO MethodID: JMethodID; Args: PJValue): JB {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallByteMethodA: function(Env: PJNIE Obj: JO MethodID: JMethodID; Args: PJValue): JB {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallCharMethodA: function(Env: PJNIE Obj: JO MethodID: JMethodID; Args: PJValue): JC {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallShortMethodA: function(Env: PJNIE Obj: JO MethodID: JMethodID; Args: PJValue): JS {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallIntMethodA: function(Env: PJNIE Obj: JO MethodID: JMethodID; Args: PJValue): JI {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallLongMethodA: function(Env: PJNIE Obj: JO MethodID: JMethodID; Args: PJValue): JL {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallFloatMethodA: function(Env: PJNIE Obj: JO MethodID: JMethodID; Args: PJValue): JF {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallDoubleMethodA: function(Env: PJNIE Obj: JO MethodID: JMethodID; Args: PJValue): JD {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallVoidMethodA: procedure(Env: PJNIE Obj: JO MethodID: JMethodID; Args: PJValue); {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallNonvirtualObjectMethodA: function(Env: PJNIE Obj: JO AClass: JC MethodID: JMethodID; Args: PJValue): JO {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallNonvirtualBooleanMethodA: function(Env: PJNIE Obj: JO AClass: JC MethodID: JMethodID; Args: PJValue): JB {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallNonvirtualByteMethodA: function(Env: PJNIE Obj: JO AClass: JC MethodID: JMethodID; Args: PJValue): JB {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallNonvirtualCharMethodA: function(Env: PJNIE Obj: JO AClass: JC MethodID: JMethodID; Args: PJValue): JC {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallNonvirtualShortMethodA: function(Env: PJNIE Obj: JO AClass: JC MethodID: JMethodID; Args: PJValue): JS {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallNonvirtualIntMethodA: function(Env: PJNIE Obj: JO AClass: JC MethodID: JMethodID; Args: PJValue): JI {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallNonvirtualLongMethodA: function(Env: PJNIE Obj: JO AClass: JC MethodID: JMethodID; Args: PJValue): JL {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallNonvirtualFloatMethodA: function(Env: PJNIE Obj: JO AClass: JC MethodID: JMethodID; Args: PJValue): JF {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallNonvirtualDoubleMethodA: function(Env: PJNIE Obj: JO AClass: JC MethodID: JMethodID; Args: PJValue): JD {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF} CallNonvirtualVoidMethodA: procedure(Env: PJNIE Obj: JO AClass: JC MethodID: JMethodID; Args: PJValue); {$IFDEF MSWINDOWS} {$ENDIF} {$IFDEF LINUX} {$ENDIF}
好了,到这里,相信大家对做 Delphi 的 JNI 已有一定的了解 关于 Delphi JNI 的话题就先说到这里 如果有兴趣,大家可以打开 jni.pas 了解更多
发布于 1年前,
阅读(192) | 评论(0) |
投票(0) | 收藏(8)
&&&delphi中可以通过函数指针把一个函数作为参数来传递,然后在另外一个函数中调用。
&&&&1) 首先,申明函数指针类型TFunctionParameter。&&&&&&&type&&&&&&&&&&TFunctionParameter = function(const value : integer) :&&&&&2) 定义准备被作为参数传递的函数&&&&&&&&&function One(const value : integer) :&&&&&&&&&begin&&&&&&&&&&&&result := IntToStr(value) ;&&&&&&&&&&&&&&&&&&function Two(const value : integer) :&&&&&&&&&begin&&&&&&&&&&&&result := IntToStr(2 * value) ;&&&&&&&&&&&&&&&&&&&&3) 定义将要使用动态函数指针参数的函数&&&&&&&&function DynamicFunction(f : TFunctionP const value : integer) :&&&&&&&&begin&&&&&&&&&&&result := f(value) ;&&&&&&&&&&&&&&4) 上面这个动态函数的使用实例&&&&&&&&var&&&&&&&&&&&s :&&&&&&&&begin&&&&&&&&&&&s := DynamicFunction(One,2006) ;&&&&&&&&&&&ShowMessage(s) ; //will display "2006"&&&&&&&&&&&s := DynamicFunction(Two,2006) ;&&&&&&&&&&&ShowMessage(s) ; // will display "4012"&&&&&&&&
一个指向函数的指针在赋值指向函数时,不需要显示地取函数的地址。
var F:function(X:Integer):I
function aa(X:Integer):I
不需要: F:=^
只要:F:=就可以了。
F:=aa可能是一个函数类型变量赋值,也可能是调用aa函数过程。
如果F不是一个函数过程类型,它就是一个函数调用。
但是只要是出现在表达式中,就一定是函数过程的调用。
例:if A:=fun then
A:=fun一定是一个函数过程的调用,将返回值赋予A
注意,如果fun是一个过程(它没有返回值)或它需要参数(需要写上参数),那就会产生语法错误。
如果要显示说明它是一个赋值语句而不是函数过程的调用,可以这样写
@A是将A转换成一个无类型指针(它本身就是以指针形式存在)
@fun是取得函数过程fun的地址
可以通过@@A的方式取得该过程函数变量的地址,而不是它指向的函数过程的地址
void SetProcessDataProc(NOTISFYDATAISRECEIVED ProcessDataProc)参数:ProcessDataProc —— 回调函数指针。返回值:无功能:设置数据到达通知函数。动态连接库主动通知用户有新数据到达,随后用户就可以立即查询相关数据。用户调用此接口函数设置通知函数以后,每当新数据到达,动态连接库就通过这个通知函数通知用户。通知函数原型必须如下:(函数名称和参数名称可以不同)void ProcessDataProc(int iBedNo,unsigned char ucDataType,WPARAM wParam);其中,iBedNo参数表示到达数据所对应的设备号。ucDataType表示到达数据类型。ucDataType值与对应的数据包类型以及常调用的接口函数如表1所示。对于表中没有列举的数据包类型,数据包内没有有用的数据。wParam用于传递其他信息,保留,暂时没有使用。所以,SetProcessDataProc接口函数的参数类型NOTISFYDATAISRECEIVED可以定义如下:typedef void(* NOTISFYDATAISRECEIVED)(int iBedNo,unsigned char ucDataType,WPARAM wParam);这是一个动态连接库中一个函数,我现在想在delphi中调用该函数,请问该如何定义上述类型和函数。
void ProcessDataProc(int iBedNo,unsigned char ucDataType,WPARAM wParam);
-&procedure ProcessDataProc(iBedNo: I ucDataType:BYTE; wParam: WPARAM);
typedef void(* NOTISFYDATAISRECEIVED)(int iBedNo,unsigned char ucDataType,WPARAM wParam);-&type NOTISFYDATAISRECEIVED = procedure of(iBedNo: I ucDataType:BYTE; wParam: WPARAM)///
发布于 1年前,
阅读(910) | 评论(0) |
投票(0) | 收藏(3)
新一篇:&IDFTP 控件使用
&&代码模板 : CTRL+J &&代码整块移动 : CTRL+SHIFT+I(右移) CTRL+SHIFT+U(左移)&&选中窗体 : 先选中任一控件,SHIFT+鼠标左键&&将鼠标指向变量名、单元名、类名,再用 CTRL+鼠标左键 可找到相应的说明&&在过程、函数、事件内部, SHIFT+CTRL+向上的方向键 &可跳跃到相应的过程、函数、事件的定义
&&& 相反,在过程、函数、事件的定义处,SHIFT+CTRL+向下的方向键 可跳跃到具体过程、函数、事件内部
&&CTRL+ SHIFT + C:编写申明或者补上函数.& 如:& procedure TT.A(AA: string); &//函数申明& 安下:CTRL+ SHIFT + C后,会写上& procedure TT.A(AA: string);& begin&
&&SHIFT+CTRL+E 显示 EXPLORER ,我觉的这个比较好
&&用crtl+d就可以做到代码排列,比这个要方便多了,当然里面还有其它的功能&这里添加&shift +f12 快速查找窗体并打开&f11 属性&f9运行&crtl+f9 编译
&&crtl + shift + n (n=1,2,3,4......)定义书签crtl + n (n=1,2,3,4......)跳到书签n&&
下面的快捷键大部分在Delphi 5.0的菜单中找不到,其中有一些还是非常有用的。Ctrl+PageUp & & &将光标移至本屏的第一行,屏幕不滚动。Ctrl+PageDown & &将光标移至本屏的最后一行,屏幕不滚动。Ctrl+↓ & & & & &向下滚动屏幕,光标跟随滚动不出本屏。Ctrl+↑ & & & & &向上滚动屏幕,光标跟随滚动不出本屏。Ctrl+Shift+NUM & 在光标行设置最多九个临时标志号,对临时切换非常有用。& & 行的左边将出现一本书,封面有NUM,再按一次取消设置。 &Ctrl+NUM & & & & 直接将光标跳到NUM处,NUM是用Ctrl+Shift+NUM设置的标号。& & NUM不能用小键盘。Ctrl+Home & & & &将光标移至文件头。Ctrl+End & & & & 将光标移至文件尾。Ctrl+B & & & & & Buffer List窗口。Ctrl+I & & & & & 同Tab键。Ctrl+M & & & & & 同Enter键。Ctrl+N & & & & & 同Enter键,但光标位置保持不变。Ctrl+T & & & & & 删除光标右边的一个单词。Ctrl+Y & & & & & 删除光标所在行。Ctrl+Shift+↑ & &光标在函数体内时,将光标快速移至当前函数声明处。Ctrl+Shift+↓ & &光标在函数声明行时,将光标快速移至函数定义处。Ctrl+Shift+C & & 声明一个过程或函数后,直接生成过程或函数的名称、begin、Ctrl+Shift+E & & 光标在Edit窗口和Explorer窗口间切换。Ctrl+Shift+G & & 插入GUID。Ctrl+Shift+J & & 弹出Delphi语句提示窗口,选择所需语句将自动完成一条语句。Ctrl+Shift+T & & 在光标行加入To-Do注释。Ctrl+Shift+Y & & 删除光标之后至本行末尾之间的文本。Ctrl+F3 & & & & &Call Stack窗口。Ctrl+F4 & & & & &等于File菜单中的Close项。Ctrl+鼠标转轮 & &加速滚屏。Shift+F8 & & & & 调试时弹出CPU窗口。Shift+F10 & & & &等于鼠标右键(Windows快捷键)。Alt+F4 & & & & & 关闭所有编辑框中打开的源程序文件,但不关闭项目。CTRL+C 复制 CTRL+V 粘贴 CTRL+X 剪切 CTRL+Z 还原(Undo) CTRL+S 保存CTRL+ENTER 定位到单元文件Shitf+箭头 选择 如果同时按住Alt +Shitf+箭头, 再进行选择, 则是一种区域选择, 而不是行选择, 粘贴的时候也就是插入粘贴了. F9 运行 CTRL+ F9编译F8 STEP OVER (步进式调试不进入子过程)F7 TRACE INTO (步进式调试同时追踪进入子过程)F11,F12 切换EDITOR,INSPECTOR,FORM DESIGNER. CTRL+ALT+F11 弹出工程管理器 CTRL+F弹出查找对话框CTRL+R弹出替换对话框CTRL+ Shitf+C 类过程代码补全(只要在定义部分定义一过程或一函数头则自动帮你生成实现部分的套架;反之也成)象这些都是菜单中有的快捷方式, 其它的您可以自己去找, 就不无聊了, 下面是一些不是很容易找到 (或者比较容易忘记的快捷操作) 但很有用的快捷操作: PB的SHITF+TAB好象很酷, 其实DELPHI也有. 另外就是在PB中, 如果你对选择的代码使用TAB键, 就是所有的选择向后跳格, 但是DELPHI中怎样跳格呢? 其实也是有办法的, 就是CTRL+K,I向后, CTRL+K,U向前. 如果你是在接口函数的实现部分, 那么 CTRL+SHIFT+上箭头 就可以到声明部分. 同样再CTRL+SHIFT+下箭头 又回到实现部分是不是觉得DELPHI好象没有标签功能, CTRL+SHIFT+数字 定义标签(当然因为数据键只有10个, 所以您也只能定义从0~9的10个标签), CTRL+数字 就是定位到相应的标签的位置. 有时候反复输入什么东西是不是很繁? CTRL+SHIFT+R录制键盘宏, 比如我经常做的就是: 下箭头-下箭头-HOME-回车-CTRL+V, 再键入一次CTRL+SHIFT+R录制完成, 之后您可以使用CTRL+SHIFT+P, 重复宏,还是省了一些事的. 另外在DELIPHI中有一个很有用的快键极其有用这就是CTRL+J;列如:在一过程中你输入ifb后再按CTRL+J你回去看看效果吧,可能你会大吃一惊。这就是Code Insight.另外还有一些快捷都是很少用到的, 我一时也想不起来, 您要是有兴趣就在帮助索引中输入 &Classic keystroke mapping&, 自己查看吧. &&
取消书签: 在书签N处,再按一次 SHIFT + CTRL + N
Ctrl+space 代码补全 &
[blue][b]在Inspector,[/b][/blue]可以用Ctrl+Tab切换Properties页和Events页Ctrl+Enter可进入相应的设置,如在Preperties页的Font按Ctrl+Enter在Events中按Ctrl+Enter可进入相应代码编辑 &
从Delphi爱好者网站载的一篇文章Delphi之快速设计(界面设计篇)西安 & & &梁 &明--------------------------------------------------------------------------------众所周知,Delphi已经是RAD之中的RAD了,但本人的目的是更加充分地挖掘出Delphi的优秀品质,哎,人的胃口呀......本人打算从两个方面来谈论这个话题:界面设计及程序设计.本文介绍界面的快速设计:如果你的手在键盘上,我想你不太会愿意再去伸手拿鼠标来移动组件吧,再说鼠标也不太精确(下面提到的均针对键盘操作,能用鼠标操作完成的不在此列),那好,以下快捷键及一些技巧请各位看官&收好&.一、以下快捷键指的是对窗体表格上组件的操作:●快捷键1:【Ctrl+UP】~向上移动当前组件(精确);【Ctrl+Left】~向左移动当前组件(精确);【Ctrl+Down】~向下移动当前组件(精确);【Ctrl+Right】~向右移动当前组件(精确);注:以上快接键中再加Shift进行组合(比如【Ctrl+Shift+Right】)即可实现粗略调整;●快捷键2:【Shift+UP】~减小当前组件的高度;【Shift+Left】~减小当前组件的宽度;【Shift+Down】~增加当前组件的高度;【Shift+Right】~增加当前组件的宽度;注:以上Up,Left等指的是方向键;二、以下快捷键指的是在对象观察器上的操作:●快捷键3:【F11】~切换到对象观察器(注:如果连续按F11则将实现在对象观察器、窗体表格、代码编辑器之间切换);【Ctrl+Down】~下拉当前窗体的组件列表;【Ctrl+Enter】~编辑带...的属性值(如组件的字体TFont);【Alt+Down】~下拉组件当前属性选单队列(如Align-&alNone,alLeft,alRight等);【Ctrl+Tab】~在属性列表及事件列表中切换;三、菜单快捷键:●快捷键4:【F12】,【Shift+F12】,【Ctrl+F12】等在Delphi的菜单中已有定义的在此不必罗嗦.技巧:如何选择被组件覆盖了的窗体(比如某组件的Align属性为alClient)?方法一、按ESC键,一层一层的往后选,直到窗体被选为当前组件为止;方法二、按Shift的同时单击鼠标左键,一步即可选定(推荐);方法三、按F11选定对象观察器,然后切换到属性列表,再用上面快捷键3中的【Ctrl+Down】.版主:梁明日期:E-mail: &
Ctrl + O + U & & 将选中的代码的大小写颠倒
1.SHIFT+鼠标左键 & 先选中任一控,按键后可选中窗体&2.Shift+F8 & & & & 调试时弹出CPU窗口。&3.Shift+F10 & & & &等于鼠标右键(Windows快捷键)。&4.Shitf+箭头 & & & 选择 &5.shift +F12 & & & 快速查找窗体并打开&6.F7 & & & & & & &(步进式调试同时追踪进入子过程)&7.F8 & & & & & & &(步进式调试不进入子过程)&8.F9 & & & & & & & 运行&9.F12 & & & & & & &切换EDITOR,FORM &10.Alt+F4 & & & & &关闭所有编辑框中打开的源程序文件,但不关闭项目。&11.ALT+鼠标左键 & &可以块选代码,删除对齐的重复代码非常有用。&12.Ctrl+F9 & & & & 编译&13.Ctrl+shift+N(n=1,2,3,4......) &定义书签&14.Ctrl+n(n=1,2,3,4......)跳到书签n&15.CTRL +SHIFT+N & &在书签N处,再按一次 取消书签:&16.Ctrl+PageUp & & &将光标移至本屏的第一行,屏幕不滚动。&17.Ctrl+PageDown & &将光标移至本屏的最后一行,屏幕不滚动。&18.Ctrl+↓ & & & & &向下滚动屏幕,光标跟随滚动不出本屏。&19.Ctrl+↑ & & & & &向上滚动屏幕,光标跟随滚动不出本屏。&20.Ctrl+Home & & & &将光标移至文件头。&21.Ctrl+End & & & & 将光标移至文件尾。&22.Ctrl+B & & & & & Buffer List窗口。&23.Ctrl+I & & & & & 同Tab键。&24.CTRL+J (弹出Delphi语句提示窗口,选择所需语句将自动完成一条语句。)代码模板 &25.Ctrl+M & & & & & 同Enter键。&26.Ctrl+N & & & & & 同Enter键,但光标位置保持不变。&27.Ctrl+T & & & & & 删除光标右边的一个单词。&28.Ctrl+Y & & & & & 删除光标所在行。&29.CTRL+C 复制 &30.CTRL+V 粘贴 &31.CTRL+X 剪切 &32.CTRL+Z 还原(Undo) &33.CTRL+S 保存&34.Ctrl+F 查找&35.Ctrl+L 继续查找&36.Ctrl+r &替换&37.CTRL+ENTER & & & 定位到单元文件&38.Ctrl+F3 & & & & &Call Stack窗口。&39.Ctrl+F4 & & & & &等于File菜单中的Close项。&40.Ctrl+Backspace & 后退删除一个词。好像是到 . 为止。&41.Ctrl+鼠标转轮 & &加速滚屏。&42.Ctrl+O+U & & & & 将选中的整块代码都转为小写或大写&41.Ctrl+Shift+G & & 插入GUID。&42.Ctrl+Shift+T & & 在光标行加入To-Do注释。&43.Ctrl+Shift+Y & & 删除光标之后至本行末尾之间的文本。&44.CTRL+SHIFT+C & & 编写申明或者补上函数.&45.CTRL+SHIFT+E & & 显示 EXPLORER ,我觉的这个比较好&46.CTRL+SHIFT+U & & 代码整块移动(左移)&47.CTRL+SHIFT+I & & 代码整块移动(右移)&48.CTRL+SHIFT+↑ & &在过程、函数、事件内部, 可跳跃到相应的过程、函数、事件的定义&49.CTRL+SHIFT+↓ & &在过程、函数、事件的定义处, 可跳跃到具体过程、函数、事件内部&50.Ctrl+Alt+c &注释块&51.Ctrl+Alt+u &取消注释块&52.Ctrl+Alt+h &生成头(更详细的设置在GExperts配置的Editor Experts属性页)& &
呵呵,完全正式版出笼啦。欢迎大家批评指正。Enjoy:-)& & & & & & & & & & & From doxpix& & & & & & & & & & & &___________________________________________________________________________________________DELPHI中的快捷方式一览(完全正式版)& &::::Created By RedBaby ::::& &::::Modified By doxpix ::::& &::::CopyRight DFW 2002::::&1.SHIFT+鼠标左键 & &先选中任一控件,按键后可选中窗体(选中控件后按Esc效果一样)&2.Shift+F8 & & & & &调试时弹出CPU窗口。&3.Shift+F10 & & & & 等于鼠标右键(Windows快捷键)。&4.Shitf+箭头 & & & &选择&5.shift +F12 & & & &快速查找窗体并打开&6.F7 & & & & & & & (步进式调试同时追踪进入子过程)&7.F8 & & & & & & & (步进式调试不进入子过程)&8.F9 & & & & & & & &运行&9.F12 & & & & & & & 切换EDITOR,FORM&10.Alt+F4 & & & & & 关闭所有编辑框中打开的源程序文件,但不关闭项目&11.ALT+鼠标左键 & & &可以块选代码,用来删除对齐的重复代码非常有用&12.Ctrl+F9 & & & & &编译&13.Ctrl+shift+N(n=1,2,3,4......) &定义书签&14.Ctrl+n(n=1,2,3,4......)跳到书签n&15.CTRL +SHIFT+N & &在书签N处,再按一次 取消书签&16.Ctrl+PageUp & & &将光标移至本屏的第一行,屏幕不滚动&17.Ctrl+PageDown & &将光标移至本屏的最后一行,屏幕不滚动&18.Ctrl+↓ & & & & &向下滚动屏幕,光标跟随滚动不出本屏&19.Ctrl+↑ & & & & &向上滚动屏幕,光标跟随滚动不出本屏&20.Ctrl+Home & & & &将光标移至文件头&21.Ctrl+End & & & & 将光标移至文件尾&22.Ctrl+B & & & & & Buffer List窗口&23.Ctrl+I & & & & & 同Tab键&24.CTRL+J & & & & & (弹出Delphi语句提示窗口,选择所需语句将自动完成一条语句)代码模板&25.Ctrl+M & & & & & 同Enter键。&26.Ctrl+N & & & & & 同Enter键,但光标位置保持不变&27.Ctrl+T & & & & & 删除光标右边的一个单词&28.Ctrl+Y & & & & & 删除光标所在行&29.CTRL+C & & & & & 复制&30.CTRL+V & & & & & 粘贴&31.CTRL+X & & & & & 剪切&32.CTRL+Z & & & & & 还原(Undo)&33.CTRL+S & & & & & 保存&34.Ctrl+F & & & & & 查找&35.Ctrl+L & & & & & 继续查找&36.Ctrl+r & & & & & 替换&37.CTRL+ENTER & & & 定位到单元文件&38.Ctrl+F3 & & & & &弹出Call Stack窗口&39.Ctrl+F4 & & & & &等于File菜单中的Close项&40.Ctrl+Backspace & 后退删除一个词,直到遇到一个分割符&41.Ctrl+鼠标转轮 & &加速滚屏&42.Ctrl+O+U & & & & 切换选择块的大小写(注意松开O后再按U,Ctrl保持按下)&43.Ctrl+K+O & & & & 切换选择块为小写(注意松开K后再按O,Ctrl保持按下)&44.Ctrl+K+N & & & & 切换选择块为大写(注意松开K后再按N,Ctrl保持按下)&45.Ctrl+Shift+G & & 插入GUID&46.Ctrl+Shift+T & & 在光标行加入To-Do注释&47.Ctrl+Shift+Y & & 删除光标之后至本行末尾之间的文本&48.CTRL+SHIFT+C & & 编写申明或者补上函数,绝好!!!&49.CTRL+SHIFT+E & & 显示EXPLORER&50.Ctrl+Tab & & & & 在Inspector中切换Properties页和Events页&51.CTRL+SHIFT+U & & 代码整块左移2个空格位置&52.CTRL+SHIFT+I & & 代码整块右移2个空格位置&53.CTRL+SHIFT+↑ & &在过程、函数、事件内部, 可跳跃到相应的过程、函数、事& & & & & & & & & & &件的定义(在interface和implementation之间来回切换)&54.CTRL+SHIFT+↓ & &在过程、函数、事件的定义处, 可跳跃到具体过程、函数、事件内部(同上)&55.Tab & & & & & & &在object inspector窗口按tab键将光标移动到属性名区,然后键入属性名的开头& & & & & & & & & & &字母可快速定位到该属性&56.Ctrl+Alt & & & & 按着Ctrl+Alt之后,可用鼠标选择一个矩形块中的代码,& & & & & & & & & & &并可比它进行复制,粘贴&57.Shift+↓、↑、→、← 以1像素单位更改所选控件大小&58.Ctrl+↓、↑、→、←以1像素单位更改所选控件位置&59.Ctrl+E & & & & & 快速选择(呵呵,试试吧,很好玩的) & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &---------GExperts中---------&60.Ctrl+Alt+c & & & 注释块&61.Ctrl+Alt+u & & & 取消注释块&62.Ctrl+Alt+h & & & 生成头(更详细的设置在GExperts配置的Editor Experts属性页)&63.Ctrl+Alt+o & & & 选择对应分隔符之间的语句&64.Ctrl+Alt+v & & & 在对应的分隔符之间来回跳转(与已有快捷键有冲突,请更改)---------GExperts中---------___________________________________________________________________________________________ &
还没结束啊!不用这么麻烦,DELPHI的HELP中把所有的快捷键都列出来了。而且各种配置的快捷键并不是完全一致的!在Help中查找keyboard shortcuts就可以了,列一部份如下:These editor keyboard shortcuts apply to the [red][b]Default[/b][/red] keystroke mapping scheme.Shortcut &Action or commandF1 &Help|Topic SearchCtrl+F1 &Help|Topic SearchF3 &Search|Search AgainCtrl+E &Search|Incremental SearchCtrl+F &Search|FindCtrl+I &Inserts a tab characterCtrl+j &Templates pop-up menuCtrl+N &Inserts a new lineCtrl+P &Causes next character to be interpreted as an ASCII sequenceCtrl+R &Search|ReplaceCtrl+S &File|SaveCtrl+T &Deletes a wordCtrl+Y &Deletes a lineCtrl+Z &Edit|UndoCtrl+&space bar& &Code Completion pop-up windowCtrl+Shift+g &Inserts a new Globally Unique Identifier (GUID)Ctrl+Shift+I &Indents blockCtrl+Shift+U &Outdents blockCtrl+Shift+Y &Deletes to the end of a lineCtrl+Shift+Z &Edit|RedoCtrl+Shift+&space bar& &Code Parameters pop-up windowAlt+[ &Finds the matching delimiter (forward)Alt+] &Finds the matching delimiter (backward)End &Moves to the end of a lineHome &Moves to the start of a lineEnter &Inserts a carriage returnIns &Turns insert mode on/offDel &Deletes the character to the right of the cursorBackspace &Deletes the character to the left of the cursorTab &Inserts a tabSpace &Inserts a blank spaceLeft Arrow &Moves the cursor left one column, accounting for the autoindent settingRight Arrow &Moves the cursor right one column, accounting for the autoindent settingUp Arrow &Moves up one lineDown Arrow &Moves down one linePage Up &Moves up one pagePage Down &Moves down one pageCtrl+Left Arrow &Moves one word leftCtrl+Right Arrow &Moves one word rightCtrl+Tab &Moves to the next code page (or file)Ctrl+Shift+Tab &Moves to the previous code page (or file)Ctrl+Backspace &Deletes the word to the right of the cursorCtrl+Home &Moves to the top of a fileCtrl+End &Moves to the end of a fileCtrl+Del &Deletes a currently selected blockCtrl+Space &Inserts a blank spaceCtrl+PgDn &Moves to the bottom of a screenCtrl+PgUp &Moves to the top of a screenCtrl+Up Arrow &Scrolls up one lineCtrl+Down Arrow &Scrolls down one lineCtrl+Enter &Opens file at cursorShift+Tab &Moves the cursor to the left one tab positionShift+Backspace &Deletes the character to the left of the cursorShift+Left Arrow &Selects the character to the left of the cursorShift+Right Arrow &Selects the character to the right of the cursorShift+Up Arrow &Moves the cursor up one line and selects from the left of the starting cursor positionShift+Down Arrow &Moves the cursor down one line and selects from the right of the starting cursor positionShift+PgUp &Moves the cursor up one screen and selects from the left of the starting cursor positionShift+PgDn &Moves the cursor down one line and selects from the right of the starting cursor positionShift+End &Selects from the cursor position to the end of the current lineShift+Home &Selects from the cursor position to the start of the current lineShift+Space &Inserts a blank spaceShift+Enter &Inserts a new line with a carriage returnCtrl+Shift+Left Arrow &Selects the word to the left of the cursorCtrl+Shift+Right Arrow &Selects the word to the right of the cursorCtrl+Shift+Home &Selects from the cursor position to the start of the current fileCtrl+Shift+End &Selects from the cursor position to the end of the current fileCtrl+Shift+PgDn &Selects from the cursor position to the bottom of the screenCtrl+Shift+PgUp &Selects from the cursor position to the top of the screenCtrl+Shift+Tab &Moves to the previous pageShift+Alt+arrow &Selects column-oriented blocksClick+Alt+mousemove &Selects column-oriented blocksCtrl+O+C &Turns on column blockingCtrl+O+K &Turns off column blockingAlt+Backspace &Edit|UndoAlt+Shift+Backspace &Edit|RedoAlt+Shift+Left Arrow &Selects the column to the left of the cursorAlt+Shift+Right Arrow &Selects the column to the right of the cursorAlt+Shift+Up Arrow &Moves the cursor up one line and selects the column from the left of the starting cursor positionAlt+Shift+Down Arrow &Moves the cursor down one line and selects the column from the left of the starting cursor positionAlt+Shift+Page Up &Moves the cursor up one screen and selects the column from the left of the starting cursor positionAlt+Shift+Page Down &Moves the cursor down one line and selects the column from the right of the starting cursor positionAlt+Shift+End &Selects the column from the cursor position to the end of the current lineAlt+Shift+Home &Selects the column from the cursor position to the start of the current lineCtrl+Alt+Shift+Left Arrow &Selects the column to the left of the cursorCtrl+Alt+Shift+Right Arrow &Selects the column to the right of the cursorCtrl+Alt+Shift+Home &Selects the column from the cursor position to the start of the current fileCtrl+Alt+Shift+End &Selects the column from the cursor position to the end of the current fileCtrl+Alt+Shift+Page Up &Selects the column from the cursor position to the bottom of the screenCtrl+Alt+Shift+Page Down &Selects the column from the cursor position to the top of the screen &
找一下帮助,查找shortcuts,什么都有了。Ctrl+Ins &Edit|CopyShift+Del &Edit|CutShift+Ins &Edit|PasteCtrl+C &Edit|CopyCtrl+V &Edit|PasteCtrl+X &Edit|CutBreakpoint viewCtrl+V &View SourceCtrl+S &Edit SourceCtrl+E &Edit BreakpointEnter &Edit BreakpointCtrl+D &Delete BreakpointDel &Delete BreakpointCtrl+A &Add BreakpointIns &Add BreakpointCtrl+N &Enable BreakpointCall stack viewCtrl+V &View SourceCtrl+E &Edit Source (Delphi only)Space &View Source (Epsilon only)Ctrl+Enter &Edit Source (Epsilon only)Message viewCtrl+V &View SourceSpace &View SourceCtrl+S &Edit SourceCtrl+Enter &Edit SourceWatch viewCtrl+E &Edit WatchEnter &Edit WatchCtrl+A &Add WatchIns &Add WatchCtrl+D &Delete WatchDel &Delete WatchShortcut &Action or commandF5 &Search|Find (forward from cursor position)F6 &Search|Replace (forward from cursor position)Alt+F5 &Search|Find (backward from cursor position)Alt+F6 &Search|Replace (backward from cursor position)Alt+F9 &Displays the local menuShift+F4 &Tiles windows horizontallyShift+F5 &Search|Search AgainShift+F6 &Repeats the last Search|Replace operationEsc &Cancels a command at the prompt Del &Deletes a character or block at the cursorAsterisk (*)/keypad &Edit|UndoBackspace &Deletes the character to the left of the cursorShift+Backspace &Deletes the character to the left of the cursorTab &Inserts a tab characterEnter &Inserts a new line with a carriage returnCtrl+B &Moves to the bottom of the windowCtrl+C &Centers line in windowCtrl+D &Moves down one screenCtrl+E &Moves up one screenCtrl+K &Deletes to the beginning of a lineCtrl+M &Inserts a new line with a carriage returnCtrl+S &Performs an incremental searchCtrl+T &Moves to the top of the windowCtrl+U &Edit|RedoCtrl+Backspace &Deletes the word to the left of the cursorCtrl+Enter &Inserts an empty new lineCtrl+- (dash) &Closes the current pageAlt+A &Marks a non-inclusive blockAlt+B &Displays a list of open filesAlt+C &Mark the beginning of a column blockAlt+D &Deletes a lineAlt+G &Search|Go to line numberAlt+I &Toggles insert modeAlt+K &Deletes of the end of a lineAlt+L &Marks a lineAlt+M &Marks an inclusive blockAlt+N &Displays the contents of the next pageAlt+P &Prints the selected blockAlt+Q &Causes next character to be interpreted as an ASCII sequenceAlt+R &Reads a block from a fileAlt+S &Search|FindAlt+T &Search|ReplaceAlt+U &Edit|UndoAlt+Backspace &Deletes the word to the right of the cursorAlt+Hyphen &Jumps to the previous pageAlt+Page Down &Goes to the next tabAlt+Page Up &Goes to the previous tabCtrl+Q+[ &Finds the matching delimiter (forward)Ctrl+Q+Ctrl+[ &Finds the matching delimiter (forward)Ctrl+Q+] &Finds the matching delimiter (backward)Ctrl+Q+Ctrl+] &Finds the matching delimiter (backward)Ctrl+O+A &Open file at cursorCtrl+O+B &Browse symbol at cursorCtrl+O+O &Toggles the case of a selectionCtrl+F1 &Help keyword searchCtrl+F5 &Toggles case-sensitive searchingCtrl+F6 &Toggles regular expression searchingCtrl+F9 &只编译F9 & & & 先编译后运行程序F5 & & & 设置断点F8 & & & 断点调试Ctrl+z & 撤消Ctrl + 空格(Space) &系统默认提示 & &注:可能与系统Ctrl+space文字切换冲突,你可以到输入法中将之禁掉Ctrl + Shift + Space & 也是系统提示 如:Copy() ,将光标移动到()里,按三键就会出现提示Ctrl + Shift + C & & &将自己定义的函数或过程定义语句显示在下面Ctrl + S & & & & & & &保存文件Ctrl + F & & & & & & &查询某词Ctrl + Y & & & & & & &删除某行F12 & & & & & & & & & 窗体与表单切换Ctrl + Shift + (箭头:向上或向下) &移动此行定义的过程或函数的定义或声明位置累,不想说了!!
发布于 1年前,
阅读(1618) | 评论(0) |
投票(0) | 收藏(1)
原文见“/sonicit/archive//1129586.html”
说明:看了上面那位兄台的解法后,还是有些不明所以,不明白他说的最后一句话——”那么解决方法很简单,创建一个带窗口的Frame基类,再从这个基类继承即可“究竟是什么,纠结了很久,
后来在 majingli 的帮助下,才明白,在Delphi 7 下的 TFrame 的继承不像我们在 MFC 中的操作一样直接改代码就可以了,而是要通过 IDE 来进行操作。
具体问题描述
&&&&& 由于需求总在变化,加上不断的会进行重构,所以我们有可能在 一个 TFrame3=class(TFrame)已经写到比较完善时,突然想把其基类从 TFrame 转成 TFrame2;按我们的在 MFC 中的习惯做法,我们会先创建一个 TFrame2,然后手动编辑 TFrame3 的 pas 文件,使其变为& TFrame3=class(TFrame2);然后运行程序,OK,一切正常。
&&&&& 可是当我们关闭工程,再打开时,会弹对话框,显示 “ TabOrder does not exit“,此时,无论我们选择什么,再次运行时都会弹出”Property OldCreateOrder does not exist错误。
解决的办法
删除 TFrame3, 再重新由 IDE 生成 TFrame3,在创建时选择由 ”Frame2“ 派生, 然后再把原 TFrame3 的 pas 文件复制过来即可.可以看到,两者的 pas 文件是完全一模一样的, 光从代码根本看不出任何问题. 这应该算是 delphi7 的bug了。
&&&& 有的时候,我们已经创建了太多的 TFrame3, 这样一个一个重新派生,再改其 pas 文件,实在是一项非常浩大的工程,这会对重构造成极大的负担,那么有没有更好的办法呢?
&&&& 因为 pas 文件是完全一致的,所以我们只能把目标放在 dfm 文件上,打开 TFrame3 的 dfm 文件,其第一行写的是 “object Frame3: TFrame3”;再打开一个由IDE创建的,派生自 TFrame2 的 TFrame4 的 dfm 文件,其第一行写的是“inherited Frame4: TFrame4”,那么这是不是就是问题所以呢?我们试着把“object Frame3: TFrame3”,改成“inherited Frame3: TFrame3”, 再次运行,一切 OK。
发布于 1年前,
阅读(26) | 评论(0) |
投票(0) | 收藏(1)
引入文件&DLL比较复杂时,可以为它的声明专门创建一个引入单元,这会使该DLL变得更加容易维护和查看。引入单元的格式如下:  unit MyDllI {Import unit for MyDll.dll }  interface  procedure MyDllP…implementation   procedure MyDllPexternal 'MyDll' index 1;…end.这样以后想要使用MyDll中的例程时,只要简单的在程序模块中的uses子句中加上MyDllImport即可。其实这仅仅是种方便开发的技巧,大家打开Windows等引入windows API的单元,可以看到类似的做法。&动态(显式)调用DLL&前面讲述静态调用DLL时提到,DLL会在启动调用程序时即被调入。所以这样的做法只能起到公用DLL以及减小运行文件大小的作用,而且DLL装载出错会立刻导致整个启动过程终止,哪怕该DLL在运行中只起到微不足道的作用。使用动态调用DLL的方式,仅在调用外部例程时才将DLL装载内存(引用记数为0时自动将该DLL从内存中清除),从而节约了内存空间。而且可以判断装载是否正确以避免调用程序崩溃的情况,最多损失该例程功能而已。动态调用虽然有上述优点,但是对于频繁使用的例程,因DLL的调入和释放会有额外的性能损耗,所以这样的例程则适合使用静态引入。调用范例&DLL动态调用的原理是首先声明一个函数/过程类型并创建一个指针变量。为了保证该指针与外部例程指针一致以确保赋值正确,函数/过程的声明必须和外部例程的原始声明兼容(兼容的意思是1、参数名称可以不一样;2、参数/返回值类型至少保持可以相互赋值,比如原始类型声明为Word,新的声明可以为Integer,假如传递的实参总是在Word的范围内,就不会出错)。接下来通过windows API函数LoadLibrary引入指定的库文件,LoadLibrary的参数是DLL文件名,返回一个THandle。如果该步骤成功,再通过另一个API函数GetProcAddress获得例程的入口地址,参数分别为LoadLibrary的指针和例程名,最终返回例程的入口指针。将该指针赋值给我们预先定义好的函数/过程指针,然后就可以使用这个函数/过程了。记住最后还要使用API函数FreeLibrary来减少DLL引用记数,以保证DLL使用结束后可以清除出内存。这三个API函数的Delphi声明如下:Function LoadLibrary(LibFileName:PChar):THFunction GetProcAddress(Module:THProcName:PChar):TfarPProcedure FreeLibrary(LibModule:THandle);将前面静态调用DLL例程的代码更改为动态调用,如下所示:typeTDllProc = function (PathName : Pchar):varLibHandle: THDelPath : TDllPbeginLibHandle := LoadLibrary(PChar('FileOperate.dll'));if LibHandle &= 32 then begintryDelPath := GetProcAddress(LibHandle,PChar('DeleteDir'));if DirectoryExists(ShellTreeView.Path) thenif Application.MessageBox(Pchar('确定删除目录'+QuotedStr(ShellTreeView.Path)+'吗?'), 'Information',MB_YESNO) = IDYes thenif DelPath(PChar(ShellTreeView.Path)) thenshowmessage('删除成功');finallyFreeLibrary(LibHandle);16位DLL的动态调入下面将演示一个16位DLL例程调用的例子,该例程是windows9x中的一个隐藏API函数。代码混合了静态、动态调用两种方式,除了进一步熟悉外,还可以看到调用16位DLL的解决方法。先解释一下问题所在:我要实现的功能是获得win9x的“系统资源”。在winNT/2000下是没有“系统资源”这个概念的,因为winNT/2000中堆栈和句柄不再象win9X那样被限制在64K大小。为了取该值,可以使用win9x的user dll中一个隐藏的API函数GetFreeSystemResources。&该DLL例程必须动态引入。如果静态声明的话,在win2000里执行就会立即出错。这个兼容性不解决是不行的。所以必须先判断系统版本,如果是win9x再动态加载。检查操作系统版本的代码是:&var&OSversion : _OSVERSIONINFOA;&FWinVerIs9x: B&begin&OSversion.dwOSVersionInfoSize := sizeof(_OSVERSIONINFOA);GetVersionEx(OSversion);FWinVerIs9x := OSversion.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;&E&以上直接调用API函数,已在Windows单元中被声明。&function LoadLibrary16(LibraryName: PChar): TH external kernel32 index 35;procedure FreeLibrary16(HInstance: THandle); external kernel32 index 36;function GetProcAddress16(Hinstance: TH ProcName: PChar): P external kernel32 index 37;function TWinResMonitor.GetFreeSystemResources(SysResource: Word): WtypeTGetFreeSysRes = function (value : integer):TQtThunk = procedure();varProcHandle : THGetFreeSysRes : TGetFreeSysRProcThunkH : THQtThunk : TQtTThunkTrash: array[0..$20] of WbeginResult := 0;ThunkTrash[0] := ProcHif FWinVerIs9x then beginProcHandle := LoadLibrary16('user.exe');if ProcHandle &= 32 then beginGetFreeSysRes := GetProcAddress16(ProcHandle,Pchar('GetFreeSystemResources'));if assigned(GetFreeSysRes) then beginProcThunkH := LoadLibrary(Pchar('kernel32.dll'));if ProcThunkH &= 32 then beginQtThunk := GetProcAddress(ProcThunkH,Pchar('QT_Thunk'));if assigned(QtThunk) thenasmpush SysResource //push argumentsmov edx, GetFreeSysRes //load 16-bit procedure pointercall QtThunk //call thunkmov Result, ax //save the resultFreeLibrary(ProcThunkH);FreeLibrary16(ProcHandle);endelse Result := 100;首先,LoadLibrary16等三个API是静态声明的(也可以动态声明,我这么做是为了减少代码)。由于LoadLibrary无法正常调入16位的例程(微软啊!),所以改用 LoadLibrary16、FreeLibrary16、GetProcAddress16,它们与LoadLibrary、FreeLibrary、GetProcAddress的意义、用法、参数都一致,唯一不同的是必须用它们才能正确加载16位的例程。&在定义部分声明了函数指针TGetFreeSysRes 和TQtThunk。Stdcall、cdecl参数定义堆栈的行为,必须根据原函数定义,不能更改。&假如类似一般的例程调用方式,跟踪到这一步:if assigned(GetFreeSysRes) then begin GetFreeSysRes已经正确加载并且有了函数地址,却无法正常使用GetFreeSysRes(int)!!!&所以这里动态加载(理由也是在win2k下无法执行)了一个看似多余的过程QT_Thunk。对于一个32位的外部例程,是不需要QT_Thunk的, 但是,对于一个16位的例程,就必须使用如上汇编代码(不清楚的朋友请参考Delphi语法资料)&asm&push SysResource&mov edx, GetFreeSysRes&call QtThunk&mov Result, ax&它的作用是将压入参数压入堆栈,找到GetFreeSysRes的地址,用QtThunk来转换16位地址到32位,最后才能正确的执行并返回值!&以上16位DLL的部分在小仓系列中曾经提到过Delphi开发DLL常见问题&字符串参数&前面曾提到过,为了保证DLL参数/返回值传递的正确性,尤其是为C++等其他语言开发的宿主程序使用时,应尽量使用指针或基本类型,因为其他语言与Delphi的变量存储分配方法可能是不一样的。C++中字符才是基本类型,串则是字符型的线形链表。所以最好将string强制转换为Pchar。如果DLL和宿主程序都用Delphi开发,且使用string(还有动态数组,它们的数据结构类似)作为导出例程的参数/返回值,那么添加ShareMem为工程文件uses语句的第一个引用单元。ShareMem是Borland共享的内存管理器Borlndmm.dll的接口单元。引用该单元的DLL的发布需要包括Borlndmm.dll,否则就得避免使用string。&初始化COM库&如果在DLL中使用了TADOConnection之类的COM组件,或者ActiveX控件,调用时会提示 “标记没有引用存储”等错误,这是因为没有初始化COM。DLL中不会调用CoInitilizeEx,初始化COM库被认为是应用程序的责任,这是Borland的实现策略。你需要做的是1、引用Activex单元,保证CoInitilizeEx函数被正确调用了2、在单元级加入初始化和退出代码:initializationCoinitialize(nil);finalizationCoUend.3、 在结束时记住将连接和数据集关闭,否则也会报地址错误。在DLL中建立及显示窗体&凡是基于窗体的Delphi应用程序都自动包含了一个全局对象Application,这点大家是很熟悉的。值得注意的是Delphi创建的DLL同样有一个独立的Application。所以若是在DLL中创建的窗体要成为应用程序的模式窗体的话,就必须将该Application替换为应用程序的,否则结果难以预料(该窗体创建后,对它的操作比如最小化将不会隶属于任何主窗体)。在DLL中要避免使用ShowMessage而用MessageBox。创建DLL中的模式窗体比较简单,把Application.Handle属性作为参数传递给DLL例程,将该句柄赋与Dll的Application.Handle,然后再用Application创建窗体就可以了。无模式窗体则要复杂一些,除了创建显示窗体例程,还必须有一个对应的释放窗体例程。对于无模式窗体需要十分小心,创建和释放例程的调用都需在调用程序中得到控制。这有两层意思:一要防止同一个窗体实例的多次创建;二由应用程序创建一个无模式窗体必须保证由应用程序释放,否则假如DLL中有另一处代码先行释放,再调用释放例程将会失败。下面是DLL窗体的代码:unit uSampleFinterfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, ExtCtrls, StdCtypeTSampleForm = class(TForm)Panel: TPprocedure CreateAndShowModalForm(AppHandle : THCaption : PChar);function CreateAndShowForm(AppHandle : THandle):LongIprocedure CloseShowForm(AFormRef : LongInt);implementation{$R *.dfm}//模式窗体procedure CreateAndShowModalForm(AppHandle : THCaption : PChar);varForm : TSampleFstr :beginApplication.Handle := AppHForm := TSampleForm.Create(Application);trystr := CForm.Caption :=Form.ShowMfinallyForm.F//非模式窗体function CreateAndShowForm(AppHandle : THandle):LongIvarForm : TSampleFbeginApplication.Handle := AppHForm := TSampleForm.Create(Application);Result := LongInt(Form);Form.Sprocedure CloseShowForm(AFormRef : LongInt);beginif AFormRef & 0 thenTSampleForm(AFormRef).Rend.DLL工程单元的引出声明:exportsCloseShowForm,CreateAndShowForm,CreateAndShowModalF应用程序调用声明:procedure CreateAndShowModalForm(Handle : THCaption : PChar);external 'FileOperate.dll';function CreateAndShowForm(AppHandle : THandle):LongIexternal 'FileOperate.dll';procedure CloseShowForm(AFormRef : LongInt);external 'FileOperate.dll';除了普通窗体外,怎么在DLL中创建TMDIChildForm呢?其实与创建普通窗体类似,不过这次需要传递调用程序的Application.MainForm作为参数:function ShowForm(mainForm:TForm):stdcallvarForm1: TForm1;ptr:PLongIbeginptr:=@(Application.MainForm);//先把DLL的MainForm句柄保存起来,也无须释放,只不过是替换一下ptr^:=LongInt(mainForm);//用调用程序的mainForm替换DLL的MainFormForm1:=TForm1.Create(mainForm);//用参数建立代码中用了一个临时指针的原因在Application.MainForm是只读属性。MDI窗体的FormStyle不用设为fmMDIChild。引出DLL中的对象从DLL窗体的例子中可以发现,将句柄做为参数传递给DLL,DLL能指向这个句柄的实例。同样的道理,从DLL中引出对象,基本思路是通过函数返回DLL中对象的指针,将该指针赋值到宿主程序的变量,使该变量指向内存中某对象的地址。对该变量的操作即对DLL中的对象的操作。本文不再详解代码,仅说明需要注意的几点规则:1、 应用程序只能访问对象中的虚拟方法,所以要引用的对象方法必须声明为虚方法;2、 DLL和应用程序中都需要相同的对象及方法定义,且方法定义顺序必须一致;3、 DLL中的对象无法继承;4、 对象实例只能在DLL中创建。声明虚方法的目的不是为了重载,而是为了将该方法加入虚拟方法表中。对象的方法与普通例程是不同的,这样做才能让应用程序得到方法的指针。DLL毕竟是结构化编程时代的产物,基于函数级的代码共享,实现对象化已经力不从心。现在类似DLL功能,但对对象提供强大支持的新方式已经得到普遍应用,象接口(COM/DCOM/COM+)之类的技术。进程内的服务端程序从外表看就是一个dll文件,但它不通过外部例程引出应用,而是通过注册发布一系列接口来提供支持。它与DLL从使用上有两个较大区别:需要注册,通过创建接口对象调用服务。可以看出,DLL虽然通过一些技巧也可以引出对象,但是使用不便,而且常常将对象化强制转为过程化的方式,这种情况下最好考虑新的实现方法。
发布于 2年前,
阅读(2931) | 评论(0) |
投票(0) | 收藏(0)
1.Round(四舍六入五留双)
功能说明:对一个实数进行四舍五入。(按照银行家算法)
例:var&&& i, j: Ibegin&&& i := Round(1.5); // i等于2&&& j := Round(2.5); // j等于2
在Delphi中使用Round函数得到的答案有时与我们所预期的会不太一样:采用的是四舍六入五留双。即当舍或入位大于或小于五时按四舍五入来处理
,而当舍或入位等于五时,就要看前面一位是什么,根据奇进偶不进,它总是返回一个偶数值。例:&&&&&&&&&&&&i:= Round(11.5)//i等于12i:= Round(10.5)//i等于10
这种Round其实是按照银行家算法,统计学上一般都用这种算法,比传统的&四舍五入&要科学。如果要使用传统的&四舍五入&方法,可以使用下面函数:function RoundClassic(R: Real)
2.trunc(取得X的整数部分)如:trunc(-123.55)=-123, floor(123.55)=123
3.ceil(取得大于等于X的最小的整数)
如:ceil(-123.55)=-123, ceil(123.15)=124
4.floor(取得小于等于X的最大的整数)
如:floor(-123.55)=-124,floor(123.55)=123
5.RoundTo(取得需要的小数个数)
直接使用RoundTo函数,需要uses中加入math。RoundTo(1.245,&-2);&&=&1.25需要注意的是,旧的Delphi版本Round函数采用的是四舍六入,逢五的时候是前面是奇数才入,是偶数则不入,delphi手册帮助中的示例如下:RoundTo()&1234000RoundTo(1.234,&-2)&1.23RoundTo(1.235,&-2)&1.24RoundTo(1.245,&-2)&1.24但delphi&7已经不是这样的了,是直接四舍五入的:RoundTo(1.245,&-2)&=&1.25
注:floor和ceil是math unit里的函数,使用前要先Uses Math
&procedure&TForm1.btn1Click(Sender:&TObject);
&&sedt1&:=&edt1.T
&&edt2.Text&:=&FloatToStr(RoundFloat(StrToFloat(sedt1),&2));
procedure&TForm1.btn2Click(Sender:&TObject);
&&sedt1&:=&edt1.T
&&edt2.Text&:=&FloatToStr(RoundFloatZero(StrToFloat(sedt1),&2));
procedure&TForm1.btn3Click(Sender:&TObject);
&&sedt1&:=&edt1.T
&&edt2.Text&:=&FloatToStr(Round(StrToFloat(sedt1)));
procedure&TForm1.btn4Click(Sender:&TObject);
&&sedt1&:=&edt1.T
&&edt2.Text&:=&FloatToStr(trunc(StrToFloat(sedt1)));
procedure&TForm1.btn5Click(Sender:&TObject);
&&sedt1&:=&edt1.T
&&edt2.Text&:=&FloatToStr(ceil(StrToFloat(sedt1)));
procedure&TForm1.btn6Click(Sender:&TObject);
&&sedt1&:=&edt1.T
&&edt2.Text&:=&FloatToStr(floor(StrToFloat(sedt1)));
procedure&TForm1.btn7Click(Sender:&TObject);
&&sedt1&:=&edt1.T
&&edt2.Text&:=&FloatToStr(RoundTo(StrToFloat(sedt1),&-2));
{&TForm1&}
function&TForm1.RoundFloat(AFloat:&D&ADigits:&Integer):&D
&&sFormat:&
&&eAvoidError:&
&&sFormat&:=&'#.'&+&StringOfChar('0',&ADigits);
&&eAvoidError&:=&StrToFloat(FloatToStr(AFloat));
&&Result&:=&StrToFloat(FormatFloat(sFormat,&eAvoidError));
function&TForm1.RoundFloatZero(AFloat:&D&ADigits:&Integer):&D
&&sFormat:&
&&eAvoidError:&
&&sFormat&:=&'0.'&+&StringOfChar('0',&ADigits);
&&eAvoidError&:=&StrToFloat(FloatToStr(AFloat));
&&Result&:=&StrToFloat(FormatFloat(sFormat,&eAvoidError));
发布于 2年前,
阅读(461) | 评论(0) |
投票(0) | 收藏(0)

我要回帖

更多关于 i m a loser 的文章

 

随机推荐