home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / msysjour / vol04 / 02a / mdi / colors.c < prev    next >
C/C++ Source or Header  |  1988-12-06  |  15KB  |  546 lines

  1. /*
  2.  * COLORS.C - Colorful MDI Children
  3.  *
  4.  * LANGUAGE      : Microsoft C5.1
  5.  * MODEL         : medium
  6.  * ENVIRONMENT   : Microsoft Windows 2.1 SDK
  7.  * STATUS        : operational
  8.  *
  9.  * This module contains all the application code for the COLORS
  10.  * application.  This application handles an MDI desktop on which
  11.  * any number of colored documents reside.  Documents are either
  12.  * red, green, or blue and can be shaded from 0% of that color to
  13.  * 100% of that color (in increments of 25%).  In order to demonstrate
  14.  * acclerators, only the blue documents have accelerator keys.
  15.  *
  16.  * Developed by:
  17.  *   Geoffrey Nicholls
  18.  *   Kevin P. Welch
  19.  *
  20.  * (C) Copyright 1988
  21.  * Eikon Systems, Inc.
  22.  * 989 E. Hillsdale Blvd, Suite 260
  23.  * Foster City  CA  94404
  24.  *
  25.  */
  26.  
  27. #include <string.h>
  28. #include <stdio.h>
  29. #include <windows.h>
  30.  
  31. #include "colors.h"
  32. #include "mdi.h"
  33.  
  34. /* */
  35.  
  36. /*
  37.  *
  38.  * Static variables
  39.  *
  40.  */
  41.  
  42. /* Text for client area */
  43. static char    *szShadings[5] = {"0 %", "25 %", "50 %", "75 %", "100 %"};
  44.  
  45. /* Titles of documents */
  46. static char    *szTitles[3] = { "Red", "Green", "Blue" };
  47.  
  48. /* Count of each document (for titles) */
  49. static int     wCounts[3] = { 0, 0, 0 };
  50.  
  51. /* Color & Shading table */
  52. static DWORD   rgbColors[3][5] = {
  53.                   {  /* RED */
  54.                   RGB(255,255,255),    /*   0 % */
  55.                   RGB(255,192,192),    /*  25 % */
  56.                   RGB(255,128,128),    /*  50 % */
  57.                   RGB(255,64,64),      /*  75 % */
  58.                   RGB(255,0,0)         /* 100 % */
  59.                   },
  60.                   {  /* GREEN */
  61.                   RGB(255,255,255),    /*   0 % */
  62.                   RGB(192,255,192),    /*  25 % */
  63.                   RGB(128,255,128),    /*  50 % */
  64.                   RGB(64,255,64),      /*  75 % */
  65.                   RGB(0,255,0)         /* 100 % */
  66.                   },
  67.                   {  /* BLUE */
  68.                   RGB(255,255,255),    /*   0 % */
  69.                   RGB(192,192,255),    /*  25 % */
  70.                   RGB(128,128,255),    /*  50 % */
  71.                   RGB(64,64,255),      /*  75 % */
  72.                   RGB(0,0,255)         /* 100 % */
  73.                   } };
  74.  
  75. /* */
  76.  
  77. /*
  78.  * PASCAL WinMain( hPrevInst, hInst, lpszCommand, nCmdShow ) : int;
  79.  *
  80.  *    hPrevInst      Previous instance handle
  81.  *    hInst          Current instance handle
  82.  *    lpszCmdLine    Pointer to command line arguments
  83.  *    nCmdShow       ShowWindow() parameter
  84.  *
  85.  * First routine called by windows.  Calls the initialization routine
  86.  * and contains the message loop.
  87.  *
  88.  */
  89.  
  90. int PASCAL WinMain(
  91.    HANDLE      hInst,
  92.    HANDLE      hPrevInst,
  93.    LPSTR       lpszCmdLine,
  94.    int         nCmdShow )
  95. {
  96.    HWND        hwndColors;       /* Handle to our MDI desktop */
  97.    MSG         msg;              /* Current message */
  98.  
  99.    /* Initialize things needed for this application */
  100.    hwndColors = MainInit( hPrevInst, hInst, nCmdShow );
  101.    if ( !hwndColors )
  102.    {
  103.       /* Failure to initialize */
  104.       return NULL;
  105.    }
  106.  
  107.    /* Process messages */
  108.    while ( MdiGetMessage( hwndColors, &msg, NULL, NULL, NULL ) )
  109.    {
  110.       /* Normal message processing */
  111.       if ( !MdiTranslateAccelerators( hwndColors, &msg ) )
  112.       {
  113.          TranslateMessage( &msg );
  114.          DispatchMessage( &msg );
  115.       }
  116.    }
  117.  
  118.    /* Done */
  119.    return msg.wParam;
  120. }
  121.  
  122. /* */
  123.  
  124. /*
  125.  * MainInit( hPrevInst, hInst, nCmdShow ) : HWND;
  126.  *
  127.  *    hPrevInst      Previous instance handle
  128.  *    hInst          Current instance handle
  129.  *    nCmdShow       ShowWindow() parameter
  130.  *
  131.  * First, initialize the MDI desktop and the color document windows.
  132.  * Second, create the MDI desktop and then create one red document.
  133.  *
  134.  */
  135.  
  136. HWND MainInit(
  137.    HANDLE      hPrevInst,
  138.    HANDLE      hInst,
  139.    int         nCmdShow )
  140. {
  141.    char        szTitle[80];      /* Title of our MDI desktop */
  142.    char        szClass[80];      /* Class name of our MDI desktop */
  143.    HWND        hwndColors;       /* Handle to our MDI desktop */
  144.    WNDCLASS    WndClass;         /* Class structure */
  145.  
  146.    /* Window classes */
  147.    if ( !hPrevInst )
  148.    {
  149.       /* Main window */
  150.       LoadString( hInst, IDS_MAINCLASS, szClass, sizeof( szClass ) );
  151.  
  152.       /* Prepare registation */
  153.       memset( &WndClass, 0, sizeof( WndClass ) );
  154.       WndClass.style          = CS_HREDRAW | CS_VREDRAW;
  155.       WndClass.lpfnWndProc    = MainWndProc;
  156.       WndClass.hInstance      = hInst;
  157.       WndClass.hIcon          = LoadIcon( hInst, "MainIcon" );
  158.       WndClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
  159.       WndClass.hbrBackground  = COLOR_APPWORKSPACE + 1;
  160.       WndClass.lpszMenuName   = "MainMenu";
  161.       WndClass.lpszClassName  = szClass;
  162.  
  163.       /* Register main class */
  164.       if ( !RegisterClass( &WndClass ) )
  165.          return NULL;
  166.  
  167.       /* Allow each of the MDI children to do their own initialize */
  168.       if ( !ColorInit(hInst) )
  169.          return NULL;
  170.    }
  171.  
  172.    /* Create our main overlapped window */
  173.    LoadString( hInst, IDS_TITLE, szTitle, sizeof( szTitle ) );
  174.    hwndColors = MdiMainCreateWindow( szClass,
  175.       szTitle, 
  176.       WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  177.       CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  178.       NULL,
  179.       NULL,
  180.       hInst,
  181.       NULL );
  182.  
  183.    /* Did we create successfully? */
  184.    if ( !hwndColors )
  185.       return NULL;
  186.  
  187.    /* Give us one red child to begin with */
  188.    if ( !ColorCreate( hwndColors, COLOR_RED ) )
  189.    {
  190.       DestroyWindow( hwndColors );
  191.       return NULL;
  192.    }
  193.  
  194.    /* Ready */
  195.    ShowWindow( hwndColors, nCmdShow );
  196.    UpdateWindow( hwndColors );
  197.  
  198.    /* Done */
  199.    return hwndColors;
  200. }
  201.  
  202. /* */
  203.  
  204. /*
  205.  * MainWndProc( hwndMain, message, wParam, lParam ) : LONG;
  206.  *
  207.  *    hwndColors     Handle to our MDI desktop
  208.  *    message        Current message
  209.  *    wParam         Word parameter to the message
  210.  *    lParam         Long parameter to the message
  211.  *
  212.  * Handle messages for our MDI desktop.  This includes any WM_COMMAND
  213.  * messages that are received when NO document is visible on the
  214.  * desktop.
  215.  *
  216.  */
  217.  
  218. long FAR PASCAL MainWndProc(
  219.    HWND        hwndColors,
  220.    unsigned    message,
  221.    WORD        wParam,
  222.    LONG        lParam )
  223. {
  224.    FARPROC     lpProc;           /* Procedure instance for dialogs */
  225.    HANDLE      hInst;            /* Current instance handle */
  226.  
  227.    switch ( message )
  228.    {
  229.    case WM_COMMAND:
  230.       hInst = GetWindowWord( hwndColors, GWW_HINSTANCE );
  231.       switch( wParam )
  232.       {
  233.       case IDM_NEW:
  234.          /* New dialog box */
  235.          lpProc = MakeProcInstance( MainDlgNew, hInst );
  236.          switch( DialogBox( hInst, "MainNew", hwndColors, lpProc ) )
  237.          {
  238.          case DLGNEW_RED:
  239.             ColorCreate( hwndColors, COLOR_RED );
  240.             break;
  241.  
  242.          case DLGNEW_GREEN:
  243.             ColorCreate( hwndColors, COLOR_GREEN );
  244.             break;
  245.  
  246.          case DLGNEW_BLUE:
  247.             ColorCreate( hwndColors, COLOR_BLUE );
  248.             break;
  249.          }
  250.          FreeProcInstance( lpProc );
  251.          break;
  252.  
  253.       case IDM_OPEN:
  254.          break;
  255.  
  256.       case IDM_ABOUT:
  257.          /* About dialog box */
  258.          lpProc = MakeProcInstance( MainDlgAbout, hInst );
  259.          DialogBox( hInst, "MainAbout", hwndColors, lpProc );
  260.          FreeProcInstance( lpProc );
  261.          break;
  262.  
  263.       case IDM_EXIT:
  264.          /* Tell application to shut down */
  265.          PostMessage( hwndColors, WM_SYSCOMMAND, SC_CLOSE, 0L );
  266.          break;
  267.       }
  268.       break;
  269.  
  270.    case WM_DESTROY:
  271.       PostQuitMessage( 0 );
  272.       break;
  273.    }
  274.    return MdiMainDefWindowProc( hwndColors, message, wParam, lParam );
  275. }
  276.  
  277. /* */
  278.  
  279. /*
  280.  * ColorInit( hInst ) : BOOL;
  281.  *
  282.  *    hInst          Current instance handle
  283.  *
  284.  * Register the document class.
  285.  *
  286.  */
  287.  
  288. BOOL ColorInit(
  289.    HANDLE      hInst )
  290. {
  291.    char        szClass[80];      /* Class name */
  292.    WNDCLASS    WndClass;         /* Class structure */
  293.  
  294.    /* Get class name */
  295.    LoadString( hInst, IDS_COLORCLASS, szClass, sizeof( szClass ) );
  296.  
  297.    /* Prepare registation */
  298.    memset( &WndClass, 0, sizeof( WndClass ) );
  299.    WndClass.style          = CS_HREDRAW | CS_VREDRAW;
  300.    WndClass.lpfnWndProc    = ColorWndProc;
  301.    WndClass.cbWndExtra     = WE_EXTRA;
  302.    WndClass.hInstance      = hInst;
  303.    WndClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
  304.    WndClass.hbrBackground  = GetStockObject( GRAY_BRUSH );
  305.    WndClass.lpszClassName  = szClass;
  306.  
  307.    /* Register */
  308.    return RegisterClass( &WndClass );
  309. }
  310.  
  311. /* */
  312.  
  313. /*
  314.  * ColorCreate( hwndParent, wType ) : HWND;
  315.  *
  316.  *    hwndParent     Handle to our MDI desktop
  317.  *    wType          Document color
  318.  *
  319.  * Create a document window of a given color on the MDI desktop.
  320.  * It loads the appropriate menu, and accelerator table if the
  321.  * color is BLUE.  It initializes color and shading in the window
  322.  * extra words.
  323.  *
  324.  */
  325.  
  326. HWND ColorCreate(
  327.    HWND        hwndParent,
  328.    int         wType )
  329. {
  330.    char        szClass[80];      /* Class name for documents */
  331.    char        szTitle[80];      /* Title for this document */
  332.    HANDLE      hAccel = NULL;    /* Accelerator for blue doc only */
  333.    HANDLE      hInst;            /* Current instance handle */
  334.    HMENU       hmenuChild;       /* Handle to document's menu */
  335.    HWND        hwndChild;        /* Handle to document */
  336.  
  337.    /* Get important info */
  338.    hInst = GetWindowWord( hwndParent, GWW_HINSTANCE );
  339.    LoadString( hInst, IDS_COLORCLASS, szClass, sizeof( szClass ) );
  340.    sprintf( szTitle, "%s%d", szTitles[wType], ++wCounts[wType] );
  341.  
  342.    switch( wType )
  343.    {
  344.    case COLOR_RED:
  345.       hmenuChild = LoadMenu( hInst, "RedMenu" );
  346.       break;
  347.  
  348.    case COLOR_GREEN:
  349.       hmenuChild = LoadMenu( hInst, "GreenMenu" );
  350.       break;
  351.  
  352.    case COLOR_BLUE:
  353.       hmenuChild = LoadMenu( hInst, "BlueMenu" );
  354.       hAccel = LoadAccelerators( hInst, "BlueAccel" );
  355.       break;
  356.    }
  357.  
  358.    /* Create */
  359.    hwndChild = MdiChildCreateWindow( szClass,
  360.       szTitle,
  361.       WS_MDICHILD,
  362.       CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  363.       hwndParent,
  364.       hmenuChild,
  365.       hInst,
  366.       0L );
  367.  
  368.    /* Success? */
  369.    if ( hwndChild )
  370.    {
  371.       SetWindowWord( hwndChild, WE_SHADE, IDM_100 );
  372.       SetWindowWord( hwndChild, WE_COLOR, wType );
  373.       MdiSetAccel( hwndChild, hAccel );
  374.    }
  375.  
  376.    return hwndChild;
  377. }
  378.  
  379. /* */
  380.  
  381. /*
  382.  * ColorWndProc( hwndColor, message, wParam, lParam ) : LONG;
  383.  *
  384.  *    hwndChild      Handle to the current document
  385.  *    message        Current message
  386.  *    wParam         Word parameter to the message
  387.  *    lParam         Long parameter to the message
  388.  *
  389.  * Handle messages for our documents.  WM_COMMAND messages arrive at
  390.  * this procedure just as if the menu were attached to this window.
  391.  *
  392.  */
  393.  
  394. long FAR PASCAL ColorWndProc(
  395.    HWND        hwndChild,
  396.    unsigned    message,
  397.    WORD        wParam,
  398.    LONG        lParam )
  399. {
  400.    char        szText[20];       /* Client area text */
  401.    HBRUSH      hBrush;           /* Brush for filling document */
  402.    PAINTSTRUCT Paint;            /* Paint structure */
  403.    int         wColor;           /* Color of current document */
  404.    int         wShade;           /* Shading of current document */
  405.  
  406.    switch ( message )
  407.    {
  408.    case WM_COMMAND:
  409.       switch( wParam )
  410.       {
  411.       /* File menu */
  412.       case IDM_SAVE:
  413.       case IDM_SAVEAS:
  414.       case IDM_PRINT:
  415.          break;
  416.  
  417.       case IDM_CLOSE:
  418.          PostMessage( hwndChild, WM_SYSCOMMAND, SC_CLOSE, lParam );
  419.          break;
  420.  
  421.       case IDM_0:
  422.       case IDM_25:
  423.       case IDM_50:
  424.       case IDM_75:
  425.       case IDM_100:
  426.          CheckMenuItem( MdiGetMenu( hwndChild ),
  427.             SetWindowWord( hwndChild, WE_SHADE, wParam ),
  428.             MF_UNCHECKED );
  429.          CheckMenuItem( MdiGetMenu( hwndChild ),
  430.             GetWindowWord( hwndChild, WE_SHADE ),
  431.             MF_CHECKED );
  432.          InvalidateRect( hwndChild, (LPRECT) NULL, TRUE );
  433.          break;
  434.       }
  435.       break;
  436.  
  437.    case WM_ERASEBKGND:
  438.       return TRUE;
  439.  
  440.    case WM_PAINT:
  441.       wColor = GetWindowWord( hwndChild, WE_COLOR );
  442.       wShade = GetWindowWord( hwndChild, WE_SHADE );
  443.       BeginPaint( hwndChild, &Paint );
  444.       hBrush = CreateSolidBrush( rgbColors[wColor][wShade - IDM_0] );
  445.       FillRect( Paint.hdc, &Paint.rcPaint, hBrush );
  446.       DeleteObject( hBrush );
  447.       strcpy( szText, szShadings[wShade - IDM_0] );
  448.       TextOut( Paint.hdc, 0, 0, szText, strlen( szText ) );
  449.       EndPaint( hwndChild, &Paint );
  450.       break;
  451.    }
  452.    return MdiChildDefWindowProc( hwndChild, message, wParam, lParam );
  453. }
  454.  
  455. /* */
  456.  
  457. /*
  458.  * MainDlgNew( hDlg, message, wParam, lParam ) : int;
  459.  *
  460.  *    hDlg           Handle to dialog box
  461.  *    message        Current message
  462.  *    wParam         Word parameter to the message
  463.  *    lParam         Long parameter to the message
  464.  *
  465.  * Handle the NEW dialog box.
  466.  *
  467.  */
  468.  
  469. int FAR PASCAL MainDlgNew(
  470.    HWND        hDlg,
  471.    unsigned    message,
  472.    WORD        wParam,
  473.    LONG        lParam )
  474. {
  475.    static int  iButton;          /* Keep track of radio buttons */
  476.    int         iReturn = FALSE;  /* Return value */
  477.  
  478.    switch ( message )
  479.    {
  480.    case WM_INITDIALOG:
  481.       SendMessage( hDlg, WM_COMMAND, DLGNEW_RED, 0L );
  482.       iReturn = TRUE;
  483.       break;
  484.    
  485.    case WM_COMMAND:
  486.       switch( wParam )
  487.       {
  488.       case DLGNEW_RED:
  489.       case DLGNEW_GREEN:
  490.       case DLGNEW_BLUE:
  491.          iButton = wParam;
  492.          CheckRadioButton( hDlg, DLGNEW_RED, DLGNEW_BLUE, iButton );
  493.          if ( HIWORD( lParam ) == BN_DOUBLECLICKED )
  494.          {
  495.             SendMessage( hDlg, WM_COMMAND, IDOK, 0L );
  496.          }
  497.          break;
  498.  
  499.       case IDOK:
  500.          EndDialog( hDlg, iButton );
  501.          break;
  502.       
  503.       case IDCANCEL:
  504.          EndDialog( hDlg, 0 );
  505.          break;
  506.       }
  507.       break;
  508.    }
  509.    return iReturn;
  510. }
  511.  
  512. /* */
  513.  
  514. /*
  515.  * MainDlgAbout( hDlg, message, wParam, lParam ) : int;
  516.  *
  517.  *    hDlg           Handle to dialog box
  518.  *    message        Current message
  519.  *    wParam         Word parameter to the message
  520.  *    lParam         Long parameter to the message
  521.  *
  522.  * Handle the ABOUT dialog box.
  523.  *
  524.  */
  525.  
  526. int FAR PASCAL MainDlgAbout(
  527.    HWND        hDlg,
  528.    unsigned    message,
  529.    WORD        wParam,
  530.    LONG        lParam )
  531. {
  532.    int         iReturn = FALSE;  /* Return value */
  533.  
  534.    switch( message )
  535.    {
  536.    case WM_INITDIALOG:
  537.       iReturn = TRUE;
  538.       break;
  539.  
  540.    case WM_COMMAND:
  541.       EndDialog( hDlg, TRUE );
  542.       break;
  543.    }
  544.    return iReturn;
  545. }
  546.