<HTML>
<LINK HREF="style.css" REL="STYLESHEET" TYPE="text/css">
<HEAD>
<TITLE>App Part 4: Multiple Document Interface</TITLE>
</HEAD>
<BODY>
<FONT SIZE="-1">
[ <A HREF="./index.html">contents</A>
| <A HREF="http://www.winprog.org/">#winprog</A>
]
</FONT>
<HR>
<H1>App Part 4: Multiple Document Interface</H1>
<P>Example: app_four</P>
<IMG SRC="images/app_four.gif" ALT="[images/app_four.gif]" ALIGN="right">
<H2>MDI Overview</H2>
First a bit of background... Every window has a <I>Client Area</I>, this is
where most programs draw images, place controls etc... the Client Area is not
seperate from the window itself, it is simply a smaller specialised region
of it. Sometimes a window can be all client area, and nothing else, sometimes
the client area is smaller to make room for menus, titles, scrollbars, etc...
<P>
In MDI terms, your main window is called the Frame, this is probably the
only window you would have in a SDI (Single Document Interface) program.
In MDI there is an additional window, called the <I>MDI Client Window</I>
which is a child of your Frame window.
Unlike the <I>Client Area</I> it is a complete and seperate window all on it's
own, it has a client area of it's own and probably a few pixels for a border.
You never directly handle messages for the MDI Client, it is done by the
pre-defined windows class <CODE>"MDICLIENT"</CODE>. You can communicate with
and manipulate the MDI Client and the windows it contains through messages.
<P>
When it comes to the windows which actually display your document or
whatever your program displays, you send a message to the MDI Client to tell it to create a new
window of the type you've specified. The new window is created as a child of
the MDI Client, not of your Frame window. This new window is an MDI Child.
The MDI Child is a child of the MDI Client, which in turn is a child of the
MDI Frame (Getting dizzy yet?). To make matters worse, the MDI Child will
probably have child windows of its own, for instance the edit control in the
example program for this section.
<P>
You are responsable for writing two (or more) Window Procedures. One, just like
always, for your main window(the Frame). And one more for the MDI Child. You may also
have more than one type of Child, in which case, you'll want a seperate window
procedure for each type.
<P>
If I've thoroughly confused you now talking about MDI Clients and things, this diagram
may clear things up a little better:
<P ALIGN="CENTER">
<IMG SRC="images/mdi_diagram.gif" ALT="[images/mdi_diagram.gif]" BORDER="1">
</P>
<H2>Getting Started with MDI</H2>
MDI requires a few subtle changes throughout a program, so please read through this section
carefully... chances are that if your MDI program doesn't work or has strange behaviour
it's because you missed one of the alterations from a regular program.
<H3>MDI Client Window</H3>
Before we create our MDI window we need to make a change to the default message processing
that goes on in our Window Procedure... since we're creating a Frame window that will
host an MDI Client, we need to change the <CODE>DefWindowProc()</CODE> call to <CODE>DefFrameProc()</CODE> which adds
specialized message handling for Frame Windows,
<PRE CLASS="SNIP">
default:
return DefFrameProc(hwnd, g_hMDIClient, msg, wParam, lParam);
</PRE>
The next step is to create the MDI Client window itself, as a child of our frame window.
We do this in <CODE>WM_CREATE</CODE> as usual...
<PRE CLASS="SNIP">
CLIENTCREATESTRUCT ccs;
ccs.hWindowMenu = GetSubMenu(GetMenu(hwnd), 2);
ccs.idFirstChild = ID_MDI_FIRSTCHILD;
g_hMDIClient = CreateWindowEx(WS_EX_CLIENTEDGE, "mdiclient", NULL,
WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
hwnd, (HMENU)IDC_MAIN_MDI, GetModuleHandle(NULL), (LPVOID)&ccs);
</PRE>
The menu handle is the handle to the popup menu that the MDI client will add items to
representing each window that is created, allowing the user to select the window they want
to activate from the menu, we'll add functionality shortly to handle this case. In this example
it's the 3rd popup (index 2) since I've added Edit and Window to the menu after File.
<P>
<CODE>ccs.idFirstChild</CODE> is a number to use as the first ID for the items
the Client adds to the Window menu... you want this to be easily
distinguishable from your own menu identifiers so you can handle your menu commands
and pass the Window menu commands to <CODE>DefFrameProc()</CODE> for processing. In the
example I specify an identifier defined as <CODE>50000</CODE>, high enough that I know none
of my menu command id's will be above it.
<P>
Now to get this menu to work properly we need to add some special handling to our
<CODE>WM_COMMAND</CODE> handler:
<PRE CLASS="SNIP">
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_FILE_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0);
break;
// ... handle other regular IDs ...
// Handle MDI Window commands
default:
{
if(LOWORD(wParam) >= ID_MDI_FIRSTCHILD)
{
DefFrameProc(hwnd, g_hMDIClient, msg, wParam, lParam);
}
else
{
HWND hChild = (HWND)SendMessage(g_hMDIClient, WM_MDIGETACTIVE,0,0);
if(hChild)
{
SendMessage(hChild, WM_COMMAND, wParam, lParam);
}
}
}
}
break;
</PRE>
<P>
I've added a <CODE>default:</CODE> case which will catch all commands that I didn't process
directly and do a check to see if the value is greater than or equal to <CODE>ID_MDI_FIRSTCHILD</CODE>.
If it is, then the user has clicked on one of the Window menu items and we send
the message on to <CODE>DefFrameProc()</CODE> for processing.
<P>
If it isn't one of the Window
IDs then I get the handle to the active child window and forward the message
to it for processing. This allows you to delegate responsibility to the Child
windows for performing certain actions, and allows different child windows
to handle commands in different ways if so desired. In the example I only
handle commands that are global to the program in the Frame window procedure,
and send the commands which affect a certain document or child window on to the
child window itself for processsing.
<P>
Since we're building on the last example, the code to size the MDI client is the same as
the code to resize the edit control in the last example, that takes into account the size
and position of the tool and status bars so they don't overlap the MDI client window.
<P>
We also need to modify our message loop a little...
<PRE CLASS="SNIP">
while(GetMessage(&Msg, NULL, 0, 0))
{
if (!TranslateMDISysAccel(g_hMDIClient, &Msg))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
</PRE>
We've added an extra step (<CODE>TranslateMDISysAccel()</CODE>), that checks for the
pre-defined accelerator keys, Ctrl+F6 which swtiches to the next window, Ctrl+F4 which closes the Child
and so on. If you don't add in this check you will annoy your users by not
providing the standard behaviour they've gotten used to, or you'll have to
implement it manually.
<H3>Child Window Class</H3>
In addition to the main window of the program (the Frame window) we need to create new
window classes for each type of child window we want. For example you might have one
to display text, and one to display a picture or graph. In this example we'll only
be creating one child type, which will be just like the editor program in the previous
examples.
<PRE CLASS="SNIP">
BOOL SetUpMDIChildWindowClass(HINSTANCE hInstance)
{
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.st
没有合适的资源?快使用搜索试试~ 我知道了~
基于C++的WIN32 API
共45个文件
html:25个
gif:17个
css:1个
3星 · 超过75%的资源 需积分: 50 7 下载量 119 浏览量
2009-06-29
09:20:02
上传
评论
收藏 707KB ZIP 举报
温馨提示
一个老外总结的WIN32 API ,是基于C++的,很好,比较适合学习VC的人使用
资源推荐
资源详情
资源评论
收起资源包目录
Win32API学习资料(C++),很好.zip (45个子文件)
tutorial
window_click.html 9KB
animation.html 9KB
simple_window.html 16KB
errors.html 6KB
app_two.html 11KB
dlgfaq.html 7KB
modeless_dialogs.html 7KB
resources.html 7KB
transparency.html 11KB
fonts.html 14KB
references.html 4KB
start.html 7KB
resnotes.html 4KB
msvc.html 3KB
app_one.html 7KB
dialogs.html 10KB
bitmaps.html 13KB
bcpp.html 6KB
images
mdi_diagram.gif 28KB
app_two.jpg 18KB
app_three.gif 7KB
app_four.gif 8KB
font_one.gif 5KB
pocketirc.gif 8KB
button_close.gif 898B
bmp_one.gif 3KB
simple_window.gif 4KB
window_click.gif 7KB
menu_one.gif 4KB
dlg_one.gif 8KB
app_one.gif 5KB
ctl_one.gif 7KB
dlg_three.gif 4KB
bmp_two.gif 4KB
anim_one.gif 4KB
dlg_two.gif 6KB
controls.html 13KB
menus.html 11KB
index.html 6KB
app_three.html 9KB
message_loop.html 11KB
app_four.html 17KB
style.css 485B
files
source.zip 483KB
apivsmfc.html 6KB
共 45 条
- 1
资源评论
- zerocleaner2012-11-18这是基于C的,还有些汇编。但是还能用,谢谢分享。
- tyuck2012-10-15很详细,找到我需要的
GZ22043786
- 粉丝: 31
- 资源: 29
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功