先有Delphi内存对象,后有句柄(如果需要的话),最后再显示
2016-02-08 16:54
495 查看
在设计期放上一个Panel1和Button1,然后设置Panel1.Visible:=False
这时候执行:
得到552,说明这个Panel1这个内存对象已经存在了。再把它的visible改成true,还是得到552。说明这个内存对象已经存在,且大小没区别(其内容可能会有所不同)。
再重新把visible改成false,测试以下代码:
结果总是显示已经有句柄了。这是为什么呢?明明还没有显示控件,理应执行HandleNeeded
这是因为使用Handle属性时,使用了GetHandle函数,瞬间就把句柄给创建了,所以怎么测试都是已经有句柄。
所以要测,就应该测试FHandle。这就需要把FHandle从private改成public。然后测试:
这时候的结果就是no handle了。
设计期把Panel1.visible改成false,再测试:
其结果也是no handle
------------------------------------------------------------------------------------------------------------------------------------------
再来一个出错的代码:
顿时出错。因为还没有指定父控件,却在执行Handle属性的GetHandle方法时出错。其实我是从这个错误的例子中,忽然明白,直接使用Panel1.handle=0还没那么简单,是有问题的,不可以使用这种方法来判断。
------------------------------------------------------------------------------------------------------------------------------------------
再来一个问题,设计期放置Image1并载入图片,然而visible设为false,此时Image1在内存中的状态会怎么样呢?目前还不清楚。。。
这时候执行:
procedure TForm1.Button4Click(Sender: TObject); begin ShowMessage(IntToStr(panel1.InstanceSize)); end;
得到552,说明这个Panel1这个内存对象已经存在了。再把它的visible改成true,还是得到552。说明这个内存对象已经存在,且大小没区别(其内容可能会有所不同)。
再重新把visible改成false,测试以下代码:
procedure TForm1.Button1Click(Sender: TObject); begin if (panel1.Handle=0) then ShowMessage('no handle') else ShowMessage('handled'); end;
结果总是显示已经有句柄了。这是为什么呢?明明还没有显示控件,理应执行HandleNeeded
procedure TWinControl.HandleNeeded; begin if FHandle = 0 then begin if Parent <> nil then Parent.HandleNeeded; CreateHandle; end; end; function TWinControl.GetHandle: HWnd; begin HandleNeeded; Result := FHandle; end;
这是因为使用Handle属性时,使用了GetHandle函数,瞬间就把句柄给创建了,所以怎么测试都是已经有句柄。
所以要测,就应该测试FHandle。这就需要把FHandle从private改成public。然后测试:
procedure TForm1.Button1Click(Sender: TObject); var panel1 : TPanel; begin panel1:=TPanel.Create(nil); panel1.Left:=100; panel1.top:=100; if (panel1.FHandle=0) then ShowMessage('no handle') else ShowMessage('handled'); end;
这时候的结果就是no handle了。
设计期把Panel1.visible改成false,再测试:
procedure TForm1.Button1Click(Sender: TObject); begin if (panel1.FHandle=0) then ShowMessage('no handle') else ShowMessage('handled'); end;
其结果也是no handle
------------------------------------------------------------------------------------------------------------------------------------------
再来一个出错的代码:
procedure TForm1.Button1Click(Sender: TObject); var panel1 : TPanel; begin panel1:=TPanel.Create(nil); panel1.Left:=100; panel1.top:=100; if (panel1.Handle=0) then ShowMessage('no handle') else ShowMessage('handled'); end;
顿时出错。因为还没有指定父控件,却在执行Handle属性的GetHandle方法时出错。其实我是从这个错误的例子中,忽然明白,直接使用Panel1.handle=0还没那么简单,是有问题的,不可以使用这种方法来判断。
------------------------------------------------------------------------------------------------------------------------------------------
再来一个问题,设计期放置Image1并载入图片,然而visible设为false,此时Image1在内存中的状态会怎么样呢?目前还不清楚。。。
相关文章推荐
- 终于懂了:FWinControls子控件的显示是由Windows来管理,而不是由Delphi来管理(显示透明会导致计算无效区域的方式有所不同——透明的话应减少剪裁区域,所以要进行仔细计算)
- Delphi 序列化、反序列化、串行化、持久化
- DELPHI语法基础学习笔记-Windows 句柄、回调函数、函数重载等(Delphi中很少需要直接使用句柄,因为句柄藏在窗体、 位图及其他Delphi 对象的内部)
- Delphi体系内部的4种消息传递办法(Send,Post,Perform,Dispatch)
- delphi高手突破之异常及错误处理
- delphi如何加上spliter分割条,任意调整大小
- delphi高手突破学习笔记之面向对象类和对象的本质(有汇编解释 good)
- delphi模态窗体最小化会隐藏的问题
- 终于懂了:Delphi消息的Result完全是生造出来的,不是Windows消息自带的(Delphi对Windows编程体系的改造越大,学习收获就越大)
- 终于懂了:Delphi重定义消息结构随心所欲,只需要前4个字节是消息编号就行了,跟Windows消息虽然尽量保持一致,但其实相互没有特别大的关系。有了这个,就有了主动,带不带句柄完全看需要。
- WM_PAINT在微软官方定义中,wParam和lParam都没有使用,所以就被Delphi给重定义了这个消息,还增加了DC(Delphi可任意改写消息的结构,只需要保持前4个字节是消息即可,另外要携带微软定义的所有必要信息就行了)
- WM_PAINT中应该用BeginPaint与EndPaint这两个api,它们的功能正是使无效区域恢复(所以WM_PAINT里即使什么都不做,也必须写上BeginPaint与EndPaint)——Delphi里WM_PAINT消息的三个走向都做到了这一点
- Delphi和C++数据类型对照表
- Delphi中如何获得光标
- 利用Delphi编写Socket通信程序
- (delphi)DbgridEh排序
- ListView 百分比进度条(delphi版)
- Delphi的RTTI还分为对类和对象的判断,以及对普通属性的判断——相比之下,C++的RTTI实在太弱!
- 终于懂了:TWinControl主要是Delphi官方用来封装Windows的官方控件,开发者还是应该是有TCustomControl来开发三方控件
- C++能在三个地方创造对象,而Delphi只有一个地方