File:  [WindowsNT SDKs] / q_a / samples / ntsd / mdi.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:30:02 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntsdk-nov-1993, ntsdk-jul-1993, HEAD
Microsoft Windows NT Build 511 (SDK Final Release) 07-24-1993

/******************************Module*Header*******************************\
* Module Name: mdi.c
*
* MDI demonstration
*   +   Associating data with a MDI window (using Set/GetWindowLong )
*
* Created: 24-Oct-1991 18:34:08
* Author: Petrus Wong []
*
* Copyright (c) 1990 Microsoft Corporation
*
* Dependencies:
*
*   (#defines)
*   (#includes)
*       MDI.H
*
\**************************************************************************/
#define STRICT
#include <stdlib.h>
#include "mdi.h"
#include <stdarg.h>

HANDLE ghModule;
HWND   ghwndMain   = NULL;
HWND   ghwndClient = NULL;

HMENU  hMenu,	   hMenuWindow;
HMENU  hChildMenu, hChildMenuWindow;

CHAR   gszFile[20];
CHAR   gszMapName[20];

//
// Instance data for each MDI child window
//
typedef struct _PerWndInfo {
    HWND    hParent;
    HWND    hTextWnd;
    RECT    rcClient;
    char    CaptionBarText[SIZEOFCAPTIONTEXT];
} INFO, *PINFO;

//
// Forward declarations.
//
BOOL InitializeApp   (void);
LONG APIENTRY MainWndProc     (HWND, UINT, DWORD, LONG);
LONG APIENTRY MDIWndProc      (HWND, UINT, DWORD, LONG);
BOOL CALLBACK About           (HWND, UINT, DWORD, LONG);
LONG APIENTRY TextWndProc     (HWND, UINT, DWORD, LONG);
VOID vTest	     (PINFO);

/***************************************************************************\
* WinMain
*
*
* History:
* 11-Feb-1992   Petrus Wong []
*   Added conditional compile statement for internal build environment.
* 04-17-91      ????      Created.
\***************************************************************************/
int APIENTRY WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nShowCmd)
{
    MSG    msg;
    HANDLE hAccel;

    ghModule = GetModuleHandle(NULL);
    if (!InitializeApp()) {
	MessageBox(ghwndMain, "MDI: InitializeApp failure!", "Error", MB_OK);
        return 0;
    }

    if (!(hAccel = LoadAccelerators (ghModule, MAKEINTRESOURCE(ACCEL_ID))))
	MessageBox(ghwndMain, "MDI: Load Accel failure!", "Error", MB_OK);


    while (GetMessage(&msg, NULL, 0, 0)) {
        if (!TranslateAccelerator( ghwndMain, hAccel, &msg) &&
            !TranslateMDISysAccel(  ghwndClient, &msg)          ) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return 1;

    UNREFERENCED_PARAMETER(lpCmdLine);
    UNREFERENCED_PARAMETER(nShowCmd);
    UNREFERENCED_PARAMETER(hInstance);
    UNREFERENCED_PARAMETER(hPrevInstance);
}


/***************************************************************************\
* InitializeApp
*
* History:
* 11-Feb-1992   Petrus Wong []
*   Name changes.
* 09-09-91 	Created.
\***************************************************************************/

BOOL InitializeApp(void)
{
    WNDCLASS wc;

    wc.style            = CS_OWNDC;
    wc.lpfnWndProc      = (WNDPROC) MainWndProc;
    wc.cbClsExtra       = 0;
    wc.cbWndExtra	= sizeof(LONG);
    wc.hInstance        = ghModule;
    wc.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground	= (HBRUSH)(COLOR_APPWORKSPACE);
    wc.lpszMenuName     = "MainMenu";
    wc.lpszClassName	= "MDIDemoClass";

    if (!RegisterClass(&wc))
	return FALSE;

    wc.lpfnWndProc	= (WNDPROC) MDIWndProc;
    wc.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
    wc.lpszMenuName	= NULL;
    wc.lpszClassName	= "MDIClass";

    if (!RegisterClass(&wc))
        return FALSE;

    wc.style		= CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc	= (WNDPROC) TextWndProc;
    wc.hIcon		= NULL;
    wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground	= (HBRUSH)(COLOR_BTNSHADOW);
    wc.lpszMenuName	= NULL;
    wc.lpszClassName	= "Text";

    if (!RegisterClass(&wc))
            return FALSE;



    hMenu	= LoadMenu(ghModule, "MainMenu");
    hChildMenu  = LoadMenu(ghModule, "ChildMenu");
    hMenuWindow      = GetSubMenu(hMenu, 1);
    hChildMenuWindow = GetSubMenu(hChildMenu, 2);

    ghwndMain = CreateWindowEx(0L, "MDIDemoClass", "MDI Demonstration",
	    WS_OVERLAPPED   | WS_CAPTION     | WS_BORDER       |
	    WS_THICKFRAME   | WS_MAXIMIZEBOX | WS_MINIMIZEBOX  |
	    WS_CLIPCHILDREN | WS_VISIBLE     | WS_SYSMENU,
            80, 70, 400, 300,
	    NULL, hMenu, ghModule, NULL);

    if (ghwndMain == NULL)
	return FALSE;

    SetWindowLong(ghwndMain, GWL_USERDATA, 0L);

    SetFocus(ghwndMain);    /* set initial focus */

    return TRUE;
}


/***************************************************************************\
* MainWndProc
*
* History:
* 11-Feb-1992   Petrus Wong []
*   Name changes.  Added comments.
* 09-09-91 	Created.
\***************************************************************************/

long APIENTRY MainWndProc(
    HWND hwnd,
    UINT message,
    DWORD wParam,
    LONG lParam)
{
    static int	       iMDICount=1;
    CLIENTCREATESTRUCT clientcreate;
    HWND               hwndChildWindow;


    switch (message) {

      case WM_CREATE:
	SetWindowLong(hwnd, 0, (LONG)NULL);

	clientcreate.hWindowMenu  = hMenuWindow;
	clientcreate.idFirstChild = 1;

	ghwndClient = CreateWindow("MDICLIENT", NULL,
				    WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
				    0,0,0,0,
				    hwnd, NULL, ghModule, (LPVOID)&clientcreate);
	return 0L;

      case WM_DESTROY: {
	PostQuitMessage(0);
	return 0L;
      }

      case WM_COMMAND:

	switch (LOWORD(wParam)) {
            //
            // Getting default MDI functionalities...
            //
	    case IDM_TILE:
		SendMessage(ghwndClient, WM_MDITILE, 0L, 0L);
		return 0L;
	    case IDM_CASCADE:
		SendMessage(ghwndClient, WM_MDICASCADE, 0L, 0L);
		return 0L;
	    case IDM_ARRANGE:
		SendMessage(ghwndClient, WM_MDIICONARRANGE, 0L, 0L);
		return 0L;

            //
            // Creates MDI child
            //
	    case MM_MDI: {
		HANDLE hInfo;
		PINFO  pInfo;
                MDICREATESTRUCT mdicreate;

                //
                // Allocating memory for INFO to be associated with the
                //  new child
                //
		hInfo = LocalAlloc(LHND, (WORD) sizeof(INFO));
		if (hInfo) {
		    if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL)
			MessageBox(ghwndMain, "Failed in LocalLock", "Error", MB_OK);

		    wsprintf((LPSTR) &(pInfo->CaptionBarText),
			     "MDI %d", iMDICount);
                    pInfo->hParent    = ghwndClient;

		    mdicreate.szClass = "MDIClass";
		    mdicreate.szTitle = (LPTSTR)&(pInfo->CaptionBarText);
		    mdicreate.hOwner  = ghModule;
		    mdicreate.x	      =
		    mdicreate.y	      =
		    mdicreate.cx      =
		    mdicreate.cy      = CW_USEDEFAULT;
		    mdicreate.style   = 0L;
                    //
                    // passing the handle of the per MDI child INFO to the
                    //  child MDI window for storage
                    //
		    mdicreate.lParam  = (LONG) hInfo;

		    /*Create Child Window*/
		    hwndChildWindow =
			(HANDLE) SendMessage(ghwndClient, WM_MDICREATE,
				    0L,
				    (LONG)(LPMDICREATESTRUCT)&mdicreate);

		    if (hwndChildWindow == NULL) {
			MessageBox(ghwndMain, "Failed in Creating Child Window", "Error", MB_OK);
			return 0L;
		    }

		    iMDICount++;

		    LocalUnlock(hInfo);
		} else {
			    MessageBox(ghwndMain, "Failed to Allocate INFO data!", "Error", MB_OK);
		}
		return 0L;
	    }


	    case MM_ABOUT:
	    	if (DialogBox(ghModule, "AboutBox", ghwndMain, (DLGPROC)About) == -1)
	    		MessageBox(ghwndMain, "DEMO: About Dialog Creation Error!", "Error", MB_OK);
		return 0L;

            //
            // Passes these WM_COMMAND messages to the appropriate active child
            //  window proc for processing
            //
	    case MM_OPT_1:
	    case MM_OPT_2:
	    case MM_OPT_3:
	    case MM_OPT_4:
	    case MM_OPT_5:
	    case MM_OPT_6:
	    case MM_OPT_7:
	    case MM_OPT_8: {
		HWND hActiveChild;

		hActiveChild = (HANDLE) SendMessage(ghwndClient, WM_MDIGETACTIVE, 0L, 0L);
		if (hActiveChild)
		    SendMessage(hActiveChild, WM_COMMAND, wParam, lParam);
		return 0L;
	    }

	    default:
		return DefFrameProc(hwnd,  ghwndClient, message, wParam, lParam);
        }

    default:

	return DefFrameProc(hwnd,  ghwndClient, message, wParam, lParam);
    }
}

/***************************************************************************\
* MDIWndProc
*
* History:
* 11-Feb-1992   Petrus Wong []
*   Name changes. Added comments.
* 09-09-91 	Petrus Wong Rewrote.
* 04-17-91 ????      Created.
\***************************************************************************/

long APIENTRY MDIWndProc(
    HWND hwnd,
    UINT message,
    DWORD wParam,
    LONG lParam)
{

    switch (message) {
	case WM_COMMAND: {
          HANDLE      hInfo;
          PINFO       pInfo;
          HWND        hTextWnd;

          //
          // Retrieving this child window's INFO data for displaying
          //    messages in the text window
          //
          hInfo = (HANDLE) GetWindowLong(hwnd, 0);
          if (hInfo) {
              if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL)
                  MessageBox(ghwndMain, "Failed in LocalLock", "Error", MB_OK);

	      hTextWnd = pInfo->hTextWnd;
	      vTest(pInfo);
              LocalUnlock(hInfo);
          } else {
              MessageBox(ghwndMain, "Can't get hInfo!", "Error", MB_OK);
          }


	  switch (LOWORD(wParam)) {
	    case MM_OPT_1: {
	       SetWindowText(hTextWnd, "MM_OPT_1");
               return 0L;
            }

	    case MM_OPT_2: {
               SetWindowText(hTextWnd, "MM_OPT_2");
	       return 0L;
	    }

	    case MM_OPT_3: {
	       SetWindowText(hTextWnd, "MM_OPT_3");
	       return 0L;
	    }

	    case MM_OPT_4: {
	       SetWindowText(hTextWnd, "MM_OPT_4");
	       return 0L;
	    }
            default:
               return 0L;

	  }

	}
	case WM_SETFOCUS:
	    break;

        //
        // Potentially, you can set different menu for different MDI
        //  child which is currently being active.
        //
	case WM_MDIACTIVATE:
	    if ((HWND) lParam == hwnd) {
		SendMessage(GetParent(hwnd), WM_MDISETMENU,
			    (DWORD)  hChildMenu,
			    (LONG)   hChildMenuWindow) ;
		DrawMenuBar(GetParent(GetParent(hwnd))) ;
	    }
	    return 0L;

        //
        // Whenever the MDI child window is resized, its children has to be
        //  resized accordingly.
        //
	case WM_SIZE: {
            HANDLE      hInfo;
            PINFO       pInfo;
            HWND        hTextWnd;

            //
            // First, get the text window's handle from the per MDI child
            //  INFO data structure
            //
            hInfo = (HANDLE) GetWindowLong(hwnd, 0);
            if (hInfo) {
                if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL)
                    MessageBox(ghwndMain, "Failed in LocalLock", "Error", MB_OK);

                hTextWnd = pInfo->hTextWnd;
		LocalUnlock(hInfo);
	    } else {
		MessageBox(ghwndMain, "Can't get hInfo!", "Error", MB_OK);
	    }

            //
            // Always, put the text window at the bottom of the MDI window
            //
	    MoveWindow(hTextWnd,
		       0,
		       HIWORD(lParam) - GetWindowLong(hTextWnd, GWL_USERDATA),
		       LOWORD(lParam),
		       HIWORD(lParam), TRUE);
	    break;
        }

        //
        // Creates the text window for this MDI child and saves its handle
        //  in the per MDI child INFO data structure.
        //
	case WM_CREATE: {
            PINFO           pInfo;
            HANDLE          hInfo;
            HWND            hTextWnd;

            hTextWnd = CreateWindow("Text", NULL,
                                    WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE,
                                    0, 0, 0, 0,
                                    hwnd,
                                    (HMENU) 2,
                                    ghModule,
                                    NULL);

            SetWindowText(hTextWnd, "Select 'Option' menu items");
            //
            // INFO was allocated in the MDIWndProc at MM_MDI time and is
            //  passed to us at WM_CREATE time...
            //
            hInfo = (HANDLE) ((LPMDICREATESTRUCT) ((LPCREATESTRUCT) lParam)->lpCreateParams)->lParam ;
            if (hInfo) {
                if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL)
                    MessageBox(ghwndMain, "Failed in LocalLock", "Error", MB_OK);

                if (!GetClientRect(hwnd, &pInfo->rcClient))
                    MessageBox(ghwndMain, "Failed in GetClientRect!", "Error", MB_OK);

                pInfo->hTextWnd = hTextWnd;
                //
                // Save the handle to INFO in our window structure
                //
                SetWindowLong(hwnd, 0, (LONG) hInfo);
		LocalUnlock(hInfo);
	    } else {
		MessageBox(ghwndMain, "Can't allocate hInfo!", "Error", MB_OK);
	    }

            break;
	}

        //
        // Free the INFO data that associates with this window
        //  also, reset the menu.
        //
	case WM_CLOSE: {
	    HANDLE	     hInfo;

	    SendMessage(GetParent(hwnd), WM_MDISETMENU,
			    (DWORD) hMenu,
			    (LONG)  hMenuWindow) ;
	    DrawMenuBar(GetParent(GetParent(hwnd))) ;

	    hInfo = (HANDLE) GetWindowLong(hwnd, 0);
	    LocalFree(hInfo);
            break;
	}

	default:
	    return DefMDIChildProc(hwnd, message, wParam, lParam);

    } //switch
    return DefMDIChildProc(hwnd, message, wParam, lParam);
}

/***************************************************************************\
* About
*
* About dialog proc.
*
* History:
* 09-09-91 	Petrus Wong Rewrote.
* 04-13-91 ????      Created.
\***************************************************************************/

BOOL CALLBACK About (
    HWND hDlg,
    UINT message,
    DWORD wParam,
    LONG lParam)
{
    switch (message) {
    case WM_INITDIALOG:
        return TRUE;

    case WM_COMMAND:
        if (wParam == IDOK)
            EndDialog(hDlg, wParam);
        break;
    }

    return FALSE;

    UNREFERENCED_PARAMETER(lParam);
    UNREFERENCED_PARAMETER(hDlg);
}

/***************************************************************************\
*
* TextWndProc
*
* Text Window procedure for displaying miscellaneous messages to user.
*
* History:
* 10-07-91
*   3D text output
*
\***************************************************************************/

LONG APIENTRY TextWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
{
    static HFONT hFont = (HFONT) NULL;

    switch (message)
    {
    case WM_CREATE:
        {
	    LOGFONT    lf;
	    HDC        hDC;
	    HFONT      hOldFont;
            TEXTMETRIC tm;
	    RECT       rect;
	    LONG       lHeight;

            SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), (PVOID) &lf, (UINT)FALSE);

	    hDC = GetDC(hwnd);
	    // this is the height for 8 point size font in pixels
	    lf.lfHeight = 8 * GetDeviceCaps(hDC, LOGPIXELSY) / 72;

	    hFont = CreateFontIndirect(&lf);
	    hOldFont = SelectObject(hDC, hFont);
	    GetTextMetrics(hDC, &tm);
	    GetClientRect(GetParent(hwnd), &rect);

	    // base the height of the window on size of text
	    lHeight = tm.tmHeight+6*GetSystemMetrics(SM_CYBORDER)+2;
	    // saved the height for later reference
	    SetWindowLong(hwnd, GWL_USERDATA, lHeight);
	    SetWindowPos(hwnd, NULL,
		    0,
		    rect.bottom-lHeight,
		    rect.right-rect.left,
		    lHeight,
		    SWP_NOZORDER | SWP_NOMOVE);

            ReleaseDC(hwnd, hDC);
            break;
        }

    case WM_DESTROY:
	    if (hFont)
		DeleteObject(hFont);
	    break;

    case WM_SETTEXT:
            DefWindowProc(hwnd, message, wParam, lParam);
            InvalidateRect(hwnd,NULL,FALSE);
            UpdateWindow(hwnd);
            return 0L;

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            RECT   rc;
            char   ach[128];
            int    len, nxBorder, nyBorder;
            HFONT  hOldFont = NULL;

            BeginPaint(hwnd, &ps);

            GetClientRect(hwnd,&rc);

            nxBorder = GetSystemMetrics(SM_CXBORDER);
	    rc.left  += 9*nxBorder;
            rc.right -= 9*nxBorder;

            nyBorder = GetSystemMetrics(SM_CYBORDER);
	    rc.top    += 3*nyBorder;
	    rc.bottom -= 3*nyBorder;

	    // 3D Text
            len = GetWindowText(hwnd, ach, sizeof(ach));
	    SetBkColor(ps.hdc, GetSysColor(COLOR_BTNFACE));

	    SetBkMode(ps.hdc, TRANSPARENT);
	    SetTextColor(ps.hdc, RGB(64,96,96));
	    if (hFont)
		hOldFont = SelectObject(ps.hdc, hFont);
	    ExtTextOut(ps.hdc, rc.left+2*nxBorder+2, rc.top+2, ETO_OPAQUE | ETO_CLIPPED,
	                &rc, ach, len, NULL);

	    SetTextColor(ps.hdc, RGB(128,128,128));
  	    if (hFont)
		hOldFont = SelectObject(ps.hdc, hFont);
	    ExtTextOut(ps.hdc, rc.left+2*nxBorder+1, rc.top+1, ETO_CLIPPED,
			&rc, ach, len, NULL);

	    SetTextColor(ps.hdc, RGB(255,255,255));
	    if (hFont)
		hOldFont = SelectObject(ps.hdc, hFont);
	    ExtTextOut(ps.hdc, rc.left+2*nxBorder, rc.top, ETO_CLIPPED,
			&rc, ach, len, NULL);

	    SetBkMode(ps.hdc, OPAQUE);

	    if (hOldFont)
		SelectObject(ps.hdc, hOldFont);

            EndPaint(hwnd, &ps);
            return 0L;
        }
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

VOID vTest(PINFO pInfo)
{
    OutputDebugString("Inside vTest()\n");

    UNREFERENCED_PARAMETER(pInfo);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.