home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / audio / idfedit / head.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  13KB  |  454 lines

  1. //**  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. //**  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
  3. //**  TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR
  4. //**  A PARTICULAR PURPOSE.
  5. //**
  6. //**  Copyright (C) 1993 - 1997 Microsoft Corporation. All Rights Reserved.
  7. //**
  8. //**  head.c
  9. //**
  10. //**  DESCRIPTION:
  11. //**     Window proc for IDF head pane
  12. //**
  13. //************************************************************************
  14.  
  15. #include <windows.h>
  16. #include <windowsx.h>
  17. #include <mmsystem.h>
  18. #include <commctrl.h>
  19.  
  20. #include "idfedit.h"
  21. #include "tridee.h"
  22.  
  23. /*+
  24.  *
  25.  *-=================================================================*/
  26.  
  27. STATICFN void LoadTree (
  28.    HWND      hWndT,
  29.    struct _instrum_info * piSelect,
  30.    LPIDFHEAD pih)
  31. {
  32.    HTREEITEM htiSelect = NULL;
  33.    HTREEITEM htiParent = TVI_ROOT;
  34.    struct _instrum_info * pi;
  35.    UINT  ii;
  36.  
  37.    TreeView_DeleteAllItems(hWndT);
  38.  
  39.    for (pi = &pih->ai[ii = 0]; ii < pih->nInstrum; ++ii, ++pi)
  40.       {
  41.       TV_INSERTSTRUCT ti;
  42.       HTREEITEM       hti;
  43.  
  44.       ZeroMemory (&ti, sizeof(ti));
  45.  
  46.       ti.hParent        = TVI_ROOT;
  47.       ti.hInsertAfter   = TVI_SORT;
  48.       ti.item.mask      = TVIF_TEXT | TVIF_STATE | TVIF_PARAM;
  49.       ti.item.state     = TVIS_EXPANDED;
  50.       ti.item.stateMask = 0xFF;
  51.       ti.item.lParam    = (LPARAM)pi;
  52.  
  53.       if (pi->pInstrum)
  54.          ti.item.pszText = pi->pInstrum->szInstID;
  55.       else if (pi->pList)
  56.          {
  57.          LPRIFF pRiff = FindListChunk(pi->pList, FCC_hdr);
  58.          if (pRiff && pRiff->cb >= sizeof(IDFHEADER))
  59.             ti.item.pszText = ((LPIDFHEADER)(pRiff+1))->abInstID;
  60.          }                                                             
  61.          
  62.  
  63.       assert (ti.item.pszText);
  64.       if ( ! ti.item.pszText)
  65.          continue;
  66.  
  67.       hti = TreeView_InsertItem (hWndT, &ti);
  68.  
  69.       if (piSelect && (piSelect == pi))
  70.          htiSelect = hti;
  71.       }
  72.  
  73.    if (htiSelect)
  74.       {
  75.       assert (piSelect);
  76.       TreeView_SelectItem (hWndT, htiSelect);
  77.       }
  78. }
  79.  
  80. /*+
  81.  *  HeadPrivate
  82.  *
  83.  *-=================================================================*/
  84.  
  85. static LONG WINAPI HeadPrivate (
  86.    HWND   hWnd,
  87.    UINT   wMsgID,
  88.    WPARAM wParam,
  89.    LPARAM lParam)
  90.    {
  91.    LONG       lRet = 0l;               // return value from this routine
  92.    LPIDFHEAD  pih;
  93.  
  94.    pih = (LPVOID) GetWindowLong (hWnd, GWL_USERDATA);
  95.  
  96.    switch (wMsgID)
  97.       {
  98.       case HM_REFRESH_TREE:
  99.          LoadTree(pih->hWndTree, pih->piSelect, pih);
  100.          InvalidateRect (hWnd, NULL, FALSE);
  101.          break;
  102.       }
  103.  
  104.    return lRet;
  105.    }
  106.  
  107. /*+
  108.  *  HeadCommands
  109.  *
  110.  *-=================================================================*/
  111.  
  112. LONG WINAPI HeadCommands (
  113.    HWND   hWnd,
  114.    WPARAM wParam,
  115.    LPARAM lParam)
  116.    {
  117.    LONG       lRet = 0l;               // return value from this routine
  118.    LPIDFHEAD  pih;
  119.  
  120.    pih = (LPVOID) GetWindowLong (hWnd, GWL_USERDATA);
  121.  
  122.    switch (GET_WM_COMMAND_ID(wParam,lParam))
  123.       {
  124.       }
  125.  
  126.    return lRet;
  127.    }
  128.  
  129. /*+
  130.  *  
  131.  *
  132.  *-=================================================================*/
  133.  
  134. STATICFN BOOL WINAPI HandleInstrumentsSelChange (
  135.     HWND      hWnd,
  136.     LPNMHDR   lpnm,
  137.     LPIDFHEAD pih)
  138. {
  139.    LPNM_TREEVIEW pntv = (LPVOID)lpnm;
  140.    LPTV_ITEM     pti  = &pntv->itemNew;
  141.    //TV_ITEM       ti;
  142.    struct _instrum_info * pi;
  143.    //char          szSingle[MAX_ALIAS];
  144.    //BOOL          bChange = FALSE;
  145.  
  146.    if (!pih)
  147.       return FALSE;
  148.  
  149.    // if there was a valid previous selection.
  150.    // make sure that there a now changes to be
  151.    // saved off before we allow selection to proceed.
  152.    //
  153.    pi = (LPVOID)pntv->itemNew.lParam;
  154.    if (pi && !pi->pInstrum &&
  155.        (pih->piSelect == pi) && 
  156.        (pih->pInstrumSelect == &pih->instrum) &&
  157.        (pih->instrum.bChanged))
  158.       {
  159.       assert (0);
  160.       // need to save changes made to the instrument data
  161.       //
  162.       pi->pInstrum = CopyForEditing (&pih->instrum, sizeof(pih->instrum));
  163.       pih->bChanged = TRUE;
  164.       }
  165.  
  166.    // setup ti to get text & # of children
  167.    // from the IDF filename entry.
  168.    //
  169.    //ti.mask       = TVIF_PARAM;
  170.    //ti.mask       = TVIF_TEXT | TVIF_PARAM;
  171.    //ti.pszText    = szSingle;
  172.    //ti.cchTextMax = NUMELMS(szSingle);
  173.    //ti.hItem      = pti->hItem;
  174.    //TreeView_GetItem (lpnm->hwndFrom, &ti);
  175.    //pi = (LPVOID)ti.lParam;
  176.    pi = (LPVOID)pti->lParam;
  177.    if (!pi)
  178.       return FALSE;
  179.  
  180.    // if the selected instrument has no editable data set, 
  181.    // copy the raw RIFF data into the temp edit set
  182.    // and display instrument settings from there.
  183.    //
  184.    pih->piSelect = NULL;
  185.    pih->pInstrumSelect = NULL;
  186.    if (pih->nInstrum)
  187.       {
  188.       pih->piSelect = pi;
  189.       pih->pInstrumSelect = pi->pInstrum;
  190.       if (!pi->pInstrum)
  191.          {
  192.          CopyInstrumData (&pih->instrum, pi->pList);
  193.          pih->pInstrumSelect = &pih->instrum;
  194.          }
  195.       }
  196.  
  197.    View_SetData (pih->hWndInstrument, pih->pInstrumSelect);
  198.    View_InvalidateLines (pih->hWndInstrument, 0, 0);
  199.    return TRUE;
  200. }
  201.  
  202. /*+
  203.  *  HeadNotifications
  204.  *
  205.  *-=================================================================*/
  206.  
  207. LONG WINAPI HeadNotifications (
  208.    HWND     hWnd,
  209.    LPNMHDR  lpnm)
  210.    {
  211.    LONG       lRet = 0l;               // return value from this routine
  212.    LPIDFHEAD  pih;
  213.  
  214.    pih = (LPVOID) GetWindowLong (hWnd, GWL_USERDATA);
  215.  
  216.    switch (lpnm->idFrom)
  217.       {
  218.       case IDL_INSTRUMENTS:
  219.          switch (lpnm->code)
  220.             {
  221.             case TVN_SELCHANGED:
  222.                 HandleInstrumentsSelChange (hWnd, lpnm, pih);
  223.                 break;
  224.  
  225.             //case NM_DBLCLK:
  226.             //    break;
  227.  
  228.             case TVN_ENDLABELEDIT:
  229.                 {
  230.                 TV_DISPINFO * ptv = (LPVOID)lpnm;
  231.                 struct _instrum_info * pi = (LPVOID)ptv->item.lParam;
  232.  
  233.                 if (!pi)
  234.                    break;
  235.  
  236.                 if (!pi->pInstrum)
  237.                    {
  238.                    if (pih->piSelect == pi && pih->pInstrumSelect == &pih->instrum)
  239.                       pi->pInstrum = CopyForEditing (&pih->instrum, sizeof(pih->instrum));
  240.                    else
  241.                       {
  242.                       assert (0); // shoundn't be able to label edit without first selecting
  243.                       pi->pInstrum = HeapAlloc (gs.idf.hEditHeap, 0, sizeof(INSTRUMENT));
  244.                       CopyInstrumData (pi->pInstrum, pi->pList);
  245.                       }
  246.                    }
  247.                   
  248.                 lstrcpyn (pi->pInstrum->szInstID, ptv->item.pszText, NUMELMS(pi->pInstrum->szInstID));
  249.                 pi->pInstrum->bChanged = TRUE;
  250.                 pih->bChanged = TRUE;
  251.                 View_InvalidateLines (pih->hWndInstrument, 0, 0);
  252.                 lRet = 1;
  253.                 }
  254.                 break;
  255.             }
  256.          break;
  257.  
  258.       case IDC_CURRENT_INSTRUM:
  259.          switch (lpnm->code)
  260.             {
  261.             case VN_CHANGE:
  262.                if (pih->pInstrumSelect)
  263.                   {
  264.                   if (pih->pInstrumSelect == &pih->instrum)
  265.                      {
  266.                      assert (!pih->piSelect->pInstrum);
  267.                      if ( ! pih->piSelect->pInstrum)
  268.                         {
  269.                         pih->pInstrumSelect =
  270.                         pih->piSelect->pInstrum = CopyForEditing (&pih->instrum, sizeof(pih->instrum));
  271.                         View_SetData (pih->hWndInstrument, pih->pInstrumSelect);
  272.                         View_InvalidateLines (pih->hWndInstrument, 0, 0);
  273.                         }
  274.                      }
  275.                   pih->pInstrumSelect->bChanged = TRUE;
  276.                   pih->bChanged = TRUE;
  277.                   }
  278.                else
  279.                   {
  280.                   assert (0);
  281.                   }
  282.                break;
  283.             }
  284.          break;
  285.       }
  286.  
  287.    return lRet;
  288.    }
  289.  
  290. /*+
  291.  *  HeadWndProc
  292.  *
  293.  *-=================================================================*/
  294.  
  295. LONG CALLBACK HeadWndProc (
  296.    HWND   hWnd,
  297.    UINT   wMsgID,
  298.    WPARAM wParam,
  299.    LPARAM lParam)
  300.    {
  301.    LONG       lRet = 0l;               // return value from this routine
  302.    if (wMsgID >= WM_USER && wMsgID < 0x8000)
  303.       lRet = HeadPrivate (hWnd, wMsgID, wParam, lParam);
  304.    else
  305.    switch (wMsgID)
  306.       {
  307.       case WM_COMMAND:
  308.          lRet = HeadCommands (hWnd, wParam, lParam);
  309.          break;
  310.  
  311.       case WM_NOTIFY:
  312.          lRet = HeadNotifications (hWnd, (LPNMHDR)lParam);
  313.          break;
  314.  
  315.       case WM_SIZE:
  316.          {
  317.          LPIDFHEAD pih = (LPVOID) GetWindowLong (hWnd, GWL_USERDATA);
  318.          HDC hDC;
  319.          TEXTMETRIC tm;
  320.          #define BORDER 0
  321.  
  322.          hDC = GetDC (hWnd);
  323.          //if (pih->hFont)
  324.          //   SelectObject (hDC, pih->hFont);
  325.          GetTextMetrics (hDC, &tm);
  326.          pih->ptClient.y = tm.tmHeight + tm.tmExternalLeading + 6;
  327.          pih->ptClient.x = 0;
  328.          ReleaseDC (hWnd, hDC);
  329.  
  330.          pih->sClient.cx = LOWORD(lParam) - pih->ptClient.x;
  331.          pih->sClient.cy = HIWORD(lParam) - pih->ptClient.y;
  332.  
  333.          SetWindowPos (pih->hWndTree, NULL,
  334.                        pih->ptClient.x, pih->ptClient.y,
  335.                        pih->cxTree, pih->sClient.cy,
  336.                        SWP_NOZORDER);
  337.  
  338.          SetWindowPos (pih->hWndInstrument, NULL,
  339.                        pih->ptClient.x + pih->cxTree + BORDER, pih->ptClient.y,
  340.                        pih->sClient.cx - pih->cxTree - BORDER, pih->sClient.cy,
  341.                        SWP_NOZORDER);
  342.          }
  343.          break;
  344.  
  345.       case WM_CREATE:
  346.          {
  347.          LPCREATESTRUCT    lpCreate = (LPCREATESTRUCT)lParam;
  348.          LPIDFHEAD         pih;
  349.  
  350.          SetWindowLong (hWnd, GWL_USERDATA, 0);
  351.  
  352.          pih = (LPVOID)lpCreate->lpCreateParams;
  353.          if (!pih)
  354.              return -1;
  355.          SetWindowLong (hWnd, GWL_USERDATA, (LONG)pih);
  356.  
  357.          pih->cxTree = LOWORD(GetDialogBaseUnits()) * 20;
  358.  
  359.          pih->hWndTree = 
  360.              CreateWindowEx (fdwExStyle | WS_EX_NOPARENTNOTIFY,
  361.                              WC_TREEVIEW,
  362.                              "",
  363.                              TVS_DISABLEDRAGDROP |
  364.                              TVS_SHOWSELALWAYS |
  365.                              TVS_EDITLABELS |
  366.                              WS_CHILD | WS_VISIBLE | WS_BORDER,
  367.                              0, 0, pih->cxTree, 0,
  368.                              hWnd,
  369.                              (HMENU)IDL_INSTRUMENTS,
  370.                              hInst,
  371.                              NULL);
  372.          if ( ! pih->hWndTree)
  373.             lRet = -1;
  374.  
  375.          pih->hWndInstrument = 
  376.              CreateWindowEx (fdwExStyle | WS_EX_NOPARENTNOTIFY,
  377.                              cszInstrumClass,
  378.                              "",
  379.                              WS_CHILD | WS_VISIBLE | WS_BORDER,
  380.                              pih->cxTree + 6, 0, 200, 0,
  381.                              hWnd,
  382.                              (HMENU)IDC_CURRENT_INSTRUM,
  383.                              hInst,
  384.                              &pih->vi);
  385.          if ( ! pih->hWndInstrument)
  386.             lRet = -1;
  387.  
  388.          LoadTree (pih->hWndTree, &pih->ai[0], pih);
  389.          LoadString (hInst, IDS_TREE_LABEL, pih->szTreeLabel, NUMELMS(pih->szTreeLabel));
  390.          LoadString (hInst, IDS_VIEW_LABEL, pih->szViewLabel, NUMELMS(pih->szViewLabel));
  391.  
  392.          TrideeCreate(hWnd);
  393.          }
  394.          break;
  395.  
  396.       case WM_DESTROY:
  397.          {
  398.          LPIDFHEAD pih = (LPVOID) GetWindowLong (hWnd, GWL_USERDATA);
  399.          if (pih && pih != &gs.idf)
  400.             HeapFree (GetProcessHeap(), 0, pih);
  401.          SetWindowLong (hWnd, GWL_USERDATA, 0);
  402.          TrideeDestroy(hWnd);
  403.          }
  404.          break;
  405.  
  406.       case WM_ERASEBKGND:
  407.          {
  408.          RECT rc;
  409.          LPIDFHEAD pih = (LPVOID) GetWindowLong (hWnd, GWL_USERDATA);
  410.          HDC  hDC = (HDC)wParam;
  411.          int  cx = 2;
  412.          int  cy = 4;
  413.  
  414.          lRet = DefWindowProc (hWnd, wMsgID, wParam, lParam);
  415.  
  416.          GetClientRect (hWnd, &rc);
  417.  
  418.          SetTextColor (hDC, GetSysColor (COLOR_BTNTEXT));
  419.          SetBkColor (hDC, GetSysColor (COLOR_BTNFACE));
  420.  
  421.          SetTextAlign (hDC, TA_TOP | TA_LEFT);
  422.          ExtTextOut (hDC, cx, cy, ETO_CLIPPED, &rc, 
  423.                      pih->szTreeLabel, lstrlen(pih->szTreeLabel), NULL);
  424.  
  425.          cx = pih->ptClient.x + pih->cxTree + BORDER +2;
  426.          ExtTextOut (hDC, cx, cy, ETO_CLIPPED, &rc, 
  427.                      pih->szViewLabel, lstrlen(pih->szViewLabel), NULL);
  428.  
  429.          rc.bottom = rc.top + 2;
  430.          TrideeWellShadow(hDC, &rc);
  431.          }
  432.          break;
  433.  
  434.       case WM_PAINT:
  435.          {
  436.          PAINTSTRUCT ps;           // structure for BeginPaint
  437.          HDC         hDC;          // DC to draw info into
  438.  
  439.          LPIDFHEAD pih = (LPVOID) GetWindowLong (hWnd, GWL_USERDATA);
  440.  
  441.          // and draw the info into our client area
  442.          //
  443.          hDC = BeginPaint (hWnd, &ps);
  444.          EndPaint (hWnd, &ps);
  445.          }
  446.          break;
  447.  
  448.       default:
  449.          lRet = DefWindowProc (hWnd, wMsgID, wParam, lParam);
  450.       }
  451.  
  452.    return lRet;
  453.    }
  454.