home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Boston 2
/
boston-2.iso
/
DOS
/
PROGRAM
/
C
/
MDIDEMO
/
MDIDEMO.C
next >
Wrap
C/C++ Source or Header
|
1993-12-01
|
22KB
|
672 lines
/*--------------------------------------------------------
MDIDEMO.C -- Multiple Document Interface Demonstration
(c) Charles Petzold, 1990
Windows SDK V. 3.0
Microsoft C V. 6.0
Windows V. 3.0
--------------------------------------------------------*/
#if defined(_MEWEL_)
#include <stdlib.h>
#include <string.h>
#include "window.h"
#undef _CreateWindow
#define LOCALHANDLE VOID *
#define GLOBALHANDLE VOID *
#define GetWindowLOCALHANDLE GetWindowPtr
#define SetWindowLOCALHANDLE SetWindowPtr
#define GetWindowGLOBALHANDLE GetWindowPtr
#define SetWindowGLOBALHANDLE SetWindowPtr
int PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
// main
//
void main(int argc, char *argv[])
{
extern USHORT _amblksiz;
register int i;
char achCmdLine[128];
_amblksiz = 16;
strcpy (achCmdLine, "");
for (i=1 ; i<argc ; i++)
{
strcat (achCmdLine, argv[i]);
}
WinInit();
WinUseSysColors(NULLHWND, TRUE);
MDIInitialize();
exit (WinMain (0, 0, achCmdLine, SW_SHOW));
}
// _CreateWindow
//
HWND FAR PASCAL _CreateWindow(
LPSTR lpClassName,
LPSTR lpWindowName,
DWORD dwStyle,
int X,
int Y,
int nWidth,
int nHeight,
HWND hwndParent,
HMENU hMenu,
HANDLE hInstance,
LPSTR lpParam
)
{
HMENU hmenu;
USHORT usChildID;
HWND hwnd;
if (dwStyle & WS_CHILD)
{
usChildID = (USHORT) hMenu;
hmenu = (HMENU) NULL;
}
else
{
usChildID = 0;
hmenu = hMenu;
}
hwnd = CreateWindow(
lpClassName, // Window class name
lpWindowName, // Window caption
dwStyle, // Window style
X, // Initial x position
Y, // Initial y position
nWidth, // Initial x size
nHeight, // Initial y size
SYSTEM_COLOR, // Screen colors
(USHORT) usChildID, // Child ID
(HWND) hwndParent, // Parent window handle
(HMENU) hmenu, // Window menu handle
(HANDLE) hInstance, // Program instance handle
(LPSTR)lpParam // Create parameters
);
return (hwnd);
}
#else
#include <windows.h>
#define _CreateWindow CreateWindow
#define _DialogBox DialogBox
#define _TranslateAccelerator TranslateAccelerator
#define GetWindowLOCALHANDLE GetWindowWord
#define SetWindowLOCALHANDLE SetWindowWord
#define GetWindowGLOBALHANDLE GetWindowWord
#define SetWindowGLOBALHANDLE SetWindowWord
#endif
#include <memory.h>
#include <stdlib.h>
#include "mdidemo.h"
long FAR PASCAL FrameWndProc (HWND, WORD, WORD, LONG) ;
BOOL FAR PASCAL CloseEnumProc (HWND, LONG) ;
long FAR PASCAL HelloWndProc (HWND, WORD, WORD, LONG) ;
long FAR PASCAL RectWndProc (HWND, WORD, WORD, LONG) ;
// structure for storing data unique to each Hello child window
typedef struct
{
short nColor ;
#if defined(_MEWEL_)
WORD clrText ; /* colors are words */
#else
COLORREF clrText ;
#endif
}
HELLODATA ;
typedef HELLODATA *NPHELLODATA ;
// structure for storing data unique to each Rect child window
typedef struct
{
short cxClient ;
short cyClient ;
}
RECTDATA ;
typedef RECTDATA *NPRECTDATA ;
// global variables
char szFrameClass [] = "MdiFrame" ;
char szHelloClass [] = "MdiHelloChild" ;
char szRectClass [] = "MdiRectChild" ;
HANDLE hInst ;
HMENU hMenuInit, hMenuHello, hMenuRect ;
HMENU hMenuInitWindow, hMenuHelloWindow, hMenuRectWindow ;
HWND hwndFrame, hwndClient ;
int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
HANDLE hAccel ;
MSG msg ;
WNDCLASS wndclass ;
hInst = hInstance ;
if (!hPrevInstance)
{
// Register the frame window class
memset (&wndclass, 0, sizeof (wndclass));
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = FrameWndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = COLOR_APPWORKSPACE + 1 ;
wndclass.lpszMenuName = "MdiMenuInit" ;
wndclass.lpszClassName = szFrameClass ;
RegisterClass (&wndclass) ;
// Register the Hello child window class
memset (&wndclass, 0, sizeof (wndclass));
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = HelloWndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = sizeof (LOCALHANDLE) ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szHelloClass ;
RegisterClass (&wndclass) ;
// Register the Rect child window class
memset (&wndclass, 0, sizeof (wndclass));
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = RectWndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = sizeof (LOCALHANDLE) ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = NULL ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szRectClass ;
RegisterClass (&wndclass) ;
}
// Create the frame window
hwndFrame = _CreateWindow (
szFrameClass,
"MDI Demonstration",
WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
hwndClient = GetWindow (hwndFrame, GW_CHILD) ;
ShowWindow (hwndFrame, (BOOL) nCmdShow) ;
UpdateWindow (hwndFrame) ;
SetFocus(hwndFrame);
#if defined(_MEWEL_)
MessageBox(hwndFrame,
"Just so you know...\n\
MEWEL does not do complex cliiping in the Rectangle() function, so the\n\
rectangles drawn in a child window will paint over any overlapping\n\
windows. But, since this is domain of a graphical-oriented window system\n\
and not MEWEL, it shouldn't affect any normal MEWEL apps.",
"Warning", MB_OK);
#endif
// Enter the modified message loop
while (GetMessage (&msg, NULL, 0, 0))
{
if (!TranslateMDISysAccel (hwndClient, &msg) &&
!_TranslateAccelerator (hwndFrame, hAccel, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
return msg.wParam ;
}
long FAR PASCAL FrameWndProc (HWND hwnd, WORD message,
WORD wParam, LONG lParam)
{
CLIENTCREATESTRUCT clientcreate ;
FARPROC lpfnEnum ;
HWND hwndChild, hwndNext ;
MDICREATESTRUCT mdicreate ;
switch (message)
{
case WM_CREATE: // Create the client window
// Obtain handles to three possible menus & submenus
hwndFrame = hwnd;
hMenuInit = LoadMenu (hInst, "MdiMenuInit") ;
hMenuHello = LoadMenu (hInst, "MdiMenuHello") ;
hMenuRect = LoadMenu (hInst, "MdiMenuRect") ;
hMenuInitWindow = GetSubMenu (hMenuInit, INIT_MENU_POS) ;
hMenuHelloWindow = GetSubMenu (hMenuHello, HELLO_MENU_POS) ;
hMenuRectWindow = GetSubMenu (hMenuRect, RECT_MENU_POS) ;
clientcreate.hWindowMenu = hMenuInitWindow ;
clientcreate.idFirstChild = IDM_FIRSTCHILD ;
hwndClient = _CreateWindow (
"MDICLIENT",
NULL,
WS_CHILD
| WS_CLIPCHILDREN
| WS_VISIBLE,
0,
0,
0,
0,
hwnd,
1,
hInst,
(LPSTR) &clientcreate
) ;
return 0 ;
case WM_COMMAND:
switch (wParam)
{
case IDM_NEWHELLO: // Create a Hello child window
mdicreate.szClass = szHelloClass ;
mdicreate.szTitle = "Hello" ;
mdicreate.hOwner = hInst ;
mdicreate.x = CW_USEDEFAULT ;
mdicreate.y = CW_USEDEFAULT ;
mdicreate.cx = CW_USEDEFAULT ;
mdicreate.cy = CW_USEDEFAULT ;
mdicreate.style = 0 ;
mdicreate.lParam = NULL ;
hwndChild = (HWND) SendMessage(hwndClient, WM_MDICREATE, 0,
(LONG) (LPMDICREATESTRUCT) &mdicreate) ;
return 0 ;
case IDM_NEWRECT: // Create a Rect child window
mdicreate.szClass = szRectClass ;
mdicreate.szTitle = "Rectangles" ;
mdicreate.hOwner = hInst ;
mdicreate.x = CW_USEDEFAULT ;
mdicreate.y = CW_USEDEFAULT ;
mdicreate.cx = CW_USEDEFAULT ;
mdicreate.cy = CW_USEDEFAULT ;
mdicreate.style = 0 ;
mdicreate.lParam = NULL ;
hwndChild = (HWND) SendMessage(hwndClient, WM_MDICREATE, 0,
(LONG) (LPMDICREATESTRUCT) &mdicreate) ;
return 0 ;
case IDM_CLOSE: // Close the active window
hwndChild = LOWORD (SendMessage (hwndClient,
WM_MDIGETACTIVE, 0, 0L)) ;
if (SendMessage (hwndChild, WM_QUERYENDSESSION, 0, 0L))
SendMessage (hwndClient, WM_MDIDESTROY,
hwndChild, 0L) ;
return 0 ;
case IDM_EXIT: // Exit the program
SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
return 0 ;
// Messages for arranging windows
case IDM_TILE:
SendMessage (hwndClient, WM_MDITILE, 0, 0L) ;
return 0 ;
case IDM_CASCADE:
SendMessage (hwndClient, WM_MDICASCADE, 0, 0L) ;
return 0 ;
case IDM_ARRANGE:
SendMessage (hwndClient, WM_MDIICONARRANGE, 0, 0L) ;
return 0 ;
case IDM_CLOSEALL: // Attempt to close all children
lpfnEnum = MakeProcInstance (CloseEnumProc, hInst) ;
EnumChildWindows (hwndClient, lpfnEnum, 0L) ;
FreeProcInstance (lpfnEnum) ;
return 0 ;
default: // Pass to active child
hwndChild = LOWORD (SendMessage (hwndClient,
WM_MDIGETACTIVE, 0, 0L)) ;
if (IsWindow (hwndChild))
SendMessage (hwndChild, WM_COMMAND,
wParam, lParam) ;
break ; // and then to DefFrameProc
}
break ;
case WM_QUERYENDSESSION:
case WM_CLOSE: // Attempt to close all children
SendMessage (hwnd, WM_COMMAND, IDM_CLOSEALL, 0L) ;
if (NULL != GetWindow (hwndClient, GW_CHILD))
return 0 ;
break ; // ie, call DefFrameProc ;
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
// Pass unprocessed msgs to DefFrameProc (not DefWindowProc)
return DefFrameProc (hwnd, hwndClient, message, wParam, lParam) ;
}
BOOL FAR PASCAL CloseEnumProc (HWND hwnd, LONG lParam)
{
if (GetWindow (hwnd, GW_OWNER)) // check for icon title
return 1 ;
SendMessage (GetParent (hwnd), WM_MDIRESTORE, hwnd, 0L) ;
if (!SendMessage (hwnd, WM_QUERYENDSESSION, 0, 0L))
return 1 ;
SendMessage (GetParent (hwnd), WM_MDIDESTROY, hwnd, 0L) ;
return 1 ;
}
long FAR PASCAL HelloWndProc (HWND hwnd, WORD message,
WORD wParam, LONG lParam)
{
#if defined(_MEWEL_)
static WORD clrTextArray [] = /* colors are words */
{ BLACK,
RED,
GREEN,
BLUE,
WHITE } ;
#else
static COLORREF clrTextArray [] =
{ RGB ( 0, 0, 0),
RGB (255, 0, 0),
RGB ( 0, 255, 0),
RGB ( 0, 0, 255),
RGB (255, 255, 255) } ;
#endif
HDC hdc ;
HMENU hMenu ;
LOCALHANDLE hHelloData ;
NPHELLODATA npHelloData ;
PAINTSTRUCT ps ;
RECT rect ;
switch (message)
{
case WM_CREATE:
// Allocate memory for window private data
hHelloData = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT,
sizeof (HELLODATA)) ;
npHelloData = (NPHELLODATA) LocalLock (hHelloData) ;
npHelloData->nColor = IDM_BLACK ;
npHelloData->clrText = RGB (0, 0, 0) ;
LocalUnlock (hHelloData) ;
SetWindowLOCALHANDLE (hwnd, 0, hHelloData) ;
// Save some window handles
hwndClient = GetParent (hwnd) ;
hwndFrame = GetParent (hwndClient) ;
return 0 ;
case WM_COMMAND:
switch (wParam)
{
case IDM_BLACK:
case IDM_RED:
case IDM_GREEN:
case IDM_BLUE:
case IDM_WHITE:
// Change the text color
hHelloData = GetWindowLOCALHANDLE (hwnd, 0) ;
npHelloData = (NPHELLODATA) LocalLock (hHelloData) ;
hMenu = GetMenu (hwndFrame) ;
CheckMenuItem (hMenu, npHelloData->nColor,
MF_UNCHECKED) ;
npHelloData->nColor = wParam ;
CheckMenuItem (hMenu, npHelloData->nColor,
MF_CHECKED) ;
npHelloData->clrText =
clrTextArray [wParam - IDM_BLACK] ;
LocalUnlock (hHelloData) ;
InvalidateRect (hwnd, NULL, FALSE) ;
break;
}
return 0 ;
case WM_PAINT:
// Paint the window
hdc = BeginPaint (hwnd, &ps) ;
hHelloData = GetWindowLOCALHANDLE (hwnd, 0) ;
npHelloData = (NPHELLODATA) LocalLock (hHelloData) ;
SetTextColor (hdc, npHelloData->clrText) ;
LocalUnlock (hHelloData) ;
GetClientRect (hwnd, &rect) ;
#if defined(_MEWEL_)
WinClear(hwnd);
TextOut(hdc, 0, 0, "Hello, World!", strlen("Hello, World!"));
#else
DrawText (hdc, "Hello, World!", -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
#endif
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_MDIACTIVATE:
// Set the Hello menu if gaining focus
if (wParam == TRUE)
SendMessage (hwndClient, WM_MDISETMENU, 0,
MAKELONG (hMenuHello, hMenuHelloWindow)) ;
// check or uncheck menu item
hHelloData = GetWindowLOCALHANDLE (hwnd, 0) ;
npHelloData = (NPHELLODATA) LocalLock (hHelloData) ;
CheckMenuItem (hMenuHello, npHelloData->nColor,
wParam ? MF_CHECKED : MF_UNCHECKED) ;
LocalUnlock (hHelloData) ;
// Set the Init menu if losing focus
if (wParam == FALSE)
SendMessage (hwndClient, WM_MDISETMENU, 0,
MAKELONG (hMenuInit, hMenuInitWindow)) ;
DrawMenuBar (hwndFrame) ;
return 0 ;
case WM_QUERYENDSESSION:
case WM_CLOSE:
if (IDOK != MessageBox (hwnd,"OK to close window?","Hello",
MB_ICONQUESTION | MB_OKCANCEL))
return 0 ;
break ; // ie, call DefMDIChildProc
case WM_DESTROY:
hHelloData = GetWindowLOCALHANDLE (hwnd, 0) ;
LocalFree (hHelloData) ;
return 0 ;
}
// Pass unprocessed message to DefMDIChildProc
return DefMDIChildProc (hwnd, message, wParam, lParam) ;
}
long FAR PASCAL RectWndProc (HWND hwnd, WORD message,
WORD wParam, LONG lParam)
{
HPEN hBrush ;
HDC hdc ;
LOCALHANDLE hRectData ;
NPRECTDATA npRectData ;
PAINTSTRUCT ps ;
short xLeft, xRight, yTop, yBottom, nRed, nGreen, nBlue ;
#if defined(_MEWEL_)
RECT rWindow;
#endif
switch (message)
{
case WM_CREATE:
// Allocate memory for window private data
hRectData = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT,
sizeof (RECTDATA)) ;
SetWindowLOCALHANDLE (hwnd, 0, hRectData) ;
// Start the timer going
SetTimer (hwnd, 1, 250, NULL) ;
// Save some window handles
hwndClient = GetParent (hwnd) ;
hwndFrame = GetParent (hwndClient) ;
#if defined(_MEWEL_)
GetClientRect(hwnd, &rWindow);
lParam = MAKELONG(RECT_WIDTH(rWindow), RECT_HEIGHT(rWindow));
/* fall through ... */
#else
return 0 ;
#endif
case WM_SIZE: // Save the window size
hRectData = GetWindowLOCALHANDLE (hwnd, 0) ;
npRectData = (NPRECTDATA) LocalLock (hRectData) ;
npRectData->cxClient = LOWORD (lParam) ;
npRectData->cyClient = HIWORD (lParam) ;
LocalUnlock (hRectData) ;
break ; //WM_SIZE must be processed by DefMDIChildProc
case WM_TIMER: // Display a random rectangle
hRectData = GetWindowLOCALHANDLE (hwnd, 0) ;
npRectData = (NPRECTDATA) LocalLock (hRectData) ;
xLeft = rand () % npRectData->cxClient ;
xRight = rand () % npRectData->cxClient ;
yTop = rand () % npRectData->cyClient ;
yBottom = rand () % npRectData->cyClient ;
#if defined(_MEWEL_)
nRed = rand () % 16;
#else
nRed = rand () & 255 ;
nGreen = rand () & 255 ;
nBlue = rand () & 255 ;
#endif
hdc = GetDC (hwnd) ;
#if defined(_MEWEL_)
hBrush = CreateSolidBrush (nRed) ;
SetBkColor(hdc, hBrush);
#else
hBrush = CreateSolidBrush (RGB (nRed, nGreen, nBlue)) ;
#endif
SelectObject (hdc, hBrush) ;
Rectangle (hdc, min (xLeft, xRight), min (yTop, yBottom),
max (xLeft, xRight), max (yTop, yBottom)) ;
ReleaseDC (hwnd, hdc) ;
DeleteObject (hBrush) ;
LocalUnlock (hRectData) ;
return 0 ;
case WM_PAINT: // Clear the window
InvalidateRect (hwnd, NULL, TRUE) ;
hdc = BeginPaint (hwnd, &ps) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_MDIACTIVATE: // Set the appropriate menu
if (wParam == TRUE)
SendMessage (hwndClient, WM_MDISETMENU, 0,
MAKELONG (hMenuRect, hMenuRectWindow)) ;
else
SendMessage (hwndClient, WM_MDISETMENU, 0,
MAKELONG (hMenuInit, hMenuInitWindow)) ;
DrawMenuBar (hwndFrame) ;
return 0 ;
case WM_DESTROY:
hRectData = GetWindowLOCALHANDLE (hwnd, 0) ;
LocalFree (hRectData) ;
KillTimer (hwnd, 1) ;
return 0 ;
}
// Pass unprocessed message to DefMDIChildProc
return DefMDIChildProc (hwnd, message, wParam, lParam) ;
}