home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winui / resource / iconpro / mdichild.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-05  |  51.0 KB  |  1,119 lines

  1. /****************************************************************************\
  2. *            
  3. *     FILE:     MDIChild.C
  4. *
  5. *     PURPOSE:  IconPro Project MDI Child Window handling c file
  6. *
  7. *     COMMENTS: This file contains the MDI Child Window handling code
  8. *
  9. *     FUNCTIONS:
  10. *      EXPORTS: 
  11. *               IconChildWndProc   - Window Procedure for the MDI children
  12. *      LOCALS:
  13. *               Draw3DRect         - Draws a rectangle using 3D colors
  14. *               EraseBackground    - Draws the MDI child's background
  15. *               CreateChildren     - Creates MDI child's child windows
  16. *               CreateChildListBox - Creates and shows a list box
  17. *               AddFormatDlgProc   - Dialog Proc for AddFormat dialog
  18. *
  19. *     Copyright 1995 - 1997 Microsoft Corp.
  20. *
  21. *
  22. * History:
  23. *                July '95 - Created
  24. *
  25. \****************************************************************************/
  26. #include <windows.h>
  27. #include <commctrl.h>
  28. #include "Icons.h"
  29. #include "IconPro.h"
  30. #include "Resource.h"
  31. #include "MDIChild.H"
  32.  
  33.  
  34. /****************************************************************************/
  35. // External Globals
  36. extern HINSTANCE    hInst;
  37. extern HWND            hWndMain, hMDIClientWnd;
  38. /****************************************************************************/
  39.  
  40.  
  41. /****************************************************************************/
  42. // Prototypes for local functions
  43. BOOL Draw3DRect( HDC hDC, RECT Rect, BOOL bSunken );
  44. void EraseBackground( HWND hWnd, HDC hDC );
  45. BOOL CreateChildren( HWND hWnd );
  46. HWND CreateChildListBox( HWND hWndParent, UINT ID, LPRECT lpRect );
  47. BOOL CALLBACK AddFormatDlgProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
  48. /****************************************************************************/
  49.  
  50.  
  51.  
  52. /****************************************************************************
  53. *
  54. *     FUNCTION: IconChildWndProc
  55. *
  56. *     PURPOSE:  Window Procedure for MDI child window
  57. *
  58. *     PARAMS:   HWND hWnd     - This window handle
  59. *               UINT Msg      - Which Message?
  60. *               WPARAM wParam - message parameter
  61. *               LPARAM lParam - message parameter
  62. *
  63. *     RETURNS:  LRESULT - depends on message
  64. *
  65. * History:
  66. *                July '95 - Created
  67. *
  68. \****************************************************************************/
  69. LRESULT CALLBACK IconChildWndProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
  70. {
  71.     // Which message is it?
  72.     switch( Msg )
  73.     {
  74.         // User pressed left mouse button
  75.         // Should be re-generate the AND mask?
  76.         case WM_LBUTTONDOWN:
  77.         {
  78.             LPCHILDWINDOWDATA    lpcwd;
  79.  
  80.             // Get the icon resource data aassociated with this window
  81.             if( (lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA )) == NULL )
  82.                 break;
  83.  
  84.             // Do something only if the CNTRL key is pressed too
  85.             if( MK_CONTROL & wParam )
  86.             {
  87.                 POINTS    pts = MAKEPOINTS(lParam);
  88.                 POINT    pt;
  89.                 RECT    ImageRect;
  90.                 DWORD    nIndex;
  91.  
  92.                 pt.x = pts.x; pt.y = pts.y;
  93.                 // Do we have some icon resource data?
  94.                 if( lpcwd->lpIR != NULL )
  95.                 {
  96.                     // Which image is selected right now?
  97.                     if( (nIndex = SendMessage( lpcwd->hWndFormatListBox, CB_GETCURSEL, 0, 0 )) != CB_ERR )
  98.                     {
  99.                         // Where is it drawn
  100.                         ImageRect = GetXORImageRect( lpcwd->XORRect, &(lpcwd->lpIR->IconImages[nIndex]) );
  101.                         // Is the mouse click in the image?
  102.                         if( PtInRect( &ImageRect, pt ) )
  103.                         {
  104.                             HCURSOR    hOldCursor;
  105.  
  106.                             // This might take a while :(
  107.                             hOldCursor = SetCursor( LoadCursor(NULL,IDC_WAIT) );
  108.                             pt.x -= ImageRect.left;
  109.                             pt.y -= ImageRect.top;
  110.                             // generate the new AND mask
  111.                             MakeNewANDMaskBasedOnPoint( &(lpcwd->lpIR->IconImages[nIndex]), pt );
  112.                             // force a redraw
  113.                             InvalidateRect( hWnd, NULL, TRUE );
  114.                             //  Set changed flag
  115.                             lpcwd->lpIR->bHasChanged = TRUE;
  116.                             // finally, its over, put the cursor back
  117.                             SetCursor( hOldCursor );
  118.                         }
  119.                     }
  120.                 }
  121.             }
  122.         }
  123.         break; // End WM_LBUTTONDOWN
  124.  
  125.         // Time to say "Goodbye"
  126.         case WM_CLOSE:
  127.         {
  128.             LPCHILDWINDOWDATA    lpcwd;
  129.             TCHAR    szWindowTitle[MAX_PATH];
  130.  
  131.             // Get the data associated with this window
  132.             lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA );
  133.             // Is there data associated with this window?
  134.             if( lpcwd != NULL )
  135.             {
  136.                 // Does the data include an icon resource
  137.                 if( lpcwd->lpIR != NULL )
  138.                 {
  139.                     // Has the resource changed?
  140.                     if( lpcwd->lpIR->bHasChanged )
  141.                     {
  142.                         // Get the title for the message box
  143.                         GetWindowText( hWnd, szWindowTitle, MAX_PATH );
  144.                         if( lstrlen( szWindowTitle ) < 1 )
  145.                             lstrcpy( szWindowTitle, "UnKnown" );
  146.                         // User want to save changes?
  147.                         switch( MessageBox( hWnd, "Icon has Changed, Save Changes?", szWindowTitle, MB_ICONSTOP | MB_YESNOCANCEL ) )
  148.                         {
  149.                             case IDYES:
  150.                                 SendMessage( hWnd, WM_COMMAND, ID_FILE_SAVE, 0 );
  151.                                 // Fall through to IDNO and kill window
  152.                             case IDNO:
  153.                                 DefMDIChildProc( hWnd, Msg, wParam, lParam );
  154.                                 return 0;
  155.                             break;
  156.                             case IDCANCEL:
  157.                                 return 1;
  158.                             break;
  159.                         }
  160.                     }
  161.                 }
  162.             }
  163.             DefMDIChildProc( hWnd, Msg, wParam, lParam );
  164.             return 0;
  165.         }
  166.         break; // End WM_CLOSE
  167.  
  168.         // We are being created
  169.         case WM_CREATE:
  170.         {
  171.             LPCHILDWINDOWDATA    lpcwd;
  172.  
  173.             // Need new data for this new window
  174.             lpcwd = malloc( sizeof( CHILDWINDOWDATA ) );
  175.             SetWindowLong( hWnd, GWL_USERDATA, (LONG)lpcwd );
  176.             lpcwd->lpIR = NULL;
  177.             // If a resource was passed in, use it
  178.             if( (LPVOID)lParam != NULL )
  179.                 lpcwd->lpIR = (LPICONRESOURCE)(((MDICREATESTRUCT *)(((CREATESTRUCT *)lParam)->lpCreateParams))->lParam);
  180.             // If no resource was passed in, do minimal initialization
  181.             if( lpcwd->lpIR == NULL )
  182.             {
  183.                 lpcwd->lpIR = malloc(sizeof(ICONRESOURCE));
  184.                 lstrcpy( lpcwd->lpIR->szOriginalICOFileName, "Untitled" );
  185.                 lstrcpy( lpcwd->lpIR->szOriginalDLLFileName, "" );
  186.                 lpcwd->lpIR->nNumImages = 0;
  187.             }
  188.             // Nothing has changed
  189.             lpcwd->lpIR->bHasChanged = FALSE;
  190.             // Create the list box, etc
  191.             CreateChildren( hWnd );
  192.             return DefMDIChildProc( hWnd, Msg, wParam, lParam );
  193.         }
  194.         break; // End WM_CREATE
  195.  
  196.         // Won't let window get too small to show our main area
  197.         case WM_GETMINMAXINFO:
  198.         {
  199.             LPMINMAXINFO    lpmmi = (LPMINMAXINFO)lParam;
  200.  
  201.             lpmmi->ptMinTrackSize.x = WINDOW_WIDTH;
  202.             lpmmi->ptMinTrackSize.y = WINDOW_HEIGHT;
  203.             return 0;
  204.         }
  205.         break; // End WM_GETMINMAXINFO
  206.  
  207.         // Yikes! We're being destroyed!
  208.         case WM_DESTROY:
  209.         {
  210.             LPCHILDWINDOWDATA    lpcwd;
  211.  
  212.             // Get the data associated with this window 
  213.             lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA );
  214.             // Is there some?
  215.             if( lpcwd != NULL )
  216.             {
  217.                 // Is there a resource?
  218.                 if( lpcwd->lpIR != NULL )
  219.                 {
  220.                     UINT i;
  221.  
  222.                     // Free all the bits
  223.                     for( i=0; i< lpcwd->lpIR->nNumImages; i++ )
  224.                     {
  225.                         if( lpcwd->lpIR->IconImages[i].lpBits != NULL )
  226.                             free( lpcwd->lpIR->IconImages[i].lpBits );
  227.                     }
  228.                     free( lpcwd->lpIR );
  229.                 }
  230.                 free( lpcwd );
  231.             }
  232.             SetWindowLong( hWnd, GWL_USERDATA, 0 );
  233.         }
  234.         break; // End WM_DESTROY
  235.  
  236.         // Draw our background (white and black squares, etc)
  237.         case WM_ERASEBKGND:
  238.             EraseBackground( hWnd, (HDC)wParam );
  239.             return 1;
  240.         break; // End WM_ERASEBKGND
  241.  
  242.         // Ok, time to paint
  243.         case WM_PAINT:
  244.         {
  245.             LPCHILDWINDOWDATA    lpcwd;
  246.             HDC                    hDC;
  247.             PAINTSTRUCT            ps;
  248.             DWORD                nIndex;
  249.             HICON                hIcon = NULL;
  250.  
  251.             // Obligatory BeginPaint()
  252.             hDC = BeginPaint( hWnd, &ps );
  253.             // Get the data associated with this window
  254.             lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA );
  255.             // Is there some?
  256.             if( lpcwd != NULL )
  257.             {
  258.                 // Is there a resource?
  259.                 if( lpcwd->lpIR != NULL )
  260.                 {
  261.                     // Which image is selected?
  262.                     if( (nIndex = SendMessage( lpcwd->hWndFormatListBox, CB_GETCURSEL, 0, 0 )) != CB_ERR )
  263.                     {
  264.                         int            Width, Height;
  265.  
  266.                         // Get an HICON for the currently selected image
  267.                         hIcon = MakeIconFromResource( &(lpcwd->lpIR->IconImages[nIndex]) );
  268.                         // How big is the icon?
  269.                         Width = lpcwd->lpIR->IconImages[nIndex].Width;
  270.                         Height = lpcwd->lpIR->IconImages[nIndex].Height;
  271.                         // Check to see if the icon is NULL
  272.                         // If it is, consider it "unsupported"
  273.                         // In the future, maybe we should look into MakeIconFromResource() and
  274.                         // see why it is null - it may be for another reason than "unsupported"
  275.                         if( hIcon == NULL )
  276.                         {
  277.                             SIZE    Size, Position;
  278.  
  279.                             // Draw some text in the black rect
  280.                             SetTextColor( hDC, RGB(255,255,255) );
  281.                             GetTextExtentPoint32( hDC, "Unsupported", 11, &Size );
  282.                             Position.cx = lpcwd->BlackRect.left + ((RectWidth(lpcwd->BlackRect)-Size.cx)/2);
  283.                             Position.cy = lpcwd->BlackRect.top + (RectHeight(lpcwd->BlackRect)/2) - Size.cy;
  284.                             TextOut( hDC, Position.cx, Position.cy, "Unsupported", 11 );
  285.                             GetTextExtentPoint32( hDC, "Format", 6, &Size );
  286.                             Position.cx = lpcwd->BlackRect.left + ((RectWidth(lpcwd->BlackRect)-Size.cx)/2);
  287.                             Position.cy = lpcwd->BlackRect.top + (RectHeight(lpcwd->BlackRect)/2) + 1;
  288.                             TextOut( hDC, Position.cx, Position.cy, "Format", 6 );
  289.  
  290.                             // Draw some text in the white rect
  291.                             SetTextColor( hDC, RGB(0,0,0) );
  292.                             GetTextExtentPoint32( hDC, "Unsupported", 11, &Size );
  293.                             Position.cx = lpcwd->WhiteRect.left + ((RectWidth(lpcwd->WhiteRect)-Size.cx)/2);
  294.                             Position.cy = lpcwd->WhiteRect.top + (RectHeight(lpcwd->WhiteRect)/2) - Size.cy;
  295.                             TextOut( hDC, Position.cx, Position.cy, "Unsupported", 11 );
  296.                             GetTextExtentPoint32( hDC, "Format", 6, &Size );
  297.                             Position.cx = lpcwd->WhiteRect.left + ((RectWidth(lpcwd->WhiteRect)-Size.cx)/2);
  298.                             Position.cy = lpcwd->WhiteRect.top + (RectHeight(lpcwd->WhiteRect)/2) + 1;
  299.                             TextOut( hDC, Position.cx, Position.cy, "Format", 6 );
  300.                         }
  301.                         else
  302.                         {
  303.                             // Draw it on the black background
  304.                             DrawIconEx( hDC, lpcwd->BlackRect.left + ((RectWidth(lpcwd->BlackRect)-Width)/2),
  305.                                             lpcwd->BlackRect.top + ((RectHeight(lpcwd->BlackRect)-Height)/2), 
  306.                                             hIcon, Width, Height, 0, NULL, DI_NORMAL );
  307.                             // Draw it on the white background
  308.                             DrawIconEx( hDC, lpcwd->WhiteRect.left + ((RectWidth(lpcwd->WhiteRect)-Width)/2),
  309.                                             lpcwd->WhiteRect.top + ((RectHeight(lpcwd->WhiteRect)-Height)/2), 
  310.                                             hIcon, Width, Height, 0, NULL, DI_NORMAL );
  311.                         }
  312.                         // Draw just the XOR mask
  313.                         DrawXORMask( hDC, lpcwd->XORRect, &(lpcwd->lpIR->IconImages[nIndex]) );
  314.                         // Draw just the AND mask
  315.                         DrawANDMask( hDC, lpcwd->ANDRect, &(lpcwd->lpIR->IconImages[nIndex]) );
  316.                         // Kill the icon, we're one with it
  317.                         if( hIcon != NULL )
  318.                             DestroyIcon( hIcon );
  319.                     }
  320.                 }
  321.             }
  322.             // Obligtory EndPaint()
  323.             EndPaint( hWnd, &ps );
  324.         }
  325.         break; // End WM_PAINT
  326.  
  327.         // WM_COMMAND - menu options, etc
  328.         case WM_COMMAND:
  329.             // which one is it?
  330.             switch( LOWORD(wParam) )
  331.             {
  332.                 // Edit->Export BMP - write icon image as BMP file
  333.                 case ID_EDIT_EXPORTBMP:
  334.                 {
  335.                     LPCHILDWINDOWDATA    lpcwd;
  336.                     DWORD                nIndex;
  337.                     TCHAR                szFileName[MAX_PATH];
  338.  
  339.                     // Get the data associated this window 
  340.                     lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA );
  341.                     // If we have some data, including an icon resource
  342.                     if( (lpcwd != NULL ) && (lpcwd->lpIR != NULL) && (lpcwd->hWndFormatListBox!= NULL) )
  343.                     {
  344.                         // Which image is currently selected?
  345.                         if( (nIndex = SendMessage( lpcwd->hWndFormatListBox, CB_GETCURSEL, 0, 0 )) != CB_ERR )
  346.                         {
  347.                             // Get the name of the file from which to import the image
  348.                             if( GetSaveIconFileName( szFileName, IDS_BMPFILTERSTRING, "Export to BMP File" ) )
  349.                             {
  350.                                 HCURSOR    hOldCursor;
  351.  
  352.                                 // This might take a while :(
  353.                                 hOldCursor = SetCursor( LoadCursor(NULL,IDC_WAIT) );
  354.                                 IconImageToBMPFile( szFileName, &(lpcwd->lpIR->IconImages[nIndex]) );
  355.                                 SetCursor( hOldCursor );
  356.                             }
  357.                         }
  358.                     }
  359.                 }
  360.                 break; // End ID_EDIT_EXPORTBMP
  361.  
  362.                 // Edit->Import BMP and Edit->Stretch-Import BMP - convert BMP file to icon
  363.                 case ID_EDIT_IMPORTBMP:
  364.                 case ID_EDIT_STRETCHIMPORTBMP:
  365.                 {
  366.                     LPCHILDWINDOWDATA    lpcwd;
  367.                     DWORD                nIndex;
  368.                     TCHAR                szFileName[MAX_PATH];
  369.  
  370.                     // Get the data associated this window 
  371.                     lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA );
  372.                     // If we have some data, including an icon resource
  373.                     if( (lpcwd != NULL ) && (lpcwd->lpIR != NULL) && (lpcwd->hWndFormatListBox!= NULL) )
  374.                     {
  375.                         // Which image is currently selected?
  376.                         if( (nIndex = SendMessage( lpcwd->hWndFormatListBox, CB_GETCURSEL, 0, 0 )) != CB_ERR )
  377.                         {
  378.                             // Get the name of the file from which to import the image
  379.                             if( GetOpenIconFileName( szFileName, IDS_BMPFILTERSTRING, "Import from BMP File" ) )
  380.                             {
  381.                                 HCURSOR    hOldCursor;
  382.  
  383.                                 // This might take a while :(
  384.                                 hOldCursor = SetCursor( LoadCursor(NULL,IDC_WAIT) );
  385.                                 // Import the BMP image data
  386.                                 if( IconImageFromBMPFile( szFileName, &(lpcwd->lpIR->IconImages[nIndex]), (LOWORD(wParam)==ID_EDIT_STRETCHIMPORTBMP)?TRUE:FALSE ) )
  387.                                 {
  388.                                     // which, of course, changes things
  389.                                     lpcwd->lpIR->bHasChanged = TRUE;
  390.                                     // Force a repaint
  391.                                     InvalidateRect( hWnd, NULL, TRUE );
  392.                                 }
  393.                                 SetCursor( hOldCursor );
  394.                             }
  395.                         }
  396.                     }
  397.                 }
  398.                 break; // End ID_EDIT_IMPORTBMP/ID_EDIT_STRETCHIMPORTBMP
  399.  
  400.                 // User wants to add an image format
  401.                 case ID_EDIT_ADDFORMAT:
  402.                 {
  403.                     LPICONIMAGE    lpii;
  404.                     TCHAR    szBuffer[256];
  405.                     
  406.                     // Launch the dialog to ask which size and color depth
  407.                     if( DialogBoxParam( hInst, MAKEINTRESOURCE(IDD_ADDFORMATDLG), hWndMain, AddFormatDlgProc, (LPARAM)(&lpii) ) )
  408.                     {
  409.                         LPCHILDWINDOWDATA    lpcwd;
  410.                         LPICONRESOURCE        lpNewIR;
  411.                         DWORD                nIndex, i;
  412.  
  413.                         // Get the data associated this window 
  414.                         lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA );
  415.                         // If we have some data, including an icon resource
  416.                         if( (lpcwd != NULL ) && (lpcwd->lpIR != NULL) && (lpcwd->hWndFormatListBox!= NULL) )
  417.                         {
  418.                             // Need to see if the new format already exists in the resource
  419.                             // We don't want dupes, so check each image for dupe
  420.                             for(i=0;i<lpcwd->lpIR->nNumImages;i++)
  421.                             {
  422.                                 // Is it the same as the new one?
  423.                                 if( (lpcwd->lpIR->IconImages[i].Width==lpii->Width) &&
  424.                                     (lpcwd->lpIR->IconImages[i].Height==lpii->Height) && 
  425.                                     (lpcwd->lpIR->IconImages[i].Colors==lpii->Colors) )
  426.                                 {
  427.                                     // Yikes! It is - bail and select the old one
  428.                                     MessageBox( hWnd, "That format already exists - format not added", "Error", MB_OK );
  429.                                     SendMessage( lpcwd->hWndFormatListBox,     CB_SETCURSEL, (WPARAM)i, (LPARAM)0 );
  430.                                     break;
  431.                                 }
  432.                             }
  433.                             // Need bigger block of memory to hold an extra image format
  434.                             lpNewIR = malloc( sizeof( ICONRESOURCE ) + ( ( lpcwd->lpIR->nNumImages + 1) * sizeof(ICONIMAGE) ) );
  435.                             // Of course this changes things
  436.                             lpNewIR->bHasChanged = TRUE;
  437.                             // Copy old to new
  438.                             lstrcpy( lpNewIR->szOriginalICOFileName, lpcwd->lpIR->szOriginalICOFileName );
  439.                             lstrcpy( lpNewIR->szOriginalDLLFileName, lpcwd->lpIR->szOriginalDLLFileName );
  440.                             lpNewIR->nNumImages = lpcwd->lpIR->nNumImages + 1;
  441.                             for(i=0;i<lpcwd->lpIR->nNumImages;i++)
  442.                             {
  443.                                 memcpy( &(lpNewIR->IconImages[i]), &(lpcwd->lpIR->IconImages[i]), sizeof( ICONIMAGE ) );
  444.                             }
  445.                             // Add in the new one
  446.                             memcpy( &(lpNewIR->IconImages[i]), lpii, sizeof( ICONIMAGE ) );
  447.                             // Add this new one to the list box
  448.                             wsprintf( szBuffer, "%dx%d, %d Bit Color", lpii->Width, lpii->Height, lpii->Colors );
  449.                             nIndex = SendMessage( lpcwd->hWndFormatListBox, CB_ADDSTRING, 0, (LPARAM)szBuffer );
  450.                             // Select the new one
  451.                             SendMessage( lpcwd->hWndFormatListBox,     CB_SETCURSEL, (WPARAM)i, (LPARAM)0 );
  452.                             // clean up
  453.                             free( lpii );
  454.                             free( lpcwd->lpIR );
  455.                             lpcwd->lpIR = lpNewIR;
  456.                             // Create a nice new blank image for this format
  457.                             CreateBlankNewFormatIcon( &(lpcwd->lpIR->IconImages[i]) );
  458.                             // force a repaint
  459.                             InvalidateRect( hWnd, NULL, TRUE );
  460.                         }
  461.                     }
  462.                 }
  463.                 break; // End WM_COMMAND -> ID_EDIT_ADDFORMAT
  464.                 
  465.                 // User wants to remove an image format
  466.                 case ID_EDIT_REMOVEFORMAT:
  467.                 {
  468.                     LPCHILDWINDOWDATA    lpcwd;
  469.                     DWORD                nIndex, i;
  470.                     LPICONRESOURCE        lpNewIR;
  471.  
  472.                     // Get the data associated this window 
  473.                     lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA );
  474.                     // If we have some data, including an icon resource
  475.                     if( (lpcwd != NULL ) && (lpcwd->lpIR != NULL) && (lpcwd->hWndFormatListBox!= NULL) )
  476.                     {
  477.                         // Which image is currently selected?
  478.                         if( (nIndex = SendMessage( lpcwd->hWndFormatListBox, CB_GETCURSEL, 0, 0 )) != CB_ERR )
  479.                         {
  480.                             // Remove the entry from the list box
  481.                             SendMessage( lpcwd->hWndFormatListBox, CB_DELETESTRING, nIndex, 0 );
  482.                             // Need less memory now
  483.                             lpNewIR = malloc( sizeof( ICONRESOURCE ) + ( ( lpcwd->lpIR->nNumImages - 1) * sizeof(ICONIMAGE) ) );
  484.                             // Of course this changes things
  485.                             lpNewIR->bHasChanged = TRUE;
  486.                             // Copy old to new
  487.                             lstrcpy( lpNewIR->szOriginalICOFileName, lpcwd->lpIR->szOriginalICOFileName );
  488.                             lstrcpy( lpNewIR->szOriginalDLLFileName, lpcwd->lpIR->szOriginalDLLFileName );
  489.                             lpNewIR->nNumImages = lpcwd->lpIR->nNumImages - 1;
  490.                             // Copy the rest of the images from old to new
  491.                             for(i=0;i<nIndex;i++)
  492.                             {
  493.                                 memcpy( &(lpNewIR->IconImages[i]), &(lpcwd->lpIR->IconImages[i]), sizeof( ICONIMAGE ) );
  494.                             }
  495.                             for(;i<lpcwd->lpIR->nNumImages-1;i++)
  496.                             {
  497.                                 memcpy( &(lpNewIR->IconImages[i]), &(lpcwd->lpIR->IconImages[i+1]), sizeof( ICONIMAGE ) );
  498.                             }
  499.                             // Clean up
  500.                             free( lpcwd->lpIR );
  501.                             lpcwd->lpIR = lpNewIR;
  502.                             // Select a different image
  503.                             if( --nIndex < 0 ) nIndex = 0;
  504.                             SendMessage( lpcwd->hWndFormatListBox, CB_SETCURSEL, (WPARAM)nIndex, 0 );
  505.                             // Force a repaint
  506.                             InvalidateRect( hWnd, NULL, TRUE );
  507.                         }
  508.                     }
  509.                 }
  510.                 break; // End WM_COMMAND -> ID_EDIT_REMOVEFORMAT
  511.  
  512.                 // User wants to paste CF_DIB from clipboard into current image
  513.                 case ID_EDIT_STRETCHPASTE:
  514.                 case ID_EDIT_PASTE:
  515.                 {
  516.                     LPCHILDWINDOWDATA    lpcwd;
  517.                     DWORD                nIndex;
  518.  
  519.                     // Get the data associated this window 
  520.                     lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA );
  521.                     // If we have some data, including an icon resource
  522.                     if( (lpcwd != NULL ) && (lpcwd->lpIR != NULL) && (lpcwd->hWndFormatListBox!= NULL) )
  523.                     {
  524.                         // Which image is currently selected?
  525.                         if( (nIndex = SendMessage( lpcwd->hWndFormatListBox, CB_GETCURSEL, 0, 0 )) != CB_ERR )
  526.                         {
  527.                             HCURSOR    hOldCursor;
  528.  
  529.                             // This might take a while :(
  530.                             hOldCursor = SetCursor( LoadCursor(NULL,IDC_WAIT) );
  531.  
  532.                             // Paste over it from the clipboard
  533.                             if( IconImageFromClipBoard( &(lpcwd->lpIR->IconImages[nIndex]), LOWORD(wParam)!=ID_EDIT_PASTE ) )
  534.                                 // which, of course, changes things
  535.                                 lpcwd->lpIR->bHasChanged = TRUE;
  536.                             // Force a repaint
  537.                             InvalidateRect( hWnd, NULL, TRUE );
  538.                             SetCursor( hOldCursor );
  539.                         }
  540.                     }
  541.                 }
  542.                 break; // End WM_COMMAND -> ID_EDIT_STRETCHPASTE/ID_EDIT_PASTE
  543.  
  544.                 // Put current image on the clipboard in CF_DIB format
  545.                 case ID_EDIT_COPY:
  546.                 {
  547.                     LPCHILDWINDOWDATA    lpcwd;
  548.                     DWORD                nIndex;
  549.  
  550.                     // Get the data associated this window 
  551.                     lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA );
  552.                     // If we have some data, including an icon resource
  553.                     if( (lpcwd != NULL ) && (lpcwd->lpIR != NULL) && (lpcwd->hWndFormatListBox!= NULL) )
  554.                     {
  555.                         // Which image is currently selected?
  556.                         if( (nIndex = SendMessage( lpcwd->hWndFormatListBox, CB_GETCURSEL, 0, 0 )) != CB_ERR )
  557.                         {
  558.                             // Send this image to the clipboard
  559.                             IconImageToClipBoard( &(lpcwd->lpIR->IconImages[nIndex]) );
  560.                         }
  561.                     }
  562.                 }
  563.                 break; // End WM_COMMAND -> ID_EDIT_COPY
  564.  
  565.                 // The filename has changed, update the window title
  566.                 case ID_UPDATETITLE:
  567.                 {
  568.                     TCHAR    szFileTitle[MAX_PATH];
  569.                     LPCHILDWINDOWDATA    lpcwd;
  570.  
  571.                     // Get the data associated this window 
  572.                     lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA );
  573.                     // If we have some data
  574.                     if( lpcwd != NULL )
  575.                     {
  576.                         // including an icon resource
  577.                         if( lpcwd->lpIR != NULL )
  578.                         {
  579.                             // The calculate and set the new title
  580.                             if( GetFileTitle( lpcwd->lpIR->szOriginalICOFileName, szFileTitle, MAX_PATH ) == 0 )
  581.                             {
  582.                                 SetWindowText( hWnd, szFileTitle );
  583.                             }
  584.                         }
  585.                     }
  586.                 }
  587.                 break; // End WM_COMMAND -> ID_UPDATETITLE
  588.  
  589.                 // How many image formats in the icon resource? (return that number)
  590.                 case ID_GETNUMFORMATS:
  591.                 {
  592.                     LPCHILDWINDOWDATA    lpcwd;
  593.                     UINT nNum = 0;
  594.  
  595.                     // Get the data associated this window 
  596.                     lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA );
  597.                     // If we have some data
  598.                     if( lpcwd != NULL )
  599.                     {
  600.                         // If we have a listbox, get its count, else 0
  601.                         if( lpcwd->hWndFormatListBox != NULL )
  602.                             nNum = (UINT)SendMessage( lpcwd->hWndFormatListBox, CB_GETCOUNT, 0, 0 );
  603.                         else
  604.                             nNum = 0;
  605.                         // If an error occurred, default to 0
  606.                         if( nNum == (UINT)CB_ERR )
  607.                             nNum = 0;
  608.                     }
  609.                     // Send it back
  610.                     return nNum;
  611.                 }
  612.                 break; // End WM_COMMAND -> ID_GETNUMFORMATS
  613.  
  614.                 // Has this icon resource changed? return TRUE=yes, FALSE=no
  615.                 case ID_HASFILECHANGED:
  616.                 {
  617.                     LPCHILDWINDOWDATA    lpcwd;
  618.                     UINT nRet = 0;
  619.  
  620.                     // Get the data associated this window 
  621.                     lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA );
  622.                     // If we have some data
  623.                     if( lpcwd != NULL )
  624.                         // And it includes an icon resource
  625.                         if( lpcwd->lpIR != NULL )
  626.                             // then check whether it has changed
  627.                             return lpcwd->lpIR->bHasChanged == TRUE;
  628.                     // Otherwise, return FALSE
  629.                     return nRet;
  630.                 }
  631.                 break; // End WM_COMMAND -> ID_HASFILECHANGED
  632.  
  633.                 // Handle selection changes, etc from listbox
  634.                 case ID_FORMAT_BOX:
  635.                     switch( HIWORD(wParam) )
  636.                     {
  637.                         // If a selection is made, or changes, repaint
  638.                         case CBN_SELCHANGE:
  639.                         case CBN_SELENDOK:
  640.                             InvalidateRect( hWnd, NULL, TRUE );
  641.                         break;
  642.                     }
  643.                 break; // End WM_COMMAND -> ID_FORMAT_BOX
  644.             
  645.                 // User wants to save the ICO file
  646.                 case ID_FILE_SAVEAS:
  647.                 case ID_FILE_SAVE:
  648.                 {
  649.                     TCHAR    szFileName[MAX_PATH];
  650.                     LPCHILDWINDOWDATA    lpcwd;
  651.  
  652.                     // Get the data associated this window 
  653.                     if( ( lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA ) ) != NULL )
  654.                     {
  655.                         // See if it includes an icon resource
  656.                         if( lpcwd->lpIR != NULL )
  657.                         {
  658.                             HCURSOR    hOldCursor;
  659.  
  660.                             // This might take a while :(
  661.                             hOldCursor = SetCursor( LoadCursor(NULL,IDC_WAIT) );
  662.  
  663.                             // If we have an original filename, and user did *NOT* 'Save As'
  664.                             if( ( lstrlen(lpcwd->lpIR->szOriginalICOFileName) > 0 ) && (LOWORD(wParam)!=ID_FILE_SAVEAS) )
  665.                             {
  666.                                 // The just write it out
  667.                                 WriteIconToICOFile( lpcwd->lpIR, lpcwd->lpIR->szOriginalICOFileName );
  668.                                 // which, of course, brings it up to date
  669.                                 lpcwd->lpIR->bHasChanged = FALSE;
  670.                             }
  671.                             else
  672.                             {
  673.                                 // Either we have no name, or user hit 'Save As'
  674.                                 if( GetSaveIconFileName( szFileName, IDS_FILTERSTRING, LOWORD(wParam)==ID_FILE_SAVE?"Save Icon File":"Save Icon File As" ) )
  675.                                 {
  676.                                     // So, write it out
  677.                                     WriteIconToICOFile( lpcwd->lpIR, szFileName );
  678.                                     // Update the name associated with the resource
  679.                                     lstrcpy( lpcwd->lpIR->szOriginalICOFileName, szFileName );
  680.                                     // Inform window to update title
  681.                                     SendMessage( hWnd, WM_COMMAND, ID_UPDATETITLE, 0 );
  682.                                     // and, of course, it is now up to date
  683.                                     lpcwd->lpIR->bHasChanged = FALSE;
  684.                                 }
  685.                             }
  686.                             SetCursor( hOldCursor );
  687.                         }
  688.                         else
  689.                             MessageBox( hWnd, "Error Getting Icon Info - File Not Saved", "Error", MB_OK );
  690.                     }
  691.                 }
  692.                 break; // End WM_COMMAND -> ID_FILE_SAVE/ID_FILE_SAVEAS
  693.             }
  694.         break; // End WM_COMMAND
  695.     }
  696.     return DefMDIChildProc( hWnd, Msg, wParam, lParam );
  697. }
  698. /* End IconChildWndProc() **************************************************/
  699.  
  700.  
  701.  
  702.  
  703. /****************************************************************************
  704. *
  705. *     FUNCTION: Draw3DRect
  706. *
  707. *     PURPOSE:  draws a rectangle in 3d colors
  708. *
  709. *     PARAMS:   HDC hDC      - The DC on which to draw
  710. *               RECT Rect    - The rectangle itself
  711. *               BOOL bSunken - TRUE  = rect should look sunken
  712. *                              FALSE = rect should look raised
  713. *
  714. *     RETURNS:  BOOL - TRUE for success, FALSE for failure
  715. *
  716. * History:
  717. *                July '95 - Created
  718. *
  719. \****************************************************************************/
  720. BOOL Draw3DRect( HDC hDC, RECT Rect, BOOL bSunken )
  721. {
  722.     HBRUSH    hBrush;
  723.     HPEN    hPen, hOldPen;
  724.  
  725.     // Get the color for the main foreground
  726.     hBrush = CreateSolidBrush( GetSysColor(COLOR_3DFACE) );
  727.     // paint it
  728.     FillRect( hDC, &Rect, hBrush );
  729.     DeleteObject( hBrush );
  730.     // Get the pen for the top and left sides
  731.     if( bSunken )
  732.         hPen = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW) );
  733.     else
  734.         hPen = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT) );
  735.     hOldPen = SelectObject( hDC, hPen);
  736.     // Draw the top and left sides
  737.     MoveToEx( hDC, Rect.right, Rect.top, NULL );
  738.     LineTo( hDC, Rect.left, Rect.top );
  739.     LineTo( hDC, Rect.left, Rect.bottom );
  740.     SelectObject( hDC, hOldPen);
  741.     DeleteObject( hPen );
  742.     // Get the pen for the bottom and right sides
  743.     if( bSunken )
  744.         hPen = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT) );
  745.     else
  746.         hPen = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW) );
  747.     hOldPen = SelectObject( hDC, hPen);
  748.     // Draw the bottom and right sides
  749.     LineTo( hDC, Rect.right, Rect.bottom );
  750.     LineTo( hDC, Rect.right, Rect.top );
  751.     SelectObject( hDC, hOldPen);
  752.     DeleteObject( hPen );
  753.     return TRUE;
  754. }
  755. /* End Draw3DRect() *******************************************************/
  756.  
  757.  
  758.  
  759.  
  760. /****************************************************************************
  761. *
  762. *     FUNCTION: EraseBackground
  763. *
  764. *     PURPOSE:  Draws the background for the MDI child
  765. *
  766. *     PARAMS:   HWND hWnd - The MDI window of interest
  767. *               HDC  hDC  - The DC on which to draw
  768. *
  769. *     RETURNS:  void
  770. *
  771. * History:
  772. *                July '95 - Created
  773. *
  774. \****************************************************************************/
  775. void EraseBackground( HWND hWnd, HDC hDC )
  776. {
  777.     RECT                Rect;
  778.     LPCHILDWINDOWDATA    lpcwd;
  779.     HBRUSH                hBrush;
  780.     SIZE                TextSize;
  781.  
  782.     // Just how big is this window?
  783.     GetClientRect( hWnd, &Rect );
  784.     // Paint the background
  785.     Draw3DRect( hDC, Rect, FALSE );
  786.  
  787.     // If there is no icon resource yet, bail out
  788.     if( ( lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA ) ) == NULL )
  789.         return;
  790.     // Draw 3d rectangles around areas of interest
  791.     Draw3DRect( hDC, lpcwd->WhiteRect, TRUE );
  792.     Draw3DRect( hDC, lpcwd->WhiteTextRect, TRUE );
  793.     Draw3DRect( hDC, lpcwd->BlackRect, TRUE );
  794.     Draw3DRect( hDC, lpcwd->BlackTextRect, TRUE );
  795.     Draw3DRect( hDC, lpcwd->XORRect, TRUE );
  796.     Draw3DRect( hDC, lpcwd->XORTextRect, TRUE );
  797.     Draw3DRect( hDC, lpcwd->ANDRect, TRUE );
  798.     Draw3DRect( hDC, lpcwd->ANDTextRect, TRUE );
  799.     // Fill in the white area
  800.     hBrush = GetStockObject( WHITE_BRUSH );
  801.     SelectObject( hDC, hBrush );
  802.     Rectangle( hDC, lpcwd->WhiteRect.left, lpcwd->WhiteRect.top, lpcwd->WhiteRect.right, lpcwd->WhiteRect.bottom );
  803.     // Fill in the black area
  804.     hBrush = GetStockObject( BLACK_BRUSH );
  805.     SelectObject( hDC, hBrush );
  806.     Rectangle( hDC, lpcwd->BlackRect.left, lpcwd->BlackRect.top, lpcwd->BlackRect.right, lpcwd->BlackRect.bottom );
  807.  
  808.     // Set texts for the various sections
  809.     SetBkMode( hDC, TRANSPARENT );
  810.     GetTextExtentPoint32( hDC, "Icon On Black", 13, &TextSize );
  811.     TextOut( hDC, lpcwd->BlackTextRect.left + ((RectWidth(lpcwd->BlackTextRect)-TextSize.cx)/2),
  812.                     lpcwd->BlackTextRect.top + ((RectHeight(lpcwd->BlackTextRect)-TextSize.cy)/2), "Icon On Black", 13 );
  813.     GetTextExtentPoint32( hDC, "Icon On White", 13, &TextSize );
  814.     TextOut( hDC, lpcwd->WhiteTextRect.left + ((RectWidth(lpcwd->WhiteTextRect)-TextSize.cx)/2),
  815.                     lpcwd->WhiteTextRect.top + ((RectHeight(lpcwd->WhiteTextRect)-TextSize.cy)/2), "Icon On White", 13 );
  816.     GetTextExtentPoint32( hDC, "XOR Mask", 8, &TextSize );
  817.     TextOut( hDC, lpcwd->XORTextRect.left + ((RectWidth(lpcwd->XORTextRect)-TextSize.cx)/2),
  818.                     lpcwd->XORTextRect.top + ((RectHeight(lpcwd->XORTextRect)-TextSize.cy)/2), "XOR Mask", 8 );
  819.     GetTextExtentPoint32( hDC, "AND Mask", 8, &TextSize );
  820.     TextOut( hDC, lpcwd->ANDTextRect.left + ((RectWidth(lpcwd->ANDTextRect)-TextSize.cx)/2),
  821.                     lpcwd->ANDTextRect.top + ((RectHeight(lpcwd->ANDTextRect)-TextSize.cy)/2), "AND Mask", 8 );
  822. }
  823. /* End EraseBackground() ***************************************************/
  824.  
  825.  
  826.  
  827.  
  828. /****************************************************************************
  829. *
  830. *     FUNCTION: CreateChildren
  831. *
  832. *     PURPOSE:  Create the listbox, fills it with entries
  833. *
  834. *     PARAMS:   HWND hWnd - The MDI window of interest
  835. *
  836. *     RETURNS:  BOOL - TRUE for success, FALSE for failure
  837. *
  838. * History:
  839. *                July '95 - Created
  840. *
  841. \****************************************************************************/
  842. BOOL CreateChildren( HWND hWnd )
  843. {
  844.     RECT                ClientRect, TempRect;
  845.     LPCHILDWINDOWDATA    lpcwd;
  846.     HDC                    hDC;
  847.     SIZE                size;
  848.  
  849.     // Get the data associated with this window
  850.     if( (lpcwd = (LPCHILDWINDOWDATA)GetWindowLong( hWnd, GWL_USERDATA )) == NULL )
  851.         return FALSE;
  852.     // Just how big is this window?
  853.     GetClientRect( hWnd, &ClientRect );
  854.     // Calculate listbox size and position
  855.     SetRect( &(lpcwd->BoxRect), 10, ClientRect.bottom-30, (MAX_ICON_WIDTH*2)+14, ClientRect.bottom+50 );
  856.     // Create the listbox
  857.     if((lpcwd->hWndFormatListBox=CreateChildListBox( hWnd, ID_FORMAT_BOX, &(lpcwd->BoxRect) )) == NULL )
  858.         return FALSE;
  859.     // If we have an icon resource
  860.     if( lpcwd->lpIR != NULL )
  861.     {
  862.         UINT    i, nIndex;
  863.         TCHAR    szBuffer[256];
  864.  
  865.         // For each image in the resoure
  866.         for(i=0;i<lpcwd->lpIR->nNumImages;i++)
  867.         {
  868.             // Add the type of the image to the listbox
  869.             wsprintf( szBuffer, "%dx%d, %d Bit Color", lpcwd->lpIR->IconImages[i].Width, 
  870.                         lpcwd->lpIR->IconImages[i].Height, lpcwd->lpIR->IconImages[i].Colors );
  871.             nIndex = SendMessage( lpcwd->hWndFormatListBox, CB_ADDSTRING, 0, (LPARAM)szBuffer );
  872.         }
  873.         // Select the first entry
  874.         SendMessage( lpcwd->hWndFormatListBox,     CB_SETCURSEL, (WPARAM)0, (LPARAM)0 );
  875.     }
  876.     // Adjust the box size based on the listbox's real size
  877.     GetClientRect( lpcwd->hWndFormatListBox, &TempRect );
  878.     lpcwd->BoxRect.bottom = lpcwd->BoxRect.top + TempRect.bottom;
  879.  
  880.     // How big is text these days?
  881.     hDC = GetDC( hWnd );
  882.     GetTextExtentPoint32( hDC, "Icon on Black", 13, &size );
  883.     ReleaseDC( hWnd, hDC );
  884.  
  885.     // Set the rectangles for the various squares to be drawn later
  886. #define DIVIDER 5
  887.     SetRect( &(lpcwd->DrawingRect), 10, 10, (MAX_ICON_WIDTH*2)+14, 20 + (MAX_ICON_HEIGHT*2) + (TempRect.bottom*2) );
  888.     SetRect( &(lpcwd->BlackRect), lpcwd->DrawingRect.left, lpcwd->DrawingRect.top, lpcwd->DrawingRect.left + MAX_ICON_WIDTH + 1, lpcwd->DrawingRect.top + MAX_ICON_HEIGHT + 1 );
  889.     SetRect( &(lpcwd->BlackTextRect), lpcwd->BlackRect.left, lpcwd->BlackRect.bottom+1, lpcwd->BlackRect.right, lpcwd->BlackRect.bottom + TempRect.bottom + 1 );
  890.     SetRect( &(lpcwd->WhiteRect), lpcwd->BlackRect.right+1, lpcwd->BlackRect.top, lpcwd->DrawingRect.right, lpcwd->BlackRect.bottom );
  891.     SetRect( &(lpcwd->WhiteTextRect), lpcwd->WhiteRect.left, lpcwd->WhiteRect.bottom+1, lpcwd->WhiteRect.right, lpcwd->WhiteRect.bottom + TempRect.bottom + 1 );
  892.     SetRect( &(lpcwd->XORRect),    lpcwd->BlackTextRect.left, lpcwd->BlackTextRect.bottom + 1 + DIVIDER, lpcwd->BlackRect.right, lpcwd->BlackTextRect.bottom + 2 + DIVIDER + MAX_ICON_HEIGHT ); 
  893.     SetRect( &(lpcwd->XORTextRect),    lpcwd->XORRect.left, lpcwd->XORRect.bottom + 1, lpcwd->XORRect.right, lpcwd->DrawingRect.bottom ); 
  894.     SetRect( &(lpcwd->ANDRect),    lpcwd->WhiteTextRect.left, lpcwd->WhiteTextRect.bottom + 1 + DIVIDER, lpcwd->WhiteRect.right, lpcwd->WhiteTextRect.bottom + 2 + DIVIDER + MAX_ICON_HEIGHT ); 
  895.     SetRect( &(lpcwd->ANDTextRect),    lpcwd->ANDRect.left, lpcwd->ANDRect.bottom + 1, lpcwd->ANDRect.right, lpcwd->DrawingRect.bottom ); 
  896. #undef DIVIDER
  897.  
  898.     return TRUE;
  899. }
  900. /* End CreateChildren() ****************************************************/
  901.  
  902.  
  903.  
  904.  
  905. /****************************************************************************
  906. *
  907. *     FUNCTION: CreateChildListBox
  908. *
  909. *     PURPOSE:  Creates a listbox and shows it
  910. *
  911. *     PARAMS:   HWND   hWndParent - The MDI window to be a parent
  912. *               UINT   ID         - the ID of the new listbox
  913. *               LPRECT lpRect     - the RECT for the listbox
  914. *
  915. *     RETURNS:  HWND - handle to listbox window, NULL for failure
  916. *
  917. * History:
  918. *                July '95 - Created
  919. *
  920. \****************************************************************************/
  921. HWND CreateChildListBox( HWND hWndParent, UINT ID, LPRECT lpRect )
  922. {
  923.     HWND hWnd;
  924.  
  925.     hWnd = CreateWindow( "COMBOBOX", "", CBS_DROPDOWNLIST | CBS_DISABLENOSCROLL | WS_CHILD | WS_VSCROLL,
  926.                         lpRect->left, lpRect->top, 
  927.                         lpRect->right - lpRect->left + 1, lpRect->bottom - lpRect->top + 1,
  928.                         hWndParent, (HMENU)ID, hInst, 0 );
  929.     if( hWnd != NULL )
  930.         ShowWindow( hWnd, SW_SHOW );
  931.     return hWnd;
  932. }
  933. /* End CreateChildListBox() ************************************************/
  934.  
  935.  
  936.  
  937.  
  938. /****************************************************************************
  939. *
  940. *     FUNCTION: AddFormatDlgProc
  941. *
  942. *     PURPOSE:  Dialog Procedure for "Add Format" dialog
  943. *
  944. *     PARAMS:   HWND hWnd     - This dialog's window handle
  945. *               UINT Msg      - Which Message?
  946. *               WPARAM wParam - message parameter
  947. *               LPARAM lParam - message parameter
  948. *
  949. *     RETURNS:  BOOL - TRUE for OK, FALSE for Cancel
  950. *
  951. * History:
  952. *                July '95 - Created
  953. *
  954. \****************************************************************************/
  955. BOOL CALLBACK AddFormatDlgProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
  956. {
  957.     // Support all DIB color formats known at this time
  958.     #define MAX_COLOR_FORMAT    5
  959.     TCHAR    ColorFormats[MAX_COLOR_FORMAT+1][20] = { "Monochrome (1bpp)", "16 Color (4bpp)", "256 Color (8bpp)",
  960.                                     "16 Bit Color", "24 Bit Color", "32 Bit Color" };
  961.     UINT    Bits[MAX_COLOR_FORMAT+1] = { 1, 4, 8, 16, 24, 32 };
  962.     static    bSquareOnly = TRUE;
  963.     static    LPARAM lInitParam;
  964.  
  965.  
  966.     switch( Msg )
  967.     {
  968.         // Dialog is being initialized
  969.         case WM_INITDIALOG:
  970.         {
  971.             TCHAR    szBuffer[100];
  972.  
  973.             // We are passed a pointer to a LPICONIMAGE in lParam, save it
  974.             lInitParam = lParam;
  975.             // Set the range and position of the sliders
  976.             SendDlgItemMessage( hWnd, ID_WIDTHSLIDER, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(MIN_ICON_WIDTH,MAX_ICON_WIDTH) );
  977.             SendDlgItemMessage( hWnd, ID_WIDTHSLIDER, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)MIN_ICON_WIDTH );
  978.             wsprintf( szBuffer, "%d Width", MIN_ICON_WIDTH );
  979.             SetDlgItemText( hWnd, ID_WIDTHTEXT, szBuffer );
  980.             SendDlgItemMessage( hWnd, ID_HEIGHTSLIDER, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(MIN_ICON_HEIGHT,MAX_ICON_HEIGHT) );
  981.             SendDlgItemMessage( hWnd, ID_HEIGHTSLIDER, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)MIN_ICON_HEIGHT );
  982.             wsprintf( szBuffer, "%d Height", MIN_ICON_HEIGHT );
  983.             SetDlgItemText( hWnd, ID_HEIGHTTEXT, szBuffer );
  984.             SendDlgItemMessage( hWnd, ID_COLORSLIDER, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0,MAX_COLOR_FORMAT) );
  985.             SendDlgItemMessage( hWnd, ID_COLORSLIDER, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)2);
  986.             SetDlgItemText( hWnd, ID_COLORTEXT, ColorFormats[2] );
  987.             CheckDlgButton( hWnd, IDC_SQUAREONLY, bSquareOnly );
  988.         }
  989.         break; // End WM_INITDIALOG
  990.  
  991.         // Scroll message from the sliders
  992.         case WM_HSCROLL:
  993.         {
  994.             int    nPos;
  995.             TCHAR    szBuffer[100];
  996.  
  997.             // Get the current position
  998.             if( ( LOWORD(wParam) == TB_THUMBPOSITION ) || ( LOWORD(wParam) == TB_THUMBTRACK ) )
  999.                 nPos = HIWORD( wParam );
  1000.             else
  1001.                 nPos = SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0 );
  1002.             // Was it the width slider?
  1003.             if( (HWND)lParam == GetDlgItem( hWnd, ID_WIDTHSLIDER) )
  1004.             {
  1005.                 // Update the text
  1006.                 wsprintf( szBuffer, "%d Width", nPos );
  1007.                 SetDlgItemText( hWnd, ID_WIDTHTEXT, szBuffer );
  1008.                 // If dealing with width=height, adjust height too
  1009.                 if( bSquareOnly )
  1010.                 {
  1011.                     SendDlgItemMessage( hWnd, ID_HEIGHTSLIDER, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)nPos );
  1012.                     wsprintf( szBuffer, "%d Height", nPos );
  1013.                     SetDlgItemText( hWnd, ID_HEIGHTTEXT, szBuffer );
  1014.                 }
  1015.             }
  1016.             else
  1017.             {
  1018.                 // Was it the height slider?
  1019.                 if( (HWND)lParam == GetDlgItem( hWnd, ID_HEIGHTSLIDER) )
  1020.                 {
  1021.                     // Update the text
  1022.                     wsprintf( szBuffer, "%d Height", nPos );
  1023.                     SetDlgItemText( hWnd, ID_HEIGHTTEXT, szBuffer );
  1024.                     // If dealing with width=height, adjust width too
  1025.                     if( bSquareOnly )
  1026.                     {
  1027.                         SendDlgItemMessage( hWnd, ID_WIDTHSLIDER, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)nPos );
  1028.                         wsprintf( szBuffer, "%d Width", nPos );
  1029.                         SetDlgItemText( hWnd, ID_WIDTHTEXT, szBuffer );
  1030.                     }
  1031.                 }
  1032.                 else
  1033.                 {
  1034.                     // Was it the color slider?
  1035.                     if( (HWND)lParam == GetDlgItem( hWnd, ID_COLORSLIDER) )
  1036.                     {
  1037.                         // Update the text
  1038.                         SetDlgItemText( hWnd, ID_COLORTEXT, ColorFormats[nPos] );
  1039.                     }
  1040.                 }
  1041.             }
  1042.         }
  1043.         break; // End WM_HSCROLL
  1044.  
  1045.         // Time to say 'goodbye'
  1046.         case WM_CLOSE:
  1047.             PostMessage( hWnd, WM_COMMAND, IDCANCEL, 0l );
  1048.         break; // End WM_CLOSE
  1049.  
  1050.  
  1051.         // Messages from user items - checkboxes etc
  1052.         case WM_COMMAND:
  1053.             switch( LOWORD(wParam) )
  1054.             {
  1055.                 // Checkbox for width=height restriction
  1056.                 case IDC_SQUAREONLY:
  1057.                     // Is it checked now?
  1058.                     bSquareOnly = IsDlgButtonChecked( hWnd, IDC_SQUAREONLY );
  1059.                     // If it is, set height equal to width
  1060.                     if( bSquareOnly )
  1061.                     {
  1062.                         int nPos;
  1063.                         TCHAR    szBuffer[100];
  1064.  
  1065.                         nPos = SendDlgItemMessage( hWnd, ID_WIDTHSLIDER, TBM_GETPOS, 0, 0 );
  1066.                         SendDlgItemMessage( hWnd, ID_HEIGHTSLIDER, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)nPos );
  1067.                         wsprintf( szBuffer, "%d Height", nPos );
  1068.                         SetDlgItemText( hWnd, ID_HEIGHTTEXT, szBuffer );
  1069.                     }
  1070.                 break; // End IDC_SQUAREONLY
  1071.  
  1072.                 // Add Format button has been pressed
  1073.                 case IDOK:
  1074.                 {
  1075.                     LPICONIMAGE    lpii;
  1076.  
  1077.                     // Were we passed a valid LPICONIMAGE pointer?
  1078.                     if( ((LPICONIMAGE)lInitParam) != NULL )
  1079.                     {
  1080.                         // allocate the new ICONIMAGE
  1081.                         if( (lpii = malloc( sizeof( ICONIMAGE ) )) == FALSE )
  1082.                             EndDialog( hWnd, FALSE );
  1083.                         else
  1084.                         {
  1085.                             // initialize it
  1086.                             ZeroMemory( lpii, sizeof( ICONIMAGE ) );
  1087.                             lpii->Width = SendDlgItemMessage( hWnd, ID_WIDTHSLIDER, TBM_GETPOS, 0, 0 );
  1088.                             lpii->Height = SendDlgItemMessage( hWnd, ID_HEIGHTSLIDER, TBM_GETPOS, 0, 0 );
  1089.                             lpii->Colors = Bits[SendDlgItemMessage( hWnd, ID_COLORSLIDER, TBM_GETPOS, 0, 0 )];
  1090.                             // update the pointer that we were passed
  1091.                             *(LPICONIMAGE *)lInitParam = lpii;
  1092.                             // bail
  1093.                             EndDialog( hWnd, TRUE );
  1094.                         }
  1095.                     }
  1096.                     else
  1097.                     {
  1098.                         // bail
  1099.                         EndDialog( hWnd, FALSE );
  1100.                     }
  1101.                 }
  1102.                 break; // End IDOK
  1103.  
  1104.                 // Time to cancel
  1105.                 case IDCANCEL:
  1106.                     EndDialog( hWnd, FALSE );
  1107.                 break; // End IDCANCEL
  1108.  
  1109.             }
  1110.         break;
  1111.         default:
  1112.             return FALSE;
  1113.         break;
  1114.     }
  1115.     return TRUE;
  1116.     #undef MAX_COLOR_FORMAT
  1117. }
  1118. /* End AddFormatDlgProc() ************************************************/
  1119.