关于作者

用户名:itecwwj
笔名:itecwwj
地区:
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

在线留言



访问统计:
文章个数:8
评论个数:12
留言条数:2




Powered by BlogDriver 2.1

itecwwj的博客

 

文章

比较IBM MQSeries和BEA WebLogic JMS Server(转载)
摘要:比较IBM MQSeries和BEA WebLogic JMS Server 查看全文

- 作者: itecwwj 2005年11月29日, 星期二 14:23  回复(0) |  引用(1) 加入博采

MyEclipse+Weblogic开发EJB(一)
 

MyEclipse+Weblogic开发EJB

 

编写人:邬文俊

编写时间2005-11-14

联系邮件:wenjunwu430@gmail.com

前言

学习ejb也有段日子了,一直没有找到好的资料指导如何在myeclipse下面开发ejb,令我十分苦恼。经过查阅资料和阅读myeclipse自带帮助,总结出该文档,希望该文档能够让大家迅速上手使用MyEclipse开发EJB组件,做为我们组的培训资料。如果中间有不足或错误请补充纠正,谢谢。

1         安装myeclipse,weblogic

1.        下载安装eclipse 3.0版本,具体版本根据所下载的myeclipse版本要求(www.myeclipsesite.com

2.        下载myeclipse3.8安装文件,运行安装,需要设置eclipse的安装目录。或者下载解压包,将文件夹解压到eclipse安装文件夹plugins目录,安装方法同普通插件安装相同。

3.        安装Weblogic 8.1.运行安装程序即可。具体配置本文不再描述,认为读者已经配置好weblogicdomain

2         配置weblogic

配置服务器以后可以通过myeclipse启动停止weblogic

注:以下资料转自http://dev2dev.bea.com.cn/bbs,作者:newwei

1)        选择菜单Window->Preferences->MyEclipse->Application Servers->Weblogic 8,配置项目如下:

1.        BEA home directory: 选择Bea的安装目录

2.        Weblogic installation directory:现在BEA下面的weblogic81目录

3.        Admin username:输入上面在配置过程中设的用户名

4.        Admin password:输入刚才设的密码

5.        Execution domain root:选择BEAuser_projects\domains目录下上面第一步创建的目录

6.        Execution domain name:输入上面那个目录的名称

7.        Execution server name:输入上一步的那个Congfiguration Name

8.        Hostname:PortNumber:输入IP地址和监听的端口

9.        Security policy file:输入BEA安装目录下的\weblogic81\server\lib\weblogic.policy

2)        Weblogic 8下面配置JDK,在WLS JDK name那里选择新建,弹出的对话框中选择BEA下面的JDK安装路径,输入一个名字确定就可以;在Optional Java VM arguments对话框里面输入-ms64m -mx64m -Djava.library.path="D:/BEA/weblogic81/server/bin" -Dweblogic.management.discover=false -Dweblogic.ProductionModeEnabled=false

3)        Weblogic 8下面配置Paths,加入BEA安装路径下/weblogic81/server/lib中的webservices.jarweblogic.jar两个包。如果需要其他的包,也在这里加入。

 

3         创建第一个EJB工程

1.        File > New > Project.

2.        选择J2EE目录下 EJB Projec

3.        选择 Next >.

  1. 输入工程名称,这里是firsejb

  2. 如果要使用XDoclet工具,选择J2EE 1.3。(建议使用,XDoclet是自动生成代码和部署描述文件的工具)

选择Finish目录结构入图。

4         创建第一个stateless sessionbean

1.        主界面选择菜单File > New > Other打开新建向导。

2.        展开J2EE > EJB 文件夹,选择Session EJB

3.        选择Next>,界面如下。这里要注意,package建议用.ejb后缀,因为XDoclet工具默认ejb bean所在的文件夹以.ejb后缀,接口文件的文件夹以.interface为后缀,为了避免设置上的麻烦,建议按默认情况取名。当然你也可以通过设置XDoclet属性改变,详情请查看帮助文档。

4.        选择Finish

5.     XDoclet自动生成接口文件、部署描述文件

XDoclet可以加速EJB的开发,自动完成一些文件生成工作,这方面和JBuilder是类似的。

我们需要XDoclet生成的文件如下:

接口文件远程接口、本地接口、Home接口、本地Home接口(文件作用参考《精通EJB》)

部署文件ejb-jar.xml(标准ejb部署描述文件)、weblogic-ejb-jar.xml文件(weblogic部署ejb描述文件,不同服务器该文件不同,要特别注意,该文件是必需的,通常由工具自动生成)

5.1.  为工程配置XDoclet

1.         打开工程的properties窗口。选择菜单Properties > MyEclipse-XDoclet

2.        Add Standard

3.        选择Standard EJB

 

4.        去掉没有用的标签,保留需要的如下图(见myeclipse帮助myeclipse application developer guide->ejb development->figure 11)。

5.        build选项卡中选择 Use dynamic build specification

 

以上配置就可以生成一个标准stateless bean的所有接口和配置文件,但是要部署该bean,还缺一个服务器部署描述文件weblogic-ejb-jar.xml

 

5.2.    为服务器配置XDoclet

该配置是为了自动生成weblogic-ejb-jar.xml文件。

  1. 右击ejbdoclet 选择 Add

  2. 我这里用的是weblogic8.1,所以选择weblogic。设置属性destDir = src/META-INF

5.3.  运行XDoclet生成文件

在工程上右键MyEclipse->Run XDoclet

生成前后工程目录应该类似为:

Jboss.xml应该为weblogic-ejb-jar.xml

 

查看weblogic-ejb-jar.xml文件,可以知道Home接口的JNDI名称。

5.4.  部署EJB

1.        MyEclipse >Add and Remove Project Deployments

2.        点击add,添加部署服务器weblogic

- 作者: itecwwj 2005年11月22日, 星期二 15:33  回复(0) |  引用(1) 加入博采

学java大半年了

马上就要毕业了,还没有成为大牛,唉~

看着师兄找工作,心里也不安起来

老婆找工作越来越顺利了,祝福一个:)

明年我也要变大牛,起码是小羊吧。

- 作者: itecwwj 2005年11月22日, 星期二 15:23  回复(0) |  引用(1) 加入博采

delphi 缓冲画图(内存画图)解决画图闪烁问题
delphi 缓冲画图(内存画图)解决画图闪烁问题

很多朋友在做绘图程序的时候,往往出现屏幕不停刷新产生闪烁的问题,这里就告诉大家一个解决办法,缓冲绘图。如果有人是用取反画图解决这个问题,那么在画直线的时候容易出现斑点,效果不是很好。如果是图片很大,那么缓冲画图是解决的好办法。

在网上搜索一下内存绘图,或者缓冲绘图,会有很多技术文章,不过都是以vc或者java为主,很少有pascal的代码例子。不过原理都是一样的,大家可以参考他们的文章。我会在最后放上转载的vc缓冲画图的文章。:)感谢原作者。

Delphi中函数调用比较方便。

OldBmp, BufBmp是TbitMap

//画图方法:

procedure TChart.Draw(aCanvas: TCanvas);

begin

{把要画的操作放在这里}

end;

在你要画的地方用如下代码把内存中画好的内容放到你要显示的组件的canvas上,这里就是canvas:

Draw (BufBmp.Canvas);//Draw方法就是上面那段代码

bitblt(self.Canvas.Handle, 0, 0, ClientWidth, ClientHeight,

self.BufBmp.Canvas.Handle, 0, 0, SRCCOPY);//拷贝函数

 

 

 


如果要用多个缓冲,用BufBmp.Assign(OldBmp);做内存中图片内容复制,然后在bufbmp中做进一步操作再贴到显示区。

简单吧:)。

怎样在内存缓冲中画图  作者 相生昌

document.title="怎样在内存缓冲中画图 "&document.title 关键字 内存缓冲,画图
原作者姓名 相生昌

介绍
用双缓冲进行绘图可解决在VC中绘图时的闪烁现象

正文
用vc 做程序,如何画图是一个大家都很关心,但是却感到很难以理解的问题,因为在mfc的封装之下,没有现成的画图函数供你直接调用,像vb等等里面直接来个 point之类的,常常让人感到无从下手。这两天帮人解决了一个用内存缓冲画图的问题,顺便也就谈谈这些东西,也算是总结。

我先来解释一下在mfc里面很关键的设备环境描述符,也就是所谓的DC(device context)。

还是从历史来看吧,dos时代,我们如果要绘图,必须通过一系列系统函数来启动图形环境(用过turbo pascal或者turbo c的人该还有印象吧),这之间对各种硬件的初始化参数都不相同,非常的烦人,常常还要查阅硬件手册,那时的程序智能针对最流行的硬件来编写,对不流行的就没有办法了。windows操作系统为了屏蔽不同的硬件环境,让编程时候不考虑具体的硬件差别,采取了一系列办法,设备环境描述符就是这样产生的。简单的说,设备描述符抽象了不同的硬件环境为标准环境,用户编写时使用的是这个虚拟的标准环境,而不是真实的硬件,与真实硬件打交道的工作一般交给了系统和驱动程序完成(这同样解释了为什么我们需要经常更新驱动程序的问题)。使用在windows图形系统(gdi,而不包括direct x)上面,就体现在一系列的图形DC上面,我们如果要在gdi上面绘图,就必须先得到图形DC的句柄(handle),然后指定句柄的基础上进行图形操作。

再来回忆一下,我们怎么在sdk的环境下面绘图呢,我想这个大家都不太清楚吧,但是确实很基础。在windows的sdk环境下面,我们用传统的c编写程序,在需要的绘图地方(比如响应WM_PAINT消息的分支)这样做:

hdc = GetDC( hwnd );
oldGdiObject = SelectObject( hdc,newGdiObject );
...绘图操作...
SelectObject( hdc,oldGdiObject );
DeleteObject( newGdiObject );
ReleaseDC( hdc);

或者是这样

BeginPaint( hwnd,&ps );//PAINTSTRUCT ps -- ps is a paint struct
...绘图操作...
EndPaint( hwnd )

这就是大概的过程,我们看到了hdc(图形DC句柄)的应用,在绘图的部分,每一个绘图函数基本上也要用到这个句柄,最后我们还必须释放它,否则将严重影响性能。每次我们都必须调用GetDC这个api函数得到(不能用全局变量保存结果重复使用,我在后面解释)。这些是最最基本的windows图形操作的方式,相比dos时代简单了些,但是有些概念也难理解了些。vb里面的简单的point函数其实最后也是被转化为这样的方式来执行,系统帮助做了很多事情。

到了mfc里面,由于有了封装,所有的hdc被隐藏在对象中做为隐藏参数传递(就是DC类的this啦~~),所以我们的关键话题就转变为了怎样得到想要的 DC类而已,这个过程其实大同小异的。在消息响应的过程中,WM_PAINT被转变为OnDraw(),OnPaint()一系列函数来响应,这些函数一般都有个参数CDC *pDC传入进来,因此在这些函数里面,我们就只需要直接画图就可以了,和以前sdk的方式一样。

但是WM_PAINT消息响应的频度太高了,比如最小化最大化,移动窗体,覆盖等等都引起重绘,经常的这样画图,很是消耗性能;在有些场合,比如随机作图的场合,每一次就改变,还导致了程序的无法实现。怎么解决后一种问题呢。

ms 在msdn的例子里面交给我们document/view的经典解决办法,将图形的数据存储在document类里面,view类只是根据这些数据绘图。比如你要画个圆,只是将圆心和半径存在document里面,view类根据这个里面的数据在屏幕上面重新绘制。那么,我们只需要随机产生一次数据就可以了。

这样还是存在性能的问题,于是我们开始考虑另外的解决方法。我们知道,将内存中的图片原样输出到屏幕是很快的,这也是我们在dos时代经常做的事情,能不能在windows也重新利用呢?答案就是内存缓冲绘图,我们今天的主题。

我们还是回到DC上来,既然DC是绘图对象,我们也就可以自己来在内存里面造一个,让它等于我们想要的图,图(CBitmap)可以存储在document 类里面,每一次刷新屏幕都只是将这个图输出到屏幕上面,每一次作图都是在内存里面绘制,保存在document的图里面,必要时还可以将图输出到外存保存。这样既保证了速度,也解决了随机的问题,在复杂作图的情况下对内存的开销也不大(总是一副图片的大小)。这是一个很好的解决办法,现在让我们来实现它们。

我们在document类里面保存一个图片

CBitmap m_bmpBuf;//这里面保存了我们做的图,存在于内存中

在view类里面我们需要将这个图拷贝到屏幕上去
位于OnDraw(CDC *pDC)函数中:

CDC dcMem;//以下是输出位图的标准操作
CBitmap *pOldBitmap = NULL;
dcMem.CreateCompatibleDC(NULL);
pOldBitmap = dcMem.SelectObject(&pDoc->m_bmpBuf);
BITMAP bmpinfo;
pDoc->m_bmpBuf.GetBitmap(&bmpinfo);
pDC->BitBlt(0,0,bmpinfo.bmWidth,bmpinfo.bmHeight,&dcMem,0,0,SRCCOPY);
dcMem.SelectObject(pOldBitmap);
dcMem.DeleteDC();

在我们需要画图的函数里面,我们完成绘图工作

CBmpDrawDoc *pDoc = GetDocument(); //得到document中的bitmap对象
CDC *pDC = GetDC();
CDC dcMem;
dcMem.CreateCompatibleDC(NULL);//这里我们就在内存中虚拟建造了DC
pDoc->m_bmpBuf.DeleteObject();
pDoc->m_bmpBuf.CreateCompatibleBitmap(pDC,100,100);//依附DC创建bitmap
CBitmap *pOldBitmap = dcMem.SelectObject(&pDoc->m_bmpBuf);//我们调入了我们bitmap目标

dcMem.FillSolidRect(0,0,100,100,RGB(255,255,255));//这些时绘图操作,随便你^_^
dcMem.TextOut(0,0,"Hello,world!");
dcMem.Rectangle(20,20,40,40);
dcMem.FillSolidRect(40,40,50,50,RGB(255,0,0));

pDC->BitBlt(0,0,100,100,&dcMem,0,0,SRCCOPY);//第一次拷贝到屏幕
dcMem.SelectObject(pOldBitmap);
dcMem.DeleteDC();


全部的过程就是这样,很简单吧。以此为例子还可以实现2个缓冲或者多个缓冲等等,视具体情况而定。当然在缓冲区还可以实现很多高级的图形操作,比如透明,合成等等,取决于具体的算法,需要对内存直接操作(其实就是当年dos怎么做,现在还怎么做)。

再来解释一下前面说的为什么不能用全局变量保存DC问题。其实DC也是用句柄来标识的,所以也具有句柄的不确定性,就是只能随用随取,不同时间两次取得的是不同的(使用过文件句柄地话,应该很容易理解的)。那么我们用全局变量保存的DC就没什么意义了,下次使用只是什么也画不出来。(这一点的理解可以这样: DC需要占用一定的内存,那么在频繁的页面调度中,位置难免改变,于是用来标志指针的句柄也就不同了)。

- 作者: itecwwj 2005年04月1日, 星期五 18:45  回复(1) |  引用(1) 加入博采

delphi 中画带箭头的直线(改自网上一位论坛版主的vb代码)

procedure TLineItem.Draw(aCanvas: TCanvas);

var

  Xa, Ya, Xb, Yb: real;

  D: real;

  X1, Y1, X0, Y0: Integer;

begin

  aCanvas.Pen.Style := PsSolid;

  aCanvas.Pen.Color := clWhite;

//画直线

  aCanvas.MoveTo(PtStart.X, PtStart.Y);

  aCanvas.LineTo(PtEnd.X, PtEnd.Y);

  //画箭头

  X0 := PtStart.X;//PtStart是箭头的起点,PtEnd是终点,都是Tpoint

  Y0 := PtStart.Y;

  X1 := PtEnd.X;

  Y1 := PtEnd.Y;

  D := Sqrt((Y1 - Y0) * (Y1 - Y0) + (X1 - X0) * (X1 - X0));

  if D > 0 then begin



procedure TLineItem.Draw(aCanvas: TCanvas);

var

  Xa, Ya, Xb, Yb: real;

  D: real;

  X1, Y1, X0, Y0: Integer;

begin

  aCanvas.Pen.Style := PsSolid;

  aCanvas.Pen.Color := clWhite;

//画直线

  aCanvas.MoveTo(PtStart.X, PtStart.Y);

  aCanvas.LineTo(PtEnd.X, PtEnd.Y);

  //画箭头

  X0 := PtStart.X;//PtStart是箭头的起点,PtEnd是终点,都是Tpoint

  Y0 := PtStart.Y;

  X1 := PtEnd.X;

  Y1 := PtEnd.Y;

  D := Sqrt((Y1 - Y0) * (Y1 - Y0) + (X1 - X0) * (X1 - X0));

  if D > 0 then begin

    Xa := X1 + ARROWLEN * ((X0 - X1) + (Y0 - Y1) / 2) / D;

    Ya := Y1 + ARROWLEN * ((Y0 - Y1) - (X0 - X1) / 2) / D;

    Xb := X1 + ARROWLEN * ((X0 - X1) - (Y0 - Y1) / 2) / D;

    Yb := Y1 + ARROWLEN * ((Y0 - Y1) + (X0 - X1) / 2) / D;

    aCanvas.MoveTo(PtEnd.X, PtEnd.Y);

    aCanvas.LineTo(Trunc(Xa), Trunc(Ya));

    aCanvas.MoveTo(PtEnd.X, PtEnd.Y);

    aCanvas.LineTo(Trunc(Xb), Trunc(Yb));

  end;

//如果选中画出焦点矩形,可以不要

  if FSelected = true then begin

    aCanvas.Rectangle((PtStart.X - FORCUSRANGE),

      (PtStart.Y - FORCUSRANGE),

      (PtStart.X + FORCUSRANGE),

      (PtStart.Y + FORCUSRANGE));

    aCanvas.Rectangle((PtEnd.X - FORCUSRANGE),

      (PtEnd.Y - FORCUSRANGE),

      (PtEnd.X + FORCUSRANGE),

      (PtEnd.Y + FORCUSRANGE));

  end;

end;

 

canvas是任何一个拥有画笔的组件的canvas都可以。具体几何依据原作者没有讲。但是经过底下验算。有三个特点。

1.       箭头两翼端点连线和直线垂直(斜率之积等于-1)。

2.       .箭头两翼长度相同。(等腰三角形)

3.       箭头两翼长度和两翼端点间的距离比值一定。(决定了夹角)

- 作者: itecwwj 2005年04月1日, 星期五 18:43  回复(0) |  引用(1) 加入博采

delphi透明组件(控件)开发
透明的控件, 一般继承自TGraphicControl的
(就是那些没有handle属性, 不能有focus的控件, 如image)
都有Transparent属性. 对TWinControl类的控件, 要实现透明只要完成以下
四步基本上就成了.

网友提供的方法:

/////////////////////////////////////////////
透明的控件, 一般继承自TGraphicControl的
(就是那些没有handle属性, 不能有focus的控件, 如image)
都有Transparent属性. 对TWinControl类的控件, 要实现透明只要完成以下
四步基本上就成了.
1.在Create中设定ControlStyle :=
ControlStyle - [csOpaque];)
2. override 它的CreateParams方法, exstyle 里加上WS_EX_TRANSPARENT.
3. 修改它的parent的window style, 去掉WS_CLIPCHILDREN.
  inherited CreateParams(Params);
  with Params do
  begin
  { 完全重画 }
    Style := Style and not WS_CLIPCHILDREN;
    Style := Style and not WS_CLIPSIBLINGS;
  { 增加透明 }
    ExStyle := ExStyle or WS_EX_TRANSPARENT;
  end;


4. 截获WM_ERASEBKGND, 什么都不做直接返回1.(不搽除背景)
一般有上面3步能成. 有些控件比如TPanel, 在它的paint中用了fillrect,
所以要实现透明的话还要override 它的paint方法, 自己画.
按钮透明需要进一步处理.
createparams里加上style := style or BS_OWNERDRAW;
然后在WM_DRAWITEM中自己画吧
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


我的研究发现    Style := Style and not WS_CLIPCHILDREN;
    Style := Style and not WS_CLIPSIBLINGS;
没有作用。
如果你要改变控件位置和颜色,请拦截WM_MOVE,和CN_CTLCOLOREDIT消息,在里面调用invalidate方法,重绘组件。

阅 读inside vcl 和 飞思的组件开发书籍。了解如何选择适当的基类去继承然后扩展成自己的类。建议写控件的朋友应先了解这方面的知识,不要从tobject开始写起。 ControlStyle :=ControlStyle - [csOpaque];)很关键,看源代码发现它影响了整个控件的画方法。现在已经实现了透明组件,可是用鼠标移动该组件就出现刷新不够,背景混乱的问 题。现在正在阅读timage源代码,看它是如何实现。想讨论这方面技术的朋友请email:wenjunwu430@163.com



附网上找到的学习资料

/////////////////////////////////////////////
透明的控件, 一般继承自TGraphicControl的
(就是那些没有handle属性, 不能有focus的控件, 如image)
都有Transparent属性. 对TWinControl类的控件, 要实现透明只要完成以下
四步基本上就成了.
1.在Create中设定ControlStyle :=
ControlStyle - [csOpaque];)
2. override 它的CreateParams方法, exstyle 里加上WS_EX_TRANSPARENT.
3. 修改它的parent的window style, 去掉WS_CLIPCHILDREN.

  inherited CreateParams(Params);
  with Params do
  begin
  { 完全重画 }
    Style := Style and not WS_CLIPCHILDREN;
    Style := Style and not WS_CLIPSIBLINGS;
  { 增加透明 }
    ExStyle := ExStyle or WS_EX_TRANSPARENT;
  end;


4. 截获WM_ERASEBKGND, 什么都不做直接返回1.(不搽除背景)
一般有上面3步能成. 有些控件比如TPanel, 在它的paint中用了fillrect,
所以要实现透明的话还要override 它的paint方法, 自己画.
按钮透明需要进一步处理.
createparams里加上style := style or BS_OWNERDRAW;
然后在WM_DRAWITEM中自己画吧

这里有个控件的源代码,非常好用,可惜焦点在这个控件上时不透明,你可以试着改一下。
unit RbsWiredEdit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

const
  TWM_RbsInvalidate=WM_USER+1;

type
  TRbsWiredEdit = class(TEdit)
  private
    { Private declarations }
    procedure RbsInvalidate(var Message:TMessage); message
              TWM_RbsInvalidate;
    procedure CNCTLCOLOREDIT(var Message:TWMCTLCOLOREDIT); message
              CN_CTLCOLOREDIT;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
    procedure WMMove(var Message: TMessage); message WM_MOVE;

  protected
    { Protected declarations }
    FTransparent: boolean;
    procedure CreateWnd; override;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure DoExit; override;
    procedure DoEnter; override;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    procedure Invalidate; override;

  published
    { Published declarations }
  end;

procedure Register;

implementation

constructor TRbsWiredEdit.Create(AOwner:TComponent);
begin
inherited create(AOwner);
   ftransparent:=true;
end;

procedure TRbsWiredEdit.CreateWnd;
begin
inherited CreateWnd;
   if fTransparent then
      begin
       SetWindowLong(Parent.Handle, GWL_STYLE,
       GetWindowLong(Parent.Handle, GWL_STYLE) and not WS_CLIPCHILDREN);
       end;
end;

procedure TRbsWiredEdit.RbsInvalidate(var Message:TMessage);
var r:TRect;
begin
  if (Parent<>nil) and FTransparent then
    begin
      r:=ClientRect;
      r.TopLeft:=Parent.ScreenToClient(ClientToScreen(r.TopLeft));
      r.BottomRight:=Parent.ScreenToClient(ClientToScreen(r.BottomRight));
      RedrawWindow(Handle,nil,0,RDW_FRAME+RDW_INVALIDATE);
    end;
end;

procedure TRbsWiredEdit.CNCTLCOLOREDIT(var Message:TWMCTLCOLOREDIT);
begin
  ifFTransparent then
   with Message do
    begin
      SetBkMode(ChildDC,Windows.TRANSPARENT);
      Result:=GetStockObject(HOLLOW_BRUSH)
    end
   else inherited;
end;



procedure TRbsWiredEdit.WMEraseBkgnd(var Message:TWMERASEBKGND);
begin
  if FTransparent and not (csDesigning in ComponentState) then
      PostMessage(Handle,TWM_RbsInvalidate,0,0)
  else inherited;
end;

procedure TRbsWiredEdit.WMMove(var message:TMessage);
begin
inherited;
if FTransparent then SendMessage(Handle,TWM_RbsInvalidate,0,0)
  else Invalidate;
end;

procedure TRbsWiredEdit.CreateParams(var Params:TCreateParams);
begin
inherited CreateParams(Params);
if (CsDesigning in ComponentState) then exit;
    with Params do
      begin
   ExStyle:=ExStyle or WS_EX_TRANSPARENT;
      end;
end;

procedure TRbsWiredEdit.DoExit;
begin
inherited;
   FTransparent:=true;
   SetCursor(0);
   RecreateWnd;
end;

procedure TRbsWiredEdit.DoEnter;
var exstyle,stdstyle:longint;
begin
inherited;
Ftransparent:=false;
StdStyle:= Windows.GetWindowLong(handle, GWL_EXSTYLE);
exStyle:= StdStyle and not WS_EX_TRANSPARENT;
Windows.SetWindowLong(handle, GWL_EXSTYLE, exStyle);
invalidate;
end;

procedure TRbsWiredEdit.Invalidate;
begin
if FTransparent then SendMessage(Handle,TWM_RbsInvalidate,0,0)
  else inherited;
end;

procedure Register;
begin
  RegisterComponents('Rombest', [TRbsWiredEdit]);
end;

end.
             

- 作者: itecwwj 2005年04月1日, 星期五 18:40  回复(1) |  引用(1) 加入博采

delphi的属性property、消息处理特点、事件属性。

适合delphi初学者,有面向对象知识和java或者vc编程经验人士阅读。


Delphi  中的属性property(适合初学delphi

Propery In Delphi

 

前言:

适合delphi初学者,有面向对象知识和java或者vc编程经验人士阅读。

一普通属性

我们在delphi的类中常常能看到这样的代码:propert property 属性名 类型名 read 字符串1 write 字符串2

这里属性的名字可能不同。都是这样的格式:property 属性名 read 字符串1 write 字符串2

我以property Left: Integer read FLeft write SetLeft;为例子,它是Tcontrol的属性,你可以在controls文件中找到。Left是一个Integer类型的属性。Read申明了访问该变量要访问的变量或者方法,write申明了修改该变量时访问的变量或者方法。注意:可以是变量,也可以是方法,我在后面告诉大家这是怎么回事。这里它是一个变量,名字叫做FLeft。出于封装的目的,我们一般都会把这样的变量放在private中间去,果然,在private中我们可以找到

FLeft: Integer这段代码(出于命名的习惯,我们把这样的变量取名为属性名前面加一个大写的F)。这样当你read该属性时,实际上你访问的是Fleft的值。所以你可以写些方法来修改fleft,间接修改了left的值。然后我们再看SetLeft,这里它是一个方法(问我怎么知道?还是看命名规则,通常用属性名前面加上Set),通常也会放在private中去,我们来验证一下,我们在private中看到申明:

procedure SetLeft(Value: Integer);

和如下代码实现:

procedure TControl.SetLeft(Value: Integer);

begin

  SetBounds(Value, FTop, FWidth, FHeight);

  Include(FcalingFlags, sfLeft);

end;

如果你写了如下代码改变leftcontrol1.left:=23,那么程序调用了函数SetLeft(23),SetBounds是改变区域的函数,这里你就明白了它封装了的好处,每次你改变left时它就会根据新的left而改变区域的大小,这个函数同时也改变了Fleft的大小,请查阅SetBounds的源代码。

procedure TControl.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);

begin

  if CheckNewSize(AWidth, AHeight) and

    ((ALeft <> FLeft) or (ATop <> FTop) or

    (AWidth <> FWidth) or (AHeight <> FHeight)) then

  begin

    InvalidateControl(Visible, False);

    FLeft := ALeft;

    FTop := ATop;

    FWidth := AWidth;

    FHeight := AHeight;

    UpdateAnchorRules;

    Invalidate;

    Perform(WM_WINDOWPOSCHANGED, 0, 0);

    RequestAlign;

    if not (csLoading in ComponentState) then Resize;

  end;

end;

这样外部就看起来只是通过赋值运算来改变了该属性的值。Readwrite可以是变量,或者是函数,取决于你的设计。你当然可以这样写: propert property 属性名 类型名 read 变量1 write 变量2变量1和变量2可以是相同的。你也可以这样propert property 属性名 类型名 read 方法1 write 方法2任你组合。但是有2点要注意:

1.         命名规则最好按习惯来,易于阅读。

2.         如果是变量,那么类型要和属性的类型一致,如果是方法,那么入口参数要和属性的类型一致。

二事件属性Tevent

我们常常使用组件的事件属性,比方说click事件,可是我们很难从表面看出它是如何调用的呢,如何触发的呢。下面我来给你解答。

我们在属性管理器object inspector中看到eventonclick右边对应了一个方法的名字。我们其实可以这样给一个组件的事件对应上一个出来方法。以一个form为例子Form1. OnMouseDown:=‘你的方法‘。注意方法的入口参数有讲究,这里是(SenderTObject

我们还是一tcontrol为例子,我们找到这段代码:

property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;跟上面讲的类似,不过这里有个特殊的类型,TNOtifyEvent,是个事件类型,我们找到它的申明:

TMouseEvent = procedure(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer) of object;

可以看到,它其实就是个函数,但是蓝色部分把入口参数限定了。那么我们通过赋值Form1. OnMouseDown:=‘你的方法‘,就对应了OnMouseDown的方法。然后我们只要写了一段拦截鼠标消息的函数,在里面直接或间接调用FonMouseDown,那么就把消息和处理函数对应上去了。这里它间接调用的层数比较多,讲起来比较费时间,涉及到Message类型,建议大家去看下李维的书。

以下附上间接调用过程,其实还要很多消息发生时也间接调用了,就不一一举出来了:(

 

procedure WMRButtonDblClk(var Message: TWMRButtonDblClk); message WM_RBUTTONDBLCLK;//拦截消息的函数

procedure TControl.WMRButtonDblClk(var Message: TWMRButtonDblClk);

begin

  inherited;

  DoMouseDown(Message, mbRight, [ssDouble]);

end;

 

procedure DoMouseDown(var Message: TWMMouse; Button: TMouseButton;

Shift: TShiftState);

procedure TControl.DoMouseDown(var Message: TWMMouse; Button: TMouseButton;

  Shift: TShiftState);

begin

  if not (csNoStdEvents in ControlStyle) then

    with Message do

     if (Width > 32768) or (Height > 32768) then

        with CalcCursorPos do

          MouseDown(Button, KeysToShiftState(Keys) + Shift, X, Y)

      else

        MouseDown(Button, KeysToShiftState(Keys) + Shift, Message.XPos, Message.YPos);

end;

 

procedure MouseDown(Button: TMouseButton; Shift: TShiftState;

X, Y: Integer); dynamic;

procedure TControl.MouseDown(Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  if Assigned(FOnMouseDown) then FOnMouseDown(Self, Button, Shift, X, Y);

end;

 

好处:

如果你多写自己的类,你会发现这样做是多么的方便,而不会像java要写getleftsetleft,然后把text放在private中,访问和修改时要调用不同的方法,而delphi你都只是调用contol1.text来访问,control1.text:='某字符串'来修改它的值。

而在处理消息方面,基类把onclickonmousedown这样的属性申明为protected,如果你要使用,可以申明为published就可以出现在object inspector里面,然后方便的写处理方法,你也可以不公开,而在ctreate函数中给它赋值,而不用像java那样,写listener那么复杂。

我的研究也不深,有什么不妥请指正:)。欢迎来信wenjunwu430@163.com

 

华中科技大学,互联网中心实验室(itec.hust.edu.cn)

邬文俊

2004-12-4

- 作者: itecwwj 2005年04月1日, 星期五 18:35  回复(0) |  引用(1) 加入博采

全球华人大签名反对日本成为安理会常任理事国——新浪留言板转载
禽兽!我等着你!!!
你第一次到我这里,
  那时我叫大唐,
  威震世界我强盛无比。
  你赤著双脚、
  衣衫褴褛。
  诚惶诚恐你走进我的光辉大殿里。

  我记得我叫秦的时候曾让徐福,
  带领三千童男童女,
  远渡东海,
  扎根到你那里。
  因此我认定:
  有我的血液流到你的血管里。
  对於你的潦倒,
  我没有嫌弃。
  我给了你锦衣朝服,
  我盛唐全部礼仪、
  和那双你穿到现在的木屐。
  你千恩万谢,
  满口"哈依、哈依"。
  你藏不住那贪婪的目光,
  我告诫自己——
  这是一个人面兽心的家夥,就象在图上:
  它的形状象一只可恶的虫蚁。
  仁至义尽我送你回去,
  还教给你我盛世的全部礼仪。
  你走之後我轻声自语:
  "它还会回来"——
  我等著你。

  当我叫明的时候我等到了你。
  你手拿倭刀,
  穿著我教你做的唐衣。
  你说你并不得已,
  因爲後面有驱赶你的丰臣秀吉。
  杀人放火你奸淫掠虏,
  戚家儿郎把你赶下海去。
  用东海水我洗著伤口,
  贼心不死的禽兽——
  我等著你!

  日月如梭我身染重疾,
  东方的巨人渐渐不能自己。
  围攻撕咬我的兽群中,
  我又看见了你:
  强盗火拼你咬走了俄国熊罴,
  独占我北方要地。
  贪心不足你膨胀的恶欲。

  终於到了"九.一八"那是一九三一,
  血肉从我身上分离,
  於是有了僞满供你驱骑。
  欲壑难平你得寸进尺,
  疯狂的野兽你竞妄想把世界归己。

  一九三七的七月七,
  我的胸膛上你印上了铁蹄。
  作威作福你那麽得意,
  心在淌血我把仇恨铭记。
  多行不义你必自毙,
  自作自受——
  蘑菇云中你看见了自己的广岛和长崎。
  夹著尾巴你滚了回去,
  还有那面沾满血腥的膏药旗。

  跟在霸强後面,
  你又觉得有势可倚。
  偷机取巧你开始发迹,
  一夜之间你觉得富得无人可比。
  不改的本性让你又暗藏杀人的利器,
  打著自卫的幌子想把世人蒙弊。
  爲富不仁你开始觉得自己家里挤,
  又妄想到我的岛上来"钓鱼"!
  伤疤犹在你就忘了痛,
  参拜亡灵的政客们啊,
  在靖国神社你们是否看见了东条英机?
  往日的屈辱我怎能忘记?
  昨天的病夫现在已有了强壮的身躯!
  睁大眼睛我看你要向何处去?
  还想再来吗?
  ——世世代代我等著你!

  狼生的孩子仍然要吃肉,
  魔鬼释缚后还会害人。
  鬼魂在庙宇里在受膜拜,
  人人都知道你贼心不死。
  多少年来我受了你多少凌辱和欺骗,
  强霸面前你又有狗仗人势,
  又见到膏药旗在我的家里?!
  我知道,你早晚还会回来,
  如同饿狼常来觅食。
  子弹上膛的猎枪手中拿紧吧
  我世世代代等着你!
  -----我等着你!!
禽兽!我等着你!!!
你第一次到我这里,
  那时我叫大唐,
  威震世界我强盛无比。
  你赤著双脚、
  衣衫褴褛。
  诚惶诚恐你走进我的光辉大殿里。

  我记得我叫秦的时候曾让徐福,
  带领三千童男童女,
  远渡东海,
  扎根到你那里。
  因此我认定:
  有我的血液流到你的血管里。
  对於你的潦倒,
  我没有嫌弃。
  我给了你锦衣朝服,
  我盛唐全部礼仪、
  和那双你穿到现在的木屐。
  你千恩万谢,
  满口"哈依、哈依"。
  你藏不住那贪婪的目光,
  我告诫自己——
  这是一个人面兽心的家夥,就象在图上:
  它的形状象一只可恶的虫蚁。
  仁至义尽我送你回去,
  还教给你我盛世的全部礼仪。
  你走之後我轻声自语:
  "它还会回来"——
  我等著你。

  当我叫明的时候我等到了你。
  你手拿倭刀,
  穿著我教你做的唐衣。
  你说你并不得已,
  因爲後面有驱赶你的丰臣秀吉。
  杀人放火你奸淫掠虏,
  戚家儿郎把你赶下海去。
  用东海水我洗著伤口,
  贼心不死的禽兽——
  我等著你!

  日月如梭我身染重疾,
  东方的巨人渐渐不能自己。
  围攻撕咬我的兽群中,
  我又看见了你:
  强盗火拼你咬走了俄国熊罴,
  独占我北方要地。
  贪心不足你膨胀的恶欲。

  终於到了"九.一八"那是一九三一,
  血肉从我身上分离,
  於是有了僞满供你驱骑。
  欲壑难平你得寸进尺,
  疯狂的野兽你竞妄想把世界归己。

  一九三七的七月七,
  我的胸膛上你印上了铁蹄。
  作威作福你那麽得意,
  心在淌血我把仇恨铭记。
  多行不义你必自毙,
  自作自受——
  蘑菇云中你看见了自己的广岛和长崎。
  夹著尾巴你滚了回去,
  还有那面沾满血腥的膏药旗。

  跟在霸强後面,
  你又觉得有势可倚。
  偷机取巧你开始发迹,
  一夜之间你觉得富得无人可比。
  不改的本性让你又暗藏杀人的利器,
  打著自卫的幌子想把世人蒙弊。
  爲富不仁你开始觉得自己家里挤,
  又妄想到我的岛上来"钓鱼"!
  伤疤犹在你就忘了痛,
  参拜亡灵的政客们啊,
  在靖国神社你们是否看见了东条英机?
  往日的屈辱我怎能忘记?
  昨天的病夫现在已有了强壮的身躯!
  睁大眼睛我看你要向何处去?
  还想再来吗?
  ——世世代代我等著你!

  狼生的孩子仍然要吃肉,
  魔鬼释缚后还会害人。
  鬼魂在庙宇里在受膜拜,
  人人都知道你贼心不死。
  多少年来我受了你多少凌辱和欺骗,
  强霸面前你又有狗仗人势,
  又见到膏药旗在我的家里?!
  我知道,你早晚还会回来,
  如同饿狼常来觅食。
  子弹上膛的猎枪手中拿紧吧,
  我世世代代等着你!
  -----我等着你!!

- 作者: itecwwj 2005年03月30日, 星期三 14:56  回复(10) |  引用(1) 加入博采