source: trunk/src/user32/new/win32wmdichild.cpp@ 750

Last change on this file since 750 was 750, checked in by sandervl, 26 years ago

Added MDI class + ChildWindowFromPointEx by Rene Pronk

File size: 9.3 KB
Line 
1/* $Id: win32wmdichild.cpp,v 1.1 1999-08-31 10:36:23 sandervl Exp $ */
2/*
3 * Win32 MDI Child Window Class for OS/2
4 *
5 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
6 *
7 * Based on Wine (windows\mdi.c) (990815)
8 *
9 * Copyright 1994, Bob Amstadt
10 * 1995,1996 Alex Korobka
11 *
12 * Project Odin Software License can be found in LICENSE.TXT
13 *
14 */
15#include <os2win.h>
16#include <win.h>
17#include <stdlib.h>
18#include <stdio.h>
19#include <string.h>
20#include <stdarg.h>
21#include <assert.h>
22#include <misc.h>
23#include <heapstring.h>
24#include <win32wnd.h>
25#include <win32wmdiclient.h>
26#include <win32wmdichild.h>
27#include <spy.h>
28#include "wndmsg.h"
29#include "hooks.h"
30#include <oslibwin.h>
31#include <oslibutil.h>
32#include <oslibgdi.h>
33#include <oslibres.h>
34#include "oslibdos.h"
35#include <winres.h>
36#include "syscolor.h"
37#include "win32wndhandle.h"
38#include "heapshared.h"
39
40
41//******************************************************************************
42//******************************************************************************
43Win32MDIChildWindow::Win32MDIChildWindow(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
44 : Win32BaseWindow(lpCreateStructA, classAtom, isUnicode)
45{
46}
47//******************************************************************************
48//******************************************************************************
49Win32MDIChildWindow::~Win32MDIChildWindow()
50{
51}
52/**********************************************************************
53 * MDICreateChild
54 */
55HWND Win32MDIChildWindow::createChild(Win32MDIClientWindow *client, LPMDICREATESTRUCTA cs )
56{
57 POINT pos[2];
58 DWORD style = cs->style | (WS_CHILD | WS_CLIPSIBLINGS);
59 HWND hwnd;
60 WORD wIDmenu = client->getFirstChildId() + client->getNrOfChildren();
61 char lpstrDef[]="junk!";
62 Win32MDIChildWindow *maximizedChild, *newchild;
63
64 dprintf(("Win32MDIChildWindow::createChild %i,%i - dim %i,%i, style %08x\n",
65 cs->x, cs->y, cs->cx, cs->cy, (unsigned)cs->style));
66
67 /* calculate placement */
68 calcDefaultChildPos(client, client->incTotalCreated(), pos, 0);
69
70 if (cs->cx == CW_USEDEFAULT || !cs->cx) cs->cx = pos[1].x;
71 if (cs->cy == CW_USEDEFAULT || !cs->cy) cs->cy = pos[1].y;
72
73 if( cs->x == CW_USEDEFAULT )
74 {
75 cs->x = pos[0].x;
76 cs->y = pos[0].y;
77 }
78
79 /* restore current maximized child */
80 if( style & WS_VISIBLE && client->getMaximizedChild() )
81 {
82 if( style & WS_MAXIMIZE )
83 client->SendMessageA(WM_SETREDRAW, FALSE, 0L );
84
85 maximizedChild = client->getMaximizedChild();
86
87 maximizedChild->ShowWindow( SW_SHOWNOACTIVATE );
88
89 if( style & WS_MAXIMIZE )
90 client->SendMessageA(WM_SETREDRAW, TRUE, 0L );
91 }
92
93 /* this menu is needed to set a check mark in MDI_ChildActivate */
94 AppendMenuA(client->getMDIMenu(), MF_STRING ,wIDmenu, lpstrDef );
95
96 client->incNrActiveChildren();
97
98 /* fix window style */
99 if( !(client->getStyle() & MDIS_ALLCHILDSTYLES) )
100 {
101 style &= (WS_CHILD | WS_CLIPSIBLINGS | WS_MINIMIZE | WS_MAXIMIZE |
102 WS_CLIPCHILDREN | WS_DISABLED | WS_VSCROLL | WS_HSCROLL );
103 style |= (WS_VISIBLE | WS_OVERLAPPEDWINDOW);
104 }
105
106 hwnd = ::CreateWindowA(cs->szClass, cs->szTitle, style,
107 cs->x, cs->y, cs->cx, cs->cy, client->getWindowHandle(),
108 (HMENU)wIDmenu, cs->hOwner, cs );
109
110 /* MDI windows are WS_CHILD so they won't be activated by CreateWindow */
111 newchild = (Win32MDIChildWindow *)GetWindowFromHandle(hwnd);
112 if (hwnd && newchild)
113 {
114 newchild->menuModifyItem();
115
116 if( newchild->getStyle() & WS_MINIMIZE && client->getActiveChild()) {
117 newchild->ShowWindow(SW_SHOWMINNOACTIVE);
118 }
119 else
120 {
121 /* WS_VISIBLE is clear if a) the MDI client has
122 * MDIS_ALLCHILDSTYLES style and 2) the flag is cleared in the
123 * MDICreateStruct. If so the created window is not shown nor
124 * activated.
125 */
126 int showflag = newchild->getStyle() & WS_VISIBLE;
127 /* clear visible flag, otherwise SetWindoPos32 ignores
128 * the SWP_SHOWWINDOW command.
129 */
130 newchild->SetWindowLongA(GWL_STYLE, showflag & ~WS_VISIBLE);
131 if(showflag){
132 newchild->SetWindowPos(0, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE );
133
134 /* Set maximized state here in case hwnd didn't receive WM_SIZE
135 * during CreateWindow - bad!
136 */
137
138 if((newchild->getStyle() & WS_MAXIMIZE) && !client->getMaximizedChild() )
139 {
140 client->setMaximizedChild(newchild);
141#if 0
142 MDI_AugmentFrameMenu( ci, w->parent, hwnd );
143 MDI_UpdateFrameText( w->parent, ci->self, MDI_REPAINTFRAME, NULL );
144#endif
145 }
146 }
147 else
148 /* needed, harmless ? */
149 newchild->SetWindowPos(0, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE );
150
151 }
152 }
153 else
154 {
155 client->decNrActiveChildren();
156 DeleteMenu(client->getMDIMenu(), wIDmenu,MF_BYCOMMAND);
157
158 maximizedChild = client->getMaximizedChild();
159 if( maximizedChild && maximizedChild->IsWindow() )
160 maximizedChild->ShowWindow(SW_SHOWMAXIMIZED);
161 }
162 return hwnd;
163}
164/**********************************************************************
165 * MDI_MenuModifyItem
166 */
167BOOL Win32MDIChildWindow::menuModifyItem()
168{
169 Win32MDIClientWindow *client = (Win32MDIClientWindow *)getParent();
170 char buffer[128];
171 UINT n = sprintf(buffer, "%d ", getWindowId() - client->getFirstChildId() + 1);
172 BOOL bRet = 0;
173
174 if( !client->getMDIMenu() )
175 {
176 return FALSE;
177 }
178
179 if (getWindowNameA()) lstrcpynA(buffer + n, getWindowNameA(), sizeof(buffer) - n );
180
181 n = GetMenuState(client->getMDIMenu(), getWindowId() ,MF_BYCOMMAND);
182 bRet = ModifyMenuA(client->getMDIMenu() , getWindowId(),
183 MF_BYCOMMAND | MF_STRING, getWindowId(), buffer );
184 CheckMenuItem(client->getMDIMenu(), getWindowId() , n & MF_CHECKED);
185
186 return bRet;
187}
188
189/**********************************************************************
190 * MDI_MenuDeleteItem
191 */
192BOOL Win32MDIChildWindow::menuDeleteItem()
193{
194 Win32MDIClientWindow *client = (Win32MDIClientWindow *)getParent();
195 char buffer[128];
196 UINT index = 0,id,n;
197 BOOL retvalue;
198
199 if( !client->getNrOfChildren() ||
200 !client->getMDIMenu())
201 {
202 return FALSE;
203 }
204
205 id = getWindowId();
206 DeleteMenu(client->getMDIMenu(),id,MF_BYCOMMAND);
207
208 /* walk the rest of MDI children to prevent gaps in the id
209 * sequence and in the menu child list */
210
211 for( index = id+1; index <= client->getNrOfChildren() +
212 client->getFirstChildId(); index++ )
213 {
214 Win32MDIChildWindow *tmpWnd = client->getChildByID(index);
215 if( !tmpWnd )
216 {
217 dprintf(("no window for id=%i\n",index));
218 continue;
219 }
220
221 /* set correct id */
222 tmpWnd->setWindowId(tmpWnd->getWindowId()-1);
223
224 n = sprintf(buffer, "%d ",index - client->getFirstChildId());
225 if (tmpWnd->getWindowNameA())
226 lstrcpynA(buffer + n, tmpWnd->getWindowNameA(), sizeof(buffer) - n );
227
228 /* change menu */
229 ModifyMenuA(client->getMDIMenu(), index ,MF_BYCOMMAND | MF_STRING,
230 index - 1 , buffer );
231 }
232 return TRUE;
233}
234/**********************************************************************
235 * MDI_CalcDefaultChildPos
236 *
237 * It seems that the default height is about 2/3 of the client rect
238 */
239void Win32MDIChildWindow::calcDefaultChildPos(Win32MDIClientWindow *client, WORD n, LPPOINT lpPos, INT delta)
240{
241 INT nstagger;
242 RECT rect = *client->getClientRect();
243 INT spacing = GetSystemMetrics(SM_CYCAPTION) +
244 GetSystemMetrics(SM_CYFRAME) - 1;
245
246 if( rect.bottom - rect.top - delta >= spacing )
247 rect.bottom -= delta;
248
249 nstagger = (rect.bottom - rect.top)/(3 * spacing);
250 lpPos[1].x = (rect.right - rect.left - nstagger * spacing);
251 lpPos[1].y = (rect.bottom - rect.top - nstagger * spacing);
252 lpPos[0].x = lpPos[0].y = spacing * (n%(nstagger+1));
253}
254
255/**********************************************************************
256 * MDI_ChildGetMinMaxInfo
257 *
258 * Note: The rule here is that client rect of the maximized MDI child
259 * is equal to the client rect of the MDI client window.
260 */
261void Win32MDIChildWindow::childGetMinMaxInfo(MINMAXINFO* lpMinMax )
262{
263 Win32MDIClientWindow *client = (Win32MDIClientWindow *)getParent();
264 RECT rect = *client->getClientRect();
265
266 if(client->getParent() == NULL) {
267 dprintf(("Win32MDIChildWindow::childGetMinMaxInfo:: client parent == NULL!!"));
268 return;
269 }
270 MapWindowPoints(client->getParent()->getWindowHandle(), client->getWindowHandle(), (LPPOINT)&rect, 2);
271
272 AdjustWindowRectEx( &rect, getStyle(), 0, getExStyle());
273
274 lpMinMax->ptMaxSize.x = rect.right -= rect.left;
275 lpMinMax->ptMaxSize.y = rect.bottom -= rect.top;
276
277 lpMinMax->ptMaxPosition.x = rect.left;
278 lpMinMax->ptMaxPosition.y = rect.top;
279}
280
281//******************************************************************************
282//******************************************************************************
283
Note: See TracBrowser for help on using the repository browser.