WEB开发网
开发学院软件开发汇编语言 汇编教程:多文档界面(MDI) 阅读

汇编教程:多文档界面(MDI)

 2008-10-14 09:35:18 来源:WEB开发网   
核心提示:现在我们将注意力放到细节上来.首先你需要创建框架窗口. 创建框架窗口的方法和普通窗口是相同的:调用CreateWindowEx. 和普通窗口相比,有两个主要的不同.第一个不同是你必须调用DefFrameProc来处理你的窗口不想处理的窗口信息而不是调用DefWindowProc.这是让Windows为你作的保持一个MD

现在我们将注意力放到细节上来.首先你需要创建框架窗口. 创建框架窗口的方法和普通窗口是相同的:调用CreateWindowEx. 和普通窗口相比,有两个主要的不同.

第一个不同是你必须调用DefFrameProc来处理你的窗口不想处理的窗口信息而不是调用DefWindowProc.这是让Windows为你作的保持一个MDI应用程序的垃圾任务的一个方法.假如你忘记使用DefFrameProc,你的应用程序将不具有MDI的功能. DefFrameProc具有下列语法:

DefFrameProc proc hwndFrame:DWORD,
hwndClient:DWORD,
uMsg:DWORD,
wParam:DWORD,
lParam:DWORD

假如你将 DefFrameProc 和 DefWindowProc作一个对比,你将会注意到它们之间的唯一的不同在于DefFrameProc有5个参数,而DefWindowProc只有4个.这个增加的参数是客户窗口的句柄.这个句柄是必须的,有了它Windows才可以发送MDI-相关的消息给客户窗口.

第二个不同是你必须在你的框架窗口的消息循环中调用 TranslateMDISysAccel .假如你希望Windows为你处理MDI相关的加速键,比如Ctrl+F4,Ctrl+Tab,那么这是必须的.它具有下列语法:

TranslateMDISysAccel proc hwndClient:DWORD,

lpMsg:DWORD

第一个参数是客户窗口的句柄.对此你应该不会觉得惊讶.因为客户窗口是所有MDI子窗口的父亲. 第二个参数是你通过调用GetMessage获得的MSG框架的地址. 我们的想法是传递MSG结构给客户窗口,这样客户窗口可以检测在MSG结构中所包含的MDI相关的按键是不是按下去了.假如是的话, 客户窗口处理这个信息,然后返回一个非零值,否则返回一个假值..

创建框架窗口的步骤总结如下:

像平常一样填写 WNDCLASSEX 结构.

通过调用 RegisterClassEx注册框架窗口类.
  通过调用CreateWindowEx创建框架窗口.

在消息循环中调用TranslateMDISysAccel.

在窗口过程中,将未处理的消息传递给 DefFrameProc 而不是DefWindowProc.

创建客户窗口

现在我们有了框架窗口,我们可以开始创建客户窗口了. 客户窗口类是由Windows预先注册的. 类的名称为"MDICLIENT". 你同样也需要将 CLIENTCREATESTRUCT 的地址传递给 CreateWindowEx. 这个结构具有以下定义:

CLIENTCREATESTRUCT struct
hWindowMenu dd ?
idFirstChild dd ?
CLIENTCREATESTRUCT ends

hWindowMenu 是子菜单的句柄,这个子菜单显示Windows将要添加的MDI子窗口名称列表. 我们需要对这一功能进行一点解释.假如你以前曾经使用过类似Microsoft Word的MDI 应用程序,你将会注意到有一个名称为"窗口"的子菜单. 这个菜单一旦激活的话,将会在底部显示出和窗口管理相关的各种各样的菜单项, 还有当前打开的MDI子窗口的列表. 这个列表是由Windows自己内部保持的. 你不需要为它作任何特殊的事情. 仅仅只在需要在hWindowMenu 中传递你所希望显示列表的子菜单的句柄, Windows 将会处理剩下的事情. 注意这个子菜单可以是任何的子菜单:它并不一定要是名称为"窗口"的子菜单. 重要的是你应该传递你希望显示窗口列表的子菜单的句柄. 假如你不想要这个列表,你就给 hWindowMenu 赋一个NULL的值就行了. 你可以通过调用GetSubMenu来获得子菜单的句柄.

idFirstChild 是第一个MDI子窗口的标识号. Windows为应用程序所创建的每一个新的MDI子窗口相应的增加标识号. 举个例子, 假如你传递100给这个域, 第一个MDI子窗口将会有一个值为100的标识符, 那么第二个MDI子窗口也就会有一个值为101的标识符, 如此这样下去. 当从窗口列表中选择MDI子窗口时, 被选择的MDI子窗口的标识符通过WM_COMMAND传递给框架窗口. 正常情况下,你将传递"未处理"的WM_COMMAND消息给DefFrameProc. 我用"未处理"这个词语,是因为窗口列表中的菜单项不是由你的应用程序创建的, 这样你的应用程序不知道它们的标识符,而且也没有它们的句柄. 这是MDI框架窗口又一个特殊的地方. 假如你有窗口列表的话,你必须像这样来修改你的WM_COMMAND句柄:

.elseif uMsg==WM_COMMAND
.if lParam==0 ; 这条消息是由菜单产生的
mov eax,wParam
.if ax==IDM_CASCADE
.....
.elseif ax==IDM_TILEVERT
.....
.else
invoke DefFrameProc, hwndFrame, hwndClient, uMsg,wParam, lParam
ret
.endif

一般来说,你可以忽略未处理的消息. 但是在MDI的情况下,如果你忽略它们, 当用户点击窗口列表中的一个MDI子窗口的名称时,,这个窗口不会被激活. 你需要将这些消息传递给DefFrameProc 这样它们才会得到适当的处理.

idFirstChild 赋值的注意之处: 你不能使用0. 你窗口列表将会表现的不正常. 举个例子, 即使某一个MDI子窗口被激活的话, 窗口列表中的这个MDI子窗口名字前的复选标记也不会显现. 我们可以选择一个安全的值,比如100或是一个比100大的值.

给 CLIENTCREATESTRUCT 结构赋值后,你可以通过调用 CreateWindowEx 用预先注册好的类名"MDICLIENT", 在lParam中传递CLIENTCREATESTRUCT结构的地址来创建客户窗口. 你同样需要在hWndParent参数中指定框架窗口的句柄, 这样Windows才可以知道框架窗口和客户窗口之间的父-子关系. 你可以使用的窗口风格有:WS_CHILD ,WS_VISIBLEHE WS_CLIPCHILDREN . 假如你忘了WS_VISIBLE的话, 即使MDI子窗口成功地创建了,你也看不到它们.

以下是创建客户窗口的步骤:

获取你所希望显示窗口列表的子菜单的句柄.

将这个菜单句柄的值和你希望作为第一个MDI子窗口标识符的值一起传送给CLIENTCREATESTRUCT 结构.

调用 CreateWindowEx 用类名"MDICLIENT" ,lParam参数为CLIENTCREATESTRUCT结构的地址,

创建MDI子窗口
  现在我们既有了框架窗口,也有了客户窗口. 下一阶段可以开始创建MDI子窗口了.有两种方法:

你可以发送 WM_MDICREATE消息给客户窗口,在wParam参数中传递类型MDICREATESTRUCT的结构的地址. 这是常用的也是最简单的MDI子窗口的创建方法.

.data?
mdicreate MDICREATESTRUCT <>
....
.code
.....
[fill the members of mdicreate]
......
invoke SendMessage, hwndClient, WM_MDICREATE,addr mdicreate,0

上一页  1 2 3 4 5 6  下一页

Tags:汇编 教程 文档

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接