给MDI窗体加背景,解释MakeObjectInstance和CallWindowProc的用法
工程含有1个MDI主窗口和2个子窗口。唯一需要注意的是,每个窗体都有ClientHandle,但只有当自己是MDI主窗体的情况下才有值,否则等于0。
unit Unit1; interface uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, jpeg, Menus; type
TForm1 = class(TForm)
Image1: TImage;
MainMenu1: TMainMenu;
N1: TMenuItem;
dd1: TMenuItem;
procedure FormShow(Sender: TObject);
private
FClientInstance : TFarProc;
FPrevClientProc : TFarProc;
Procedure ClientWndProc(Var Message: TMessage); // 自定义的窗口过程
{ Private declarations }
public
{ Public declarations }
end; var
Form1: TForm1; implementation {$R *.DFM}
procedure TForm1.ClientWndProc(var Message: TMessage);
var
Dc : hDC;
Row : Integer;
Col : Integer;
begin
with Message do
case Msg of
WM_ERASEBKGND:// 当要重会背景时
begin
Dc := TWMEraseBkGnd(Message).DC; // 消息自带DC
// 铺图象
// 计算并会制行和高总共要画的数量。
for Row := to ClientHeight div Image1.Picture.Height do
for Col := to ClientWidth div Image1.Picture.Width do
BitBlt(Dc,Col * Image1.Picture.Width, Row * Image1.Picture.Height
,Image1.Picture.Width, Image1.Picture.Height
,Image1.Picture.Bitmap.Canvas.Handle, , , SRCCOPY);
Result := ; // 到此结束,并不继续传递
end;
else // 传递其他消息
Result := CallWindowProc(FPrevClientProc,ClientHandle,Msg,wParam,lParam);
end;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
FClientInstance := MakeObjectInstance(ClientWndProc);//将自定义过程的地址入口存入PClientInstance中
FPrevClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));//记录消息位置
SetWindowLong(ClientHandle,GWL_WNDPROC,LongInt(FClientInstance));//重新载入窗口的消息并继续处理。
end; end.
另外还有: Delphi非应用程序主窗口创建MDI (把原来的主窗体都给换掉了并且关闭掉了,牛!)
http://blog.csdn.net/suiyunonghen/article/details/4209306
另一个通过修改窗口函数达到目的的例子(禁止用键盘左右箭头,去切换PageControl页签):
unit Unit1; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls; type
TForm1 = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure EditWndProc(var Message: TMessage);
public
{ Public declarations }
end; var
Form1: TForm1;
EditHandle: THandle;
EditPointer:Pointer; implementation {$R *.dfm} procedure TForm1.EditWndProc(var Message: TMessage);
begin
case Message.Msg of
WM_KEYDOWN : //如果是按键消息
begin
if Message.WParam in [,] then //如果是左右箭头
Exit;
end;
end;
Message.Result:=CallWindowProc(EditPointer, EditHandle, Message.Msg, Message.WParam, Message.LParam);
end; procedure TForm1.FormCreate(Sender: TObject);
Var P:Pointer;
begin
EditHandle:=PageControl1.Handle;
if EditHandle<> then
begin
EditPointer := Pointer(GetWindowLong(EditHandle, GWL_WNDPROC));
P := Classes.MakeObjectInstance(EditWndProc);
SetWindowLong(EditHandle, GWL_WNDPROC, Longint(P));
end;
end;
我的理解:不能通过覆盖TPageControl的WndProc来达到目的,否则WndProc这个函数写在哪里呢(因为我没有重新定义一个类)?只能通过替换TPageControl的WndProc来达到目的。
给MDI窗体加背景,解释MakeObjectInstance和CallWindowProc的用法的更多相关文章
- 机房收费系统之【只允许一个MDI窗体 错误:426】 标签: vb 2014-08-15 10:36 1149人阅读 评论(23)
机房收费系统的主窗体是MDI窗体,为了在这个窗体上添加控件,所以我们在窗体上添加了picture控件,在MDI窗体中,子窗体实际上位于MDIClient里,即子窗体的父窗体就是MDIClient,而放 ...
- 使用DevExpress.XtraTabbedMdi.XtraTabbedMdiManager控件来加载MDI窗体
使用DevExpress.XtraTabbedMdi.XtraTabbedMdiManager控件来加载MDI窗体 [csharp] view plaincopyprint? <SPAN ...
- Winform MDI窗体切换不闪烁的解决办法(测试通过)
https://stackoverflow.com/questions/5817632/beginupdate-endupdate-for-datagridview-request SuspendLa ...
- 小菜学习Winform(四)MDI窗体(附示例)
前言 在做winfrom项目的时候我们可能会用到嵌套窗体,就是说一个容器中有多个窗体,可以分别管理和应用这些窗体,.net中提供了一种机制就是MDI,可能大家都会用,这边就简单的介绍下. 简单应用 w ...
- MDI窗体
1.设置父窗体 使用MDI窗体,需要先将父窗体的IsMdiContainer属性设置为True 2.生成用于MDI子窗体的窗体 1 frmTemp f1 = new frmTemp(); f1.Tex ...
- MDI窗体 的再度思考
早在敲学生管理系统的时候,青山师哥就跟我说过 MDI 窗体 跟 子窗体的事情,当时只是简单的查询.小小的用了一下,没有太在意. 当再次面对着这个东西更深层的时候才想起师哥那句话.“好好研究一下这个东 ...
- C#解决MDI窗体闪屏的方法
最近从师兄手上接了一个C#的项目,需要用到MDI窗体,可是每当我显示子窗体的时候会有一次“闪烁”,很明显,看起来非常不爽,查找许久,知道是每次在show()子窗体的时候都会调用子窗体构造函数重绘窗体, ...
- WPF实现MDI窗体的方法
原文:WPF实现MDI窗体的方法 第一:新建一个类(Class) Win32Native.cs 代码如下: using System; using System.Collections.Generi ...
- 2015.12.14 MDI(多文档窗口结构)设置基本解决,折腾一天,部分解决存在已久的问题。但效果仍不如临时航线的MDI窗体结构。
创建从一个窗口弹出多个子窗口的结构叫MDI窗体结构 如果不按MDI结构管理,最简单的做法是: 在窗体A上添加菜单或按钮,在菜单或按钮事件中添加弹出B窗体代码: B b = new B(); b.sho ...
随机推荐
- 往MySQL数据库datetime类型字段中插入数据库的当前时间
代码: StringBuilder sb = new StringBuilder(); sb.append(" insert into uosdetailfile ("); sb. ...
- 第三章,设置button边框(Android)
这样的方法是通过层叠几个图片实现边框效果. 在res目录下的drawable目录下(没有就新建)建一个xml文件选layer-list. <?xml version="1.0" ...
- Oracle11g登陆sqlplus时一直提示密码错误
我安装oracle的时候有自己设置帐号和密码,我也在服务里的oracleserver中查看了正在运行的用户名,是我注册时填的那个并已开启.但是为什么登陆Sqlplus老是说密码错误呢?我敢肯定密码没有 ...
- vuex mapActions
在组件中使用 this.$store.dispatch('xxx') 分发 action,或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用( ...
- Kafka备忘
官网 http://kafka.apache.org/ 多生产者多消费者 多topic和多分区 多消费者组.每组中消息不能重复消费,组间不影响 启动 RunKafka(){ cd $kafka_hom ...
- 哇哦!恍然大悟般的“share”功能的实现!
有一个问题一直困扰着我,也是我一直没有时间去了解和学习的,那就是前端(移动端)实现分享到微信.QQ好友.QQ空间.新浪微博等等平台的功能实现,虽然之前有做过,但是都是上一个领导自己写好的,我直接拿来用 ...
- 工作总结 用, 隔开数据 后台不可以用 List<string> 接收 get请求直接通过浏览器发请求传数组或者list到后台
旁边的 css js 为项目的 加载 css js 地址 只加载引用的样式 js http://localhost:8736/LinInFoKPI/ExcelPrint?line=&start ...
- PHP面试题及答案解析(6)—PHP网络编程
1.禁用COOKIE后SEESION还能用吗? 可以,COOKIE和SESSION都是用来实现会话机制的,由于http协议是无状态的,所以要想跟踪一个用户在同一个网站之间不同页面的状态,需要有这么一个 ...
- hdu 4417,poj 2104 划分树(模版)归并树(模版)
这次是彻底把划分树搞明确了,与此同一时候发现了模版的重要性.敲代码一个字符都不能错啊~~~ 划分树具体解释:点击打开链接 题意:求一组数列中随意区间不大于h的个数. 这个题的做法是用二分查询 求给定 ...
- URL检测脚本
#!/bin/bash# filename : 8_5_1.sh function usage(){ echo "usage:$0 url" exit 1} function ch ...