给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 ...
随机推荐
- IntelliJ IDEA 快捷键整理-from imooc
IntelliJ IDEA 快捷键整理-from imooc 学习了:https://www.imooc.com/learn/9241, main2, 100.for 3, new Date().so ...
- javascript - 活动倒计时(天、时、分、秒)
计数时: 结束时: 示例: <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- [转]Tomcat工作原理详解
一.Tomcat背景 自从JSP发布之后,推出了各式各样的JSP引擎.Apache Group在完成GNUJSP1.0的开发以后,开始考虑在SUN的JSWDK基础上开发一个可以直接提供Web服务的JS ...
- java jdk 环境变量设置
我的电脑点右键,选择“属性”,选择“高级”标签,进入环境变量设置,分别设置如下三个环境变量: 设置JAVA_HOME: 一是为了方便引用,比如,JDK安装在C:\jdk1.6.0目录里,则设置JAVA ...
- C# const和static readonly区别
[转]C# const和static readonly区别 以前只是知道Const和static readonlyd的区别在于const的值是在编译期间确定的,而static readonly是在运行 ...
- svn client命令
经常使用svn命令说明 1.从SVN仓库中检索出代码到工作拷贝: # svn checkout https://svn.sinaapp.com/appname [workcopy] 当中workcop ...
- 本地文件上传到linux
首先下载插件,输入下面命令: yum -y install lrzsz 然后输入rz选择上传文件: rz 如果rz命令不好使的话,就输入: rz -be
- Linux下安装jdk8的方法
一.yum安装 只需要一条命令就可以安装jdk: yum install java--openjdk* -y 执行过这条命令无需配置,直接可以使用. 二.下载tar包安装 下载jdk8 登录网址:ht ...
- centos7 中文输入法设置
安装centos7 后,他有自带的中文输入法安装包找到 applications->systemTools->settings->region&language 2:在 in ...
- [译]GLUT教程 - 整合代码7
Lighthouse3d.com >> GLUT Tutorial >> Extras >> The Code So Far VII 以下是子窗体的最终版本代码. ...