home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 10 / ioProg_10.iso / soft / platsdk / inetwork.exe / TAPI-S.cab / 56ACDSMPL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-01  |  75.5 KB  |  2,496 lines

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  ACDSMPL.C
  4. //
  5. //  Handles all the UI for ACDSample
  6. //
  7. //////////////////////////////////////////////////////////////////////////////
  8.  
  9. #include <windows.h>
  10. #include <commctrl.h>
  11. #include <commdlg.h>
  12. #include <tapi.h>
  13. #include <stdlib.h>
  14. #include "resource.h"
  15. #include "acdsmpl.h"
  16.  
  17.  
  18. //////////////////////////////////////////////////////////////////////////////
  19. //  PROTOTYPES
  20. //////////////////////////////////////////////////////////////////////////////
  21. static BOOL CreateMainWindow (int nCmdShow);
  22.  
  23. static LRESULT CALLBACK MainDlgProc (HWND   hwnd,
  24.                                      UINT   uMsg,
  25.                                      WPARAM wParam,
  26.                                      LPARAM lParam);
  27. void MySetWindow(HWND, int);
  28. void MySaveWindow(HWND);
  29. BOOL ResizeWindows(BOOL bSizeBar, DWORD dwBarLocation);
  30. HTREEITEM AddItemToTree(HTREEITEM hParent,
  31.                         LPTSTR lpszName,
  32.                         LPARAM lParam,
  33.                         HTREEITEM * phItem);
  34. BOOL DoPopupMenu(HTREEITEM hItem, POINT pt);
  35. BOOL DeleteLeafAndStruct(HTREEITEM hItem);
  36. BOOL CALLBACK ChangeGroupDlgProc(HWND   hWnd,
  37.                             UINT   uMsg,
  38.                             WPARAM wParam,
  39.                             LPARAM lParam);
  40. BOOL CALLBACK ChangeAgentDlgProc(HWND   hWnd,
  41.                             UINT   uMsg,
  42.                             WPARAM wParam,
  43.                             LPARAM lParam);
  44. BOOL CALLBACK AddGroupDlgProc(HWND   hWnd,
  45.                          UINT   uMsg,
  46.                          WPARAM wParam,
  47.                          LPARAM lParam);
  48. BOOL CALLBACK AddAgentDlgProc(HWND   hWnd,
  49.                          UINT   uMsg,
  50.                          WPARAM wParam,
  51.                          LPARAM lParam);
  52. LRESULT DoCommand(WPARAM wParam, LPARAM lParam);
  53. void AddGroupsToMenu(HTREEITEM hItem,
  54.                      HMENU hMenu);
  55. BOOL CALLBACK GroupAddToListProc(HWND   hWnd,
  56.                             UINT   uMsg,
  57.                             WPARAM wParam,
  58.                             LPARAM lParam);
  59. BOOL CALLBACK AgentAddToListProc(HWND   hWnd,
  60.                             UINT   uMsg,
  61.                             WPARAM wParam,
  62.                             LPARAM lParam);
  63. BOOL BuildLineList(HWND hWnd,
  64.                    DWORD dwDeviceID);
  65. BOOL BuildAddressList(HWND hWnd,
  66.                       HWND hParentWnd,
  67.                       DWORD dwDeviceID);
  68. BOOL InitializeTapi();
  69. BOOL CleanUp();
  70. BOOL UpdateGroupLeaf(PGROUP pGroup);
  71. BOOL DoAgentView();
  72. BOOL DoGroupView();
  73. BOOL ReadInFile();
  74. BOOL WriteToDisk();
  75.  
  76.  
  77.  
  78. //////////////////////////////////////////////////////////////////////////////
  79. //  GLOBALS
  80. //////////////////////////////////////////////////////////////////////////////
  81. ACDGLOBALS      g;
  82.  
  83. TCHAR gszACDSampleKey[]     = TEXT("Software\\Microsoft\\ACDSample");
  84. TCHAR gszPlacementValue[]   = TEXT("WindowPlacement");
  85. TCHAR gszBarLocation[]      = TEXT("BarLocation");
  86.  
  87.  
  88.  
  89. //////////////////////////////////////////////////////////////////////////////
  90. //
  91. // WinMain()
  92. //
  93. //////////////////////////////////////////////////////////////////////////////
  94. int WINAPI WinMain (HINSTANCE hInstance,
  95.                     HINSTANCE hPrevInstance,
  96.                     LPSTR     lpszCmdLine,
  97.                     int       nCmdShow)
  98. {
  99.     MSG msg;
  100.  
  101.     // initialize global variables
  102.     g.hInstance = hInstance;
  103.     g.pAgents = NULL;
  104.     g.pGroups = NULL;
  105.  
  106.     // init tapi stuff
  107.     if (!InitializeTapi())
  108.     {
  109.         MessageBox(NULL,
  110.                    TEXT("TAPI could not be initialized.\nVerify that")
  111.                    TEXT("your machine has TAPI devices installed"),
  112.                    TEXT("Cannot start ACDSMPL"),
  113.                    MB_OK);
  114.     }
  115.  
  116.     if (!CreateMainWindow(nCmdShow))
  117.     {
  118.         return 0;
  119.     }
  120.  
  121.     // main message loop
  122.     while (GetMessage(&msg, NULL, 0, 0))
  123.     {
  124.         if (!IsDialogMessage(g.hMainWnd,
  125.                              &msg))
  126.         {
  127.             TranslateMessage(&msg);
  128.             DispatchMessage(&msg);
  129.         }
  130.     }
  131.  
  132.     return 1;
  133. }
  134.  
  135.  
  136. /////////////////////////////////////////////////////////////////////////////
  137. //
  138. //  CreateMainWindow()
  139. //
  140. //////////////////////////////////////////////////////////////////////////////
  141. BOOL CreateMainWindow (int nCmdShow)
  142. {
  143.  
  144.     // InitCommonControls for TreeView control
  145.     InitCommonControls();
  146.  
  147.     // Create the main window
  148.     g.hMainWnd = CreateDialog(g.hInstance,
  149.                              MAKEINTRESOURCE(IDD_MAINDLG),
  150.                              NULL,
  151.                              MainDlgProc);
  152.  
  153.     if (g.hMainWnd == NULL)
  154.     {
  155.         return FALSE;
  156.     }
  157.  
  158.     // restore default location
  159.     MySetWindow(g.hMainWnd, nCmdShow);
  160.     
  161.     // store global hwnds
  162.     g.hTreeWnd = GetDlgItem(g.hMainWnd,
  163.                             IDC_TREEWND);
  164.  
  165.     g.hLogWnd = GetDlgItem(g.hMainWnd,
  166.                            IDC_EDITWND);
  167.  
  168.     if ((g.hTreeWnd == FALSE) || (g.hLogWnd == FALSE))
  169.     {
  170.         return FALSE;
  171.     }
  172.  
  173.     ResizeWindows(FALSE, 0);
  174.  
  175.     return TRUE;
  176. }
  177.  
  178.  
  179. /////////////////////////////////////////////////////////////////////////////
  180. //
  181. //  MainDlgProc()
  182. //
  183. //////////////////////////////////////////////////////////////////////////////
  184. LRESULT CALLBACK MainDlgProc (HWND   hWnd,
  185.                               UINT   uMsg,
  186.                               WPARAM wParam,
  187.                               LPARAM lParam)
  188. {
  189.     static BOOL     bButtonDown = FALSE;
  190.     
  191.     switch (uMsg)
  192.     {
  193.         case WM_INITDIALOG:
  194.             return TRUE;
  195.  
  196.         case WM_COMMAND:
  197.         {
  198.             LRESULT lResult;
  199.             
  200.             lResult = DoCommand(wParam, lParam);
  201.             return lResult;
  202.         }
  203.  
  204.         // button and mousemove messages tracked to move
  205.         // the bar between the treeview control and the
  206.         // edit control
  207.         case WM_LBUTTONDOWN:
  208.         {
  209.             bButtonDown = TRUE;
  210.             SetCapture(hWnd);
  211.             return 0;
  212.         }
  213.  
  214.         case WM_LBUTTONUP:
  215.         {
  216.             bButtonDown = FALSE;
  217.             ReleaseCapture();
  218.             return 0;
  219.         }
  220.  
  221.         case WM_MOUSEMOVE:
  222.         {
  223.             if (bButtonDown)
  224.             {
  225.                 ResizeWindows(TRUE, (DWORD)LOWORD(lParam));
  226.                 return 1;
  227.             }
  228.             break;
  229.         }
  230.  
  231.         case WM_SIZE:
  232.         {
  233.             ResizeWindows(FALSE, 0);
  234.             return 1;
  235.         }
  236.  
  237.         // catch right click in tree view to make
  238.         // popup menu
  239.         case WM_NOTIFY:
  240.         {
  241.             LPNMHDR     pnmhdr;
  242.             POINT       pt;
  243.             HTREEITEM   hItem;
  244.             TV_HITTESTINFO  hittestinfo;
  245.             RECT        rc;
  246.  
  247.             pnmhdr = (LPNMHDR)lParam;
  248.  
  249.             // make sure it's a right click and it's in the treeview
  250.             if ((pnmhdr->code != NM_RCLICK) || (pnmhdr->hwndFrom != g.hTreeWnd))
  251.             {
  252.                 break;
  253.             }
  254.  
  255.             GetCursorPos(&pt);
  256.             GetWindowRect(g.hTreeWnd,
  257.                           &rc);
  258.             
  259.             hittestinfo.pt.x = pt.x - rc.left;
  260.             hittestinfo.pt.y = pt.y - rc.top;
  261.  
  262.             // hittest to get the tree view item
  263.             hItem = TreeView_HitTest(g.hTreeWnd,
  264.                                      &hittestinfo);
  265.  
  266.             // only display a menu if the mouse is actually
  267.             // over the item (TVHT_ONITEM)
  268.             if (hItem == NULL || (!(hittestinfo.flags & TVHT_ONITEM)) )
  269.             {
  270.                 return TRUE;
  271.             }
  272.  
  273.             // select that item (right clicking will not select
  274.             // by default
  275.             TreeView_Select(g.hTreeWnd,
  276.                             hItem,
  277.                             TVGN_CARET);
  278.  
  279.             // create the menu
  280.             DoPopupMenu(hItem, pt);
  281.  
  282.             return TRUE;
  283.                            
  284.             
  285.         }
  286.         
  287.         case WM_CLOSE:
  288.  
  289.             // save the current window location
  290.             WriteToDisk();
  291.             CleanUp();
  292.             MySaveWindow(hWnd);
  293.             PostQuitMessage(0);
  294.             return 1;
  295.  
  296.         default:
  297.             break;
  298.     }
  299.     return 0;
  300. }
  301.  
  302.  
  303. ////////////////////////////////////////////////////////////////////////////////
  304. //
  305. //  ResizeWindows - Handles resizing the two child windows of the
  306. //      main window.  If bSizeBar is true, then the sizing is happening
  307. //      because the user is moving the bar.  if bSizeBar is false, the sizing
  308. //      is happening because of the WM_SIZE or something like that.
  309. //
  310. ////////////////////////////////////////////////////////////////////////////////
  311. BOOL ResizeWindows(BOOL bSizeBar, DWORD dwBarLocation)
  312. {
  313.     RECT            rc, rc2;
  314.     int             x;
  315.  
  316.     // is the user moving the bar?
  317.     if (!bSizeBar)
  318.     {
  319.         dwBarLocation = g.dwBarLocation;
  320.     }
  321.  
  322.     GetClientRect(g.hMainWnd, &rc);
  323.  
  324.     // make sure the bar is in a OK location
  325.     if (bSizeBar)
  326.     {
  327.         if ((LONG)dwBarLocation < GetSystemMetrics(SM_CXSCREEN)/WINDOWSCALEFACTOR)
  328.             return FALSE;
  329.  
  330.         if ((LONG)(rc.right - dwBarLocation) < GetSystemMetrics(SM_CXSCREEN)/WINDOWSCALEFACTOR)
  331.             return FALSE;
  332.     }
  333.  
  334.     // save the bar location
  335.     g.dwBarLocation = dwBarLocation;
  336.  
  337.     // get the size of the frame
  338.     x = GetSystemMetrics(SM_CXFRAME);
  339.  
  340.     // move tree windows
  341.     MoveWindow(g.hTreeWnd,
  342.                0,
  343.                0,
  344.                dwBarLocation,
  345.                rc.bottom,
  346.                TRUE);
  347.  
  348.     // get the size of the window (in case move window failed
  349.     GetClientRect(g.hTreeWnd, &rc2);
  350.  
  351.     // move the edit window with respect to the tree window
  352.     MoveWindow(g.hLogWnd,
  353.                rc2.right-rc2.left+x+SIZEBAR,
  354.                0,
  355.                rc.right-(rc2.right-rc2.left)-x-SIZEBAR,
  356.                rc.bottom,
  357.                TRUE);
  358.  
  359.     return TRUE;
  360. }
  361.  
  362. //////////////////////////////////////////////////////////////////////////////
  363. //
  364. //  MySetWindow - reads in the window placement from registry
  365. //  and sets the window and bar.
  366. //
  367. //////////////////////////////////////////////////////////////////////////////
  368. void MySetWindow(HWND hWnd, int nCmdShow)
  369. {
  370.     WINDOWPLACEMENT     pwp;
  371.     HKEY                hKey;
  372.     DWORD               dwDataSize;
  373.     DWORD               dwDataType;
  374.     RECT                rc;
  375.  
  376.     pwp.length = sizeof(WINDOWPLACEMENT);
  377.  
  378.     // open the key and read in the WINDOWPLACEMENT structure
  379.     RegOpenKeyEx(HKEY_CURRENT_USER,
  380.                  gszACDSampleKey,
  381.                  0,
  382.                  KEY_ALL_ACCESS,
  383.                  &hKey);
  384.  
  385.     dwDataSize = sizeof(pwp);
  386.     
  387.     if ( RegQueryValueEx(hKey,
  388.                          gszPlacementValue,
  389.                          0,
  390.                          &dwDataType,
  391.                          (LPBYTE)&pwp,
  392.                          &dwDataSize) )
  393.     {
  394.         // if it fails, default
  395.         ShowWindow(g.hMainWnd, nCmdShow);
  396.         GetWindowRect(g.hMainWnd, &rc);
  397.         g.dwBarLocation = (rc.right - rc.left) / 2;
  398.     }
  399.     else
  400.     {
  401.         // if it succeeds, set the window and bar
  402.         dwDataSize = sizeof(DWORD);
  403.         
  404.         if (RegQueryValueEx(hKey,
  405.                             gszBarLocation,
  406.                             0,
  407.                             &dwDataType,
  408.                             (LPBYTE)&g.dwBarLocation,
  409.                             &dwDataSize))
  410.         {
  411.             g.dwBarLocation = (pwp.rcNormalPosition.right - pwp.rcNormalPosition.left) / 2;
  412.         }
  413.  
  414.         SetWindowPlacement(g.hMainWnd, &pwp);
  415.     }
  416.  
  417.  
  418.     RegCloseKey( hKey );
  419. }
  420.  
  421. //////////////////////////////////////////////////////////////////////////////
  422. //
  423. //  MySaveWindow() - save the current window placement and bar
  424. //
  425. //////////////////////////////////////////////////////////////////////////////
  426. void MySaveWindow(HWND hWnd)
  427. {
  428.     WINDOWPLACEMENT     pwp;
  429.     HKEY                hKey;
  430.     DWORD               dwDisposition;
  431.  
  432.  
  433.     pwp.length = sizeof(WINDOWPLACEMENT);
  434.  
  435.     // get and save
  436.     GetWindowPlacement(hWnd, &pwp);
  437.  
  438.     RegCreateKeyEx(HKEY_CURRENT_USER,
  439.                    gszACDSampleKey,
  440.                    0,
  441.                    TEXT(""),
  442.                    REG_OPTION_NON_VOLATILE,
  443.                    KEY_ALL_ACCESS,
  444.                    0,
  445.                    &hKey,
  446.                    &dwDisposition);
  447.  
  448.     RegSetValueEx(hKey,
  449.                   gszPlacementValue,
  450.                   0,
  451.                   REG_BINARY,
  452.                   (LPBYTE)&pwp,
  453.                   sizeof(WINDOWPLACEMENT));
  454.  
  455.     RegSetValueEx(hKey,
  456.                   gszBarLocation,
  457.                   0,
  458.                   REG_DWORD,
  459.                   (LPBYTE)&g.dwBarLocation,
  460.                   sizeof(DWORD));
  461.  
  462.     RegCloseKey( hKey );
  463.  
  464. }
  465.  
  466.  
  467. //////////////////////////////////////////////////////////////////////////////
  468. //
  469. //  AddItemToTree
  470. //
  471. //    add a new leaf to the tree
  472. //
  473. //////////////////////////////////////////////////////////////////////////////
  474. HTREEITEM AddItemToTree(HTREEITEM hParent,
  475.                         LPTSTR lpszName,
  476.                         LPARAM lParam,
  477.                         HTREEITEM * phItem)
  478.     TV_ITEM         tvi; 
  479.     TV_INSERTSTRUCT tvins; 
  480.     HTREEITEM       hti; 
  481.  
  482.     tvi.mask = TVIF_TEXT | TVIF_PARAM;
  483.  
  484.     // Set the text of the item. 
  485.     tvi.pszText = lpszName; 
  486.     tvi.cchTextMax = lstrlen(lpszName) * sizeof(TCHAR);
  487.  
  488.     // Save the pointer to the buffer
  489.     tvi.lParam = lParam;
  490.  
  491.     tvins.item = tvi; 
  492.     tvins.hInsertAfter = TVI_SORT;
  493.  
  494.     // Set the parent item
  495.     tvins.hParent = hParent;
  496.     
  497.     // Add the item to the tree-view control. 
  498.     hti = (HTREEITEM) SendMessage(g.hTreeWnd,
  499.                                   TVM_INSERTITEM,
  500.                                   0, 
  501.                                   (LPARAM) (LPTV_INSERTSTRUCT) &tvins);
  502.  
  503.     // save hitem
  504.     if (phItem)
  505.     {
  506.         *phItem = hti;
  507.     }
  508.  
  509.     // select the item so it has focus
  510.     TreeView_Select(g.hTreeWnd,
  511.                     hti,
  512.                     TVGN_CARET);
  513.  
  514.     return hti;
  515.  
  516. //////////////////////////////////////////////////////////////////////////////
  517. //
  518. //  DoPopupMenu(HTREEITEM hItem,
  519. //              POINT pt)
  520. //
  521. //      hItem - item to create menu for
  522. //      pt - location of mouse so we can create menu where it is
  523. //
  524. //   creates a popup menu, depending on what kind of item is selected 
  525. //
  526. //////////////////////////////////////////////////////////////////////////////
  527. BOOL DoPopupMenu(HTREEITEM hItem, POINT pt)
  528. {
  529.  
  530.     HMENU       hMenu;
  531.     TV_ITEM     tvi;
  532.     TCHAR       szNewGroup[]        = TEXT("&New Group...");
  533.     TCHAR       szNewAgent[]        = TEXT("New &Agent...");
  534.     TCHAR       szAddAgent[]        = TEXT("A&dd Agent...");
  535.     TCHAR       szGroupProperties[] = TEXT("&Group Properties...");
  536.     TCHAR       szAgentStatus[]     = TEXT("Agent Status...");
  537.     TCHAR       szAddGroup[]        = TEXT("Add Group...");
  538.     TCHAR       szAgentProperties[] = TEXT("Agent Properties...");
  539.     TCHAR       szGroupDelete[]     = TEXT("Group Delete");
  540.     TCHAR       szAgentDelete[]     = TEXT("Agent Delete");
  541.     TCHAR       szSignIn[]          = TEXT("Agent Sign In");
  542.     TCHAR       szSignOut[]         = TEXT("Agent Sign Out");    
  543.  
  544.     // get the selected item
  545.     g.hTreeItemWithMenu = hItem;
  546.  
  547.     // create the menu
  548.     hMenu = CreatePopupMenu();
  549.  
  550.     // get the lParam, which is a pointer to the item
  551.     tvi.mask = TVIF_HANDLE | TVIF_PARAM;
  552.     tvi.hItem = hItem;
  553.  
  554.     TreeView_GetItem(g.hTreeWnd,
  555.                      &tvi);
  556.  
  557.     if (!tvi.lParam)
  558.     {
  559.         return TRUE;
  560.     }
  561.     
  562.     switch (((PGROUP)tvi.lParam)->dwKey)
  563.     {
  564.         // root item
  565.         case GROUPROOTKEY:
  566.             
  567.             AppendMenu(hMenu,
  568.                        MF_ENABLED | MF_STRING,
  569.                        IDM_NEWGROUP,
  570.                        szNewGroup);
  571.             break;
  572.  
  573.         // root item
  574.         case AGENTROOTKEY:
  575.             
  576.             AppendMenu(hMenu,
  577.                        MF_ENABLED | MF_STRING,
  578.                        IDM_NEWAGENT,
  579.                        szNewAgent);
  580.             break;
  581.         // group leaf
  582.         case GROUPKEY:
  583.             
  584.             AppendMenu(hMenu,
  585.                        MF_ENABLED | MF_STRING,
  586.                        (UINT)IDM_GROUPADDTOLIST,
  587.                        szAddAgent);
  588.             
  589.             AppendMenu(hMenu,
  590.                        MF_ENABLED | MF_STRING,
  591.                        (UINT)IDM_GROUPAGENTSTATUS,
  592.                        szAgentStatus);
  593.  
  594.             AppendMenu(hMenu,
  595.                        MF_ENABLED | MF_STRING,
  596.                        IDM_GROUPPROPERTIES,
  597.                        szGroupProperties);
  598.  
  599.             AppendMenu(hMenu,
  600.                        MF_ENABLED | MF_STRING,
  601.                        IDM_GROUPDELETE,
  602.                        szGroupDelete);
  603.  
  604.             break;
  605.         // agent leaf    
  606.         case AGENTKEY:
  607.  
  608.             AppendMenu(hMenu,
  609.                        MF_ENABLED | MF_STRING,
  610.                        (UINT)IDM_AGENTADDTOLIST,
  611.                        szAddGroup);
  612.             
  613.             AppendMenu(hMenu,
  614.                        MF_ENABLED | MF_STRING,
  615.                        IDM_AGENTPROPERTIES,
  616.                        szAgentProperties);
  617.  
  618.             AppendMenu(hMenu,
  619.                        MF_ENABLED | MF_STRING,
  620.                        IDM_AGENTDELETE,
  621.                        szAgentDelete);
  622.  
  623.             break;
  624.             
  625.         default:
  626.             break;
  627.     }
  628.  
  629.     // actually show menu
  630.     TrackPopupMenu(hMenu,
  631.                    TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
  632.                    pt.x,
  633.                    pt.y,
  634.                    0,
  635.                    g.hMainWnd,
  636.                    NULL);
  637.     
  638.     return TRUE;
  639. }
  640.  
  641. ///////////////////////////////////////////////////////////////////////////////
  642. //
  643. //  LRESULT DoCommand(WPARAM wParam, LPARAM lParam)
  644. //      handle WM_COMMAND messages for MainDlgProc
  645. //
  646. ///////////////////////////////////////////////////////////////////////////////
  647. LRESULT DoCommand(WPARAM wParam, LPARAM lParam)
  648. {
  649.     switch (LOWORD(wParam))
  650.     {
  651.         // New - create a new tree, so just init
  652.         // the items and return
  653.         case ID_FILE_NEW:
  654.             DoGroupView();
  655.             return 1;
  656.  
  657.         // Open - read in a file
  658.         case ID_FILE_OPEN:
  659.             ReadInFile();
  660.             return 1;
  661.         
  662.         case ID_FILE_EXIT:
  663.             // save the current window location
  664.             WriteToDisk();
  665.             CleanUp();
  666.             MySaveWindow(g.hMainWnd);
  667.             PostQuitMessage(0);
  668.             return 1;
  669.  
  670.         // new group
  671.         case ID_EDIT_ADDGROUP:
  672.         case IDM_NEWGROUP:
  673.             DialogBox(g.hInstance,
  674.                       MAKEINTRESOURCE(IDD_ADD),
  675.                       g.hTreeWnd,
  676.                       AddGroupDlgProc);
  677.  
  678.             return 1;
  679.  
  680.         // new agent    
  681.         case ID_EDIT_ADDAGENT:
  682.         case IDM_NEWAGENT:
  683.             DialogBox(g.hInstance,
  684.                       MAKEINTRESOURCE(IDD_ADDAGENT),
  685.                       g.hTreeWnd,
  686.                       AddAgentDlgProc);
  687.             return 1;
  688.  
  689.         // properties
  690.         case IDM_GROUPPROPERTIES:
  691.             DialogBox(g.hInstance,
  692.                       MAKEINTRESOURCE(IDD_ADD),
  693.                       g.hMainWnd,
  694.                       ChangeGroupDlgProc);
  695.  
  696.             return 1;
  697.  
  698.         // properties            
  699.         case IDM_AGENTPROPERTIES:
  700.             DialogBox(g.hInstance,
  701.                       MAKEINTRESOURCE(IDD_ADDAGENT),
  702.                       g.hMainWnd,
  703.                       ChangeAgentDlgProc);
  704.  
  705.             return 1;
  706.  
  707.         // delete            
  708.         case IDM_GROUPDELETE:            
  709.         case IDM_AGENTDELETE:
  710.         {
  711.             DeleteLeafAndStruct(g.hTreeItemWithMenu);
  712.             
  713.             return 1;
  714.         }
  715.  
  716.  
  717.         // add to list
  718.         case IDM_GROUPADDTOLIST:
  719.             DialogBoxParam(g.hInstance,
  720.                            MAKEINTRESOURCE(IDD_ADDTOLIST),
  721.                            g.hMainWnd,
  722.                            GroupAddToListProc,
  723.                            TRUE);
  724.             
  725.             return 1;
  726.                      
  727.         // add to list
  728.         case IDM_AGENTADDTOLIST:
  729.             DialogBoxParam(g.hInstance,
  730.                            MAKEINTRESOURCE(IDD_ADDTOLIST),
  731.                            g.hMainWnd,
  732.                            AgentAddToListProc,
  733.                            FALSE);
  734.  
  735.             return 1;
  736.  
  737.         case ID_VIEW_GROUP:
  738.             DoGroupView();
  739.             return 1;
  740.             
  741.         case ID_VIEW_AGENT:
  742.             DoAgentView();
  743.             return 1;
  744.  
  745.         default:
  746.             break;
  747.             
  748.     }
  749.  
  750.     return 0;
  751. }
  752.  
  753. /////////////////////////////////////////////////////////////////////////////////////////////////////
  754. //
  755. //  AddGroupDlgProc - Window proc for the add agent/group dialog box
  756. //
  757. /////////////////////////////////////////////////////////////////////////////////////////////////////
  758. BOOL CALLBACK AddGroupDlgProc(HWND   hWnd,
  759.                               UINT   uMsg,
  760.                               WPARAM wParam,
  761.                               LPARAM lParam)
  762. {
  763.     switch (uMsg)
  764.     {
  765.         case WM_INITDIALOG:
  766.  
  767.             // set text appropriately
  768.             SetWindowText(hWnd,
  769.                           TEXT("Add Group"));
  770.  
  771.             BuildLineList(GetDlgItem(hWnd,
  772.                                      IDC_LINECOMBO),
  773.                           0);
  774.  
  775.             BuildAddressList(GetDlgItem(hWnd,
  776.                                         IDC_ADDRESSCOMBO),
  777.                              hWnd,
  778.                              0);
  779.                           
  780.             // set focus on first control
  781.             SetFocus(GetDlgItem(hWnd,
  782.                                 IDC_NAME));
  783.  
  784.             return 0;
  785.  
  786.         case WM_COMMAND:
  787.  
  788.             switch (LOWORD(wParam))
  789.             {
  790.                 case IDC_LINECOMBO:
  791.                 {
  792.                     if (HIWORD(wParam) == CBN_SELENDOK)
  793.                     {
  794.                         // need to redo addresses
  795.                         BuildAddressList(GetDlgItem(hWnd,
  796.                                                     IDC_ADDRESSCOMBO),
  797.                                          hWnd,
  798.                                          0);
  799.  
  800.                         return 1;
  801.                     }
  802.                     
  803.                     return 0;
  804.                 }
  805.                 case IDOK:
  806.                 {
  807.                     TCHAR       szName[128];
  808.                     PGROUP      pGroup;
  809.                     DWORD       dwLine, dwAddress;
  810.                     int         item;
  811.  
  812.                     // get info
  813.                     SendDlgItemMessage(hWnd,
  814.                                        IDC_NAME,
  815.                                        WM_GETTEXT,
  816.                                        128,
  817.                                        (LPARAM)szName);
  818.  
  819.                     item = SendDlgItemMessage(hWnd,
  820.                                               IDC_LINECOMBO,
  821.                                               CB_GETCURSEL,
  822.                                               0,
  823.                                               0);
  824.                     
  825.                     dwLine = (DWORD)SendDlgItemMessage(hWnd,
  826.                                                        IDC_LINECOMBO,
  827.                                                        CB_GETITEMDATA,
  828.                                                        item,
  829.                                                        0);
  830.  
  831.                     dwAddress = (DWORD)SendDlgItemMessage(hWnd,
  832.                                                           IDC_ADDRESSCOMBO,
  833.                                                           CB_GETCURSEL,
  834.                                                           0,
  835.                                                           0);
  836.                     
  837.                     // create a structure
  838.                     pGroup = AddGroup(szName,
  839.                                       dwLine,
  840.                                       dwAddress);
  841.  
  842.                     if (!pGroup)
  843.                     {
  844.                         return 1;
  845.                     }
  846.  
  847.                     if (g.bGroupView)
  848.                     {
  849.                         // add it to the tree
  850.                         AddItemToTree(g.hGroupParent,
  851.                                       pGroup->lpszName,
  852.                                       (LPARAM)pGroup,
  853.                                       &pGroup->hItem);
  854.                     }
  855.  
  856.                     EndDialog(hWnd, 1);
  857.                     return 1;
  858.                 }
  859.  
  860.                 case IDCANCEL:
  861.                 {
  862.                     EndDialog(hWnd, 0);
  863.                     return 1;
  864.                 }
  865.  
  866.                 default:
  867.                     return 0;
  868.  
  869.             }
  870.  
  871.     }
  872.  
  873.     return 0;
  874. }
  875.  
  876.  
  877. /////////////////////////////////////////////////////////////////////////////////////////////////////
  878. //
  879. //  AddAgentDlgProc - Window proc for the add agent/group dialog box
  880. //
  881. /////////////////////////////////////////////////////////////////////////////////////////////////////
  882. BOOL CALLBACK AddAgentDlgProc(HWND   hWnd,
  883.                               UINT   uMsg,
  884.                               WPARAM wParam,
  885.                               LPARAM lParam)
  886. {
  887.     switch (uMsg)
  888.     {
  889.         case WM_INITDIALOG:
  890.  
  891.             BuildLineList(GetDlgItem(hWnd,
  892.                                      IDC_LINECOMBO),
  893.                           0);
  894.  
  895.             // set focus on first control
  896.             SetFocus(GetDlgItem(hWnd,
  897.                                 IDC_NAME));
  898.  
  899.             return 0;
  900.  
  901.         case WM_COMMAND:
  902.  
  903.             switch (LOWORD(wParam))
  904.             {
  905.                 case IDOK:
  906.                 {
  907.                     TCHAR       szName[128];
  908.                     TCHAR       szNumber[128];
  909.                     PAGENT      pAgent;
  910.                     DWORD       dwLine;
  911.                     int         item;
  912.  
  913.                     // get info
  914.                     SendDlgItemMessage(hWnd,
  915.                                        IDC_NAME,
  916.                                        WM_GETTEXT,
  917.                                        128,
  918.                                        (LPARAM)szName);
  919.  
  920.                     SendDlgItemMessage(hWnd,
  921.                                        IDC_DESTADDRESS,
  922.                                        WM_GETTEXT,
  923.                                        128,
  924.                                        (LPARAM)szNumber);
  925.  
  926.                     item = SendDlgItemMessage(hWnd,
  927.                                               IDC_LINECOMBO,
  928.                                               CB_GETCURSEL,
  929.                                               0,
  930.                                               0);
  931.                     
  932.                     dwLine = (DWORD)SendDlgItemMessage(hWnd,
  933.                                                        IDC_LINECOMBO,
  934.                                                        CB_GETITEMDATA,
  935.                                                        item,
  936.                                                        0);
  937.  
  938.                     // create a structure
  939.                     pAgent = AddAgent(szName,
  940.                                       szNumber,
  941.                                       dwLine);
  942.  
  943.                     if (!pAgent)
  944.                     {
  945.                         return 1;
  946.                     }
  947.  
  948.  
  949.                     if (!g.bGroupView)
  950.                     {
  951.                     // add it to the tree
  952.                         AddItemToTree(g.hAgentParent,
  953.                                       pAgent->lpszName,
  954.                                       (LPARAM)pAgent,
  955.                                       &pAgent->hItem);
  956.                     }
  957.  
  958.                     EndDialog(hWnd, 1);
  959.                     return 1;
  960.                 }
  961.  
  962.                 case IDCANCEL:
  963.                 {
  964.                     EndDialog(hWnd, 0);
  965.                     return 1;
  966.                 }
  967.  
  968.                 default:
  969.                     return 0;
  970.  
  971.             }
  972.     }
  973.     return 0;
  974. }
  975.  
  976. //////////////////////////////////////////////////////////////////////////////////
  977. //
  978. //  ChangeGroupDlgProc - Window proc for the change (properties) dialog box
  979. //     for agents/groups
  980. //
  981. //////////////////////////////////////////////////////////////////////////////////
  982. BOOL CALLBACK ChangeGroupDlgProc(HWND   hWnd,
  983.                                  UINT   uMsg,
  984.                                  WPARAM wParam,
  985.                                  LPARAM lParam)
  986. {
  987.     static TV_ITEM      tvi;
  988.     
  989.     switch (uMsg)
  990.     {
  991.         case WM_INITDIALOG:
  992.  
  993.             // set text appropriately
  994.             SetWindowText(hWnd,
  995.                           TEXT("Change Group"));
  996.  
  997.             // get PGROUP and set edit controls
  998.             tvi.mask    = TVIF_HANDLE | TVIF_PARAM;
  999.             tvi.hItem   = g.hTreeItemWithMenu;
  1000.  
  1001.             TreeView_GetItem(g.hTreeWnd,
  1002.                              &tvi);
  1003.  
  1004.             SendDlgItemMessage(hWnd,
  1005.                                IDC_NAME,
  1006.                                WM_SETTEXT,
  1007.                                0,
  1008.                                (LPARAM)((PGROUP)tvi.lParam)->lpszName);
  1009.  
  1010.             BuildLineList(GetDlgItem(hWnd,
  1011.                                      IDC_LINECOMBO),
  1012.                           (((PGROUP)tvi.lParam)->dwDeviceID));
  1013.  
  1014.             
  1015.             BuildAddressList(GetDlgItem(hWnd,
  1016.                                         IDC_ADDRESSCOMBO),
  1017.                              hWnd,
  1018.                              (((PGROUP)tvi.lParam)->dwAddress));
  1019.  
  1020.             SetFocus(GetDlgItem(hWnd,
  1021.                                 IDC_NAME));
  1022.  
  1023.             return 0;
  1024.  
  1025.         case WM_COMMAND:
  1026.  
  1027.             switch (LOWORD(wParam))
  1028.             {
  1029.                 case IDC_LINECOMBO:
  1030.                 {
  1031.                     if (HIWORD(wParam) == CBN_SELENDOK)
  1032.                     {
  1033.                         // need to redo addresses
  1034.                         BuildAddressList(GetDlgItem(hWnd,
  1035.                                                     IDC_ADDRESSCOMBO),
  1036.                                          hWnd,
  1037.                                          0);
  1038.  
  1039.                         return 1;
  1040.                     }
  1041.                     
  1042.                     return 0;
  1043.                 }
  1044.                 case IDOK:
  1045.                 {
  1046.                     TCHAR       szName[128];
  1047.                     PGROUP      pGroup;
  1048.  
  1049.                     // get info
  1050.                     SendDlgItemMessage(hWnd,
  1051.                                        IDC_NAME,
  1052.                                        WM_GETTEXT,
  1053.                                        128,
  1054.                                        (LPARAM)szName);
  1055.  
  1056.                     // get struct
  1057.                     pGroup = (PGROUP)tvi.lParam;
  1058.  
  1059.                     /// get device and address
  1060.                     pGroup->dwDeviceID = SendDlgItemMessage(hWnd,
  1061.                                             IDC_LINECOMBO,
  1062.                                             CB_GETCURSEL,
  1063.                                             0,
  1064.                                             0);
  1065.  
  1066.                     pGroup->dwDeviceID = SendDlgItemMessage(hWnd,
  1067.                                                             IDC_LINECOMBO,
  1068.                                                             CB_GETITEMDATA,
  1069.                                                             (WPARAM)pGroup->dwDeviceID,
  1070.                                                             0);
  1071.  
  1072.                     pGroup->dwAddress = SendDlgItemMessage(hWnd,
  1073.                                                            IDC_ADDRESSCOMBO,
  1074.                                                            CB_GETCURSEL,
  1075.                                                            0,
  1076.                                                            0);
  1077.  
  1078.                     // save new info and free old info
  1079.                     ACDFree(pGroup->lpszName);
  1080.                     pGroup->lpszName = ACDAlloc((lstrlen(szName) + 1) * sizeof(TCHAR));
  1081.                     lstrcpy(pGroup->lpszName, szName);
  1082.  
  1083.                     // update item name
  1084.                     tvi.mask = TVIF_TEXT;
  1085.                     tvi.pszText = szName;
  1086.                     tvi.cchTextMax = lstrlen(szName) * sizeof(TCHAR);
  1087.                     TreeView_SetItem(g.hTreeWnd,
  1088.                                      &tvi);
  1089.                     
  1090.                     EndDialog(hWnd, 1);
  1091.                     return 1;
  1092.                 }
  1093.  
  1094.                 case IDCANCEL:
  1095.                 {
  1096.                     EndDialog(hWnd, 0);
  1097.                     return 1;
  1098.                 }
  1099.  
  1100.                 default:
  1101.                     return 0;
  1102.  
  1103.             }
  1104.     }
  1105.     return 0;
  1106. }
  1107.  
  1108.  
  1109. //////////////////////////////////////////////////////////////////////////////////
  1110. //
  1111. //  ChangeGroupDlgProc - Window proc for the change (properties) dialog box
  1112. //     for agents/groups
  1113. //
  1114. //////////////////////////////////////////////////////////////////////////////////
  1115. BOOL CALLBACK ChangeAgentDlgProc(HWND   hWnd,
  1116.                                  UINT   uMsg,
  1117.                                  WPARAM wParam,
  1118.                                  LPARAM lParam)
  1119. {
  1120.     static TV_ITEM      tvi;
  1121.     
  1122.     switch (uMsg)
  1123.     {
  1124.         case WM_INITDIALOG:
  1125.  
  1126.             // set text appropriately
  1127.             SetWindowText(hWnd,
  1128.                           TEXT("Change Agent"));
  1129.  
  1130.             // get PGROUP and set edit controls
  1131.             tvi.mask    = TVIF_HANDLE | TVIF_PARAM;
  1132.             tvi.hItem   = g.hTreeItemWithMenu;
  1133.  
  1134.             TreeView_GetItem(g.hTreeWnd,
  1135.                              &tvi);
  1136.  
  1137.             SendDlgItemMessage(hWnd,
  1138.                                IDC_NAME,
  1139.                                WM_SETTEXT,
  1140.                                0,
  1141.                                (LPARAM)((PAGENT)tvi.lParam)->lpszName);
  1142.  
  1143.             SendDlgItemMessage(hWnd,
  1144.                                IDC_DESTADDRESS,
  1145.                                WM_SETTEXT,
  1146.                                0,
  1147.                                (LPARAM)((PAGENT)tvi.lParam)->lpszNumber);
  1148.  
  1149.             BuildLineList(GetDlgItem(hWnd,
  1150.                                      IDC_LINECOMBO),
  1151.                           (((PAGENT)tvi.lParam)->dwDeviceID));
  1152.  
  1153.             SetFocus(GetDlgItem(hWnd,
  1154.                                 IDC_NAME));
  1155.  
  1156.             return 0;
  1157.  
  1158.         case WM_COMMAND:
  1159.  
  1160.             switch (LOWORD(wParam))
  1161.             {
  1162.                 case IDOK:
  1163.                 {
  1164.                     TCHAR       szName[128];
  1165.                     TCHAR       szNumber[128];
  1166.                     PAGENT      pAgent;
  1167.  
  1168.                     // get info
  1169.                     SendDlgItemMessage(hWnd,
  1170.                                        IDC_NAME,
  1171.                                        WM_GETTEXT,
  1172.                                        128,
  1173.                                        (LPARAM)szName);
  1174.  
  1175.                     SendDlgItemMessage(hWnd,
  1176.                                        IDC_DESTADDRESS,
  1177.                                        WM_GETTEXT,
  1178.                                        128,
  1179.                                        (LPARAM)szNumber);
  1180.  
  1181.                     // get struct
  1182.                     pAgent = (PAGENT)tvi.lParam;
  1183.  
  1184.                     /// get device and address
  1185.                     pAgent->dwDeviceID = SendDlgItemMessage(hWnd,
  1186.                                             IDC_LINECOMBO,
  1187.                                             CB_GETCURSEL,
  1188.                                             0,
  1189.                                             0);
  1190.  
  1191.                     pAgent->dwDeviceID = SendDlgItemMessage(hWnd,
  1192.                                                             IDC_LINECOMBO,
  1193.                                                             CB_GETITEMDATA,
  1194.                                                             (WPARAM)pAgent->dwDeviceID,
  1195.                                                             0);
  1196.  
  1197.                     // save new info and free old info
  1198.                     ACDFree(pAgent->lpszName);
  1199.                     pAgent->lpszName = ACDAlloc((lstrlen(szName) + 1) * sizeof(TCHAR));
  1200.                     lstrcpy(pAgent->lpszName, szName);
  1201.  
  1202.  
  1203.                     ACDFree(pAgent->lpszNumber);
  1204.                     pAgent->lpszNumber = ACDAlloc((lstrlen(szNumber) + 1) * sizeof(TCHAR));
  1205.                     lstrcpy(pAgent->lpszNumber, szNumber);
  1206.  
  1207.                     // update item name
  1208.                     tvi.mask = TVIF_TEXT;
  1209.                     tvi.pszText = szName;
  1210.                     tvi.cchTextMax = lstrlen(szName) * sizeof(TCHAR);
  1211.                     TreeView_SetItem(g.hTreeWnd,
  1212.                                      &tvi);
  1213.                     
  1214.                     EndDialog(hWnd, 1);
  1215.                     return 1;
  1216.                 }
  1217.  
  1218.                 case IDCANCEL:
  1219.                 {
  1220.                     EndDialog(hWnd, 0);
  1221.                     return 1;
  1222.                 }
  1223.  
  1224.                 default:
  1225.                     return 0;
  1226.  
  1227.             }
  1228.     }
  1229.     return 0;
  1230. }
  1231.  
  1232. //////////////////////////////////////////////////////////////////////////////////////
  1233. //
  1234. //  AddToList() - Window proc for Add Agent To Group and Add Group To Agent
  1235. //    dialog box
  1236. //
  1237. //////////////////////////////////////////////////////////////////////////////////////
  1238. BOOL CALLBACK GroupAddToListProc(HWND   hWnd,
  1239.                                  UINT   uMsg,
  1240.                                  WPARAM wParam,
  1241.                                  LPARAM lParam)
  1242. {
  1243.     static PGROUP           pGroup;
  1244.     PAGENT                  pAgent;
  1245.     PLISTITEM               pList;
  1246.     TV_ITEM                 tvi;
  1247.     DWORD                   dwListBox;
  1248.     BOOL                    bFound;
  1249.     int                     item;
  1250.     TCHAR                   szBuffer[128];
  1251.     
  1252.     
  1253.     switch (uMsg)
  1254.     {
  1255.         case WM_INITDIALOG:
  1256.  
  1257.             // get the item in question
  1258.             tvi.mask    = TVIF_HANDLE | TVIF_PARAM;
  1259.             tvi.hItem   = g.hTreeItemWithMenu;
  1260.  
  1261.             TreeView_GetItem(g.hTreeWnd,
  1262.                              &tvi);
  1263.  
  1264.             pGroup = (PGROUP)tvi.lParam;
  1265.  
  1266.             // init lists
  1267.             if (pGroup)
  1268.             {
  1269.                 // initialize text in dialog
  1270.                 wsprintf(szBuffer, TEXT("Add To %s"), pGroup->lpszName);
  1271.  
  1272.                 SetWindowText(hWnd,
  1273.                               TEXT("Add To Group"));
  1274.  
  1275.                 SetDlgItemText(hWnd,
  1276.                                IDC_STATICNOTINLIST,
  1277.                                TEXT("Not in Group"));
  1278.                 SetDlgItemText(hWnd,
  1279.                                IDC_STATICINLIST,
  1280.                                TEXT("Group Members"));
  1281.  
  1282.                 pAgent = g.pAgents;
  1283.  
  1284.                 // walk list and initialize list boxes
  1285.                 while (pAgent)
  1286.                 {
  1287.                     pList = pGroup->pAgentList;
  1288.  
  1289.                     bFound = FALSE;
  1290.                 
  1291.                     while (pList)
  1292.                     {
  1293.                         if (pList->pAgent == pAgent)
  1294.                         {
  1295.                             bFound = TRUE;
  1296.                             break;
  1297.                         }
  1298.  
  1299.                         pList = pList->pNext;
  1300.                     }
  1301.  
  1302.                     // if it was found, it is already a member of
  1303.                     // the group
  1304.                     if (bFound)
  1305.                     {
  1306.                         dwListBox = IDC_LIST2;
  1307.                     }
  1308.                     else
  1309.                     {
  1310.                         dwListBox = IDC_LIST1;
  1311.                     }
  1312.  
  1313.                     // add to correct list box
  1314.                     item = SendDlgItemMessage(hWnd,
  1315.                                               dwListBox,
  1316.                                               LB_ADDSTRING,
  1317.                                               0,
  1318.                                               (LPARAM)pAgent->lpszName);
  1319.  
  1320.                     // set the item data to be the item so we can get back it.
  1321.                     if (item != LB_ERR)
  1322.                     {
  1323.                         SendDlgItemMessage(hWnd,
  1324.                                            dwListBox,
  1325.                                            LB_SETITEMDATA,
  1326.                                            (WPARAM)item,
  1327.                                            (LPARAM)pAgent);
  1328.                     }
  1329.  
  1330.                     pAgent = pAgent->pNext;
  1331.                 }
  1332.             }
  1333.  
  1334.             
  1335.             
  1336.             return 1;
  1337.  
  1338.         case WM_COMMAND:
  1339.  
  1340.             switch (LOWORD(wParam))
  1341.             {
  1342.                 case IDC_ADD:
  1343.                 {
  1344.                     // get the item
  1345.                     item = SendDlgItemMessage(hWnd,
  1346.                                               IDC_LIST1,
  1347.                                               LB_GETCURSEL,
  1348.                                               0,
  1349.                                               0);
  1350.  
  1351.                     if (item == 0)
  1352.                     {
  1353.                         if (!SendDlgItemMessage(hWnd,
  1354.                                                 IDC_LIST1,
  1355.                                                 LB_GETSEL,
  1356.                                                 (WPARAM)item,
  1357.                                                 0))
  1358.                         {
  1359.                             item == -1;
  1360.                         }
  1361.                     }
  1362.  
  1363.                     if (item != -1)
  1364.                     {
  1365.                         // get the PAGENT associated with it
  1366.                         pAgent = (PAGENT)SendDlgItemMessage(hWnd,
  1367.                                                             IDC_LIST1,
  1368.                                                             LB_GETITEMDATA,
  1369.                                                             (WPARAM)item,
  1370.                                                             0);
  1371.  
  1372.                         // delete it from this listbox
  1373.                         SendDlgItemMessage(hWnd,
  1374.                                            IDC_LIST1,
  1375.                                            LB_DELETESTRING,
  1376.                                            (WPARAM)item,
  1377.                                            0);
  1378.  
  1379.                         // add it to this list box
  1380.                         item = SendDlgItemMessage(hWnd,
  1381.                                                   IDC_LIST2,
  1382.                                                   LB_ADDSTRING,
  1383.                                                   0,
  1384.                                                   (LPARAM)pAgent->lpszName);
  1385.  
  1386.                         // set the item data again
  1387.                         SendDlgItemMessage(hWnd,
  1388.                                            IDC_LIST2,
  1389.                                            LB_SETITEMDATA,
  1390.                                            item,
  1391.                                            (WPARAM)pAgent);
  1392.  
  1393.                         // add it to the group's list
  1394.                         InsertIntoGroupList(pGroup,
  1395.                                             pAgent);
  1396.                         
  1397.                         return 1;
  1398.                         
  1399.                     }
  1400.                 }
  1401.                 break;
  1402.                 
  1403.                 case IDC_REMOVE:
  1404.                 {
  1405.                     // get the item
  1406.                     item = SendDlgItemMessage(hWnd,
  1407.                                               IDC_LIST2,
  1408.                                               LB_GETCURSEL,
  1409.                                               0,
  1410.                                               0);
  1411.  
  1412.                     if (item == 0)
  1413.                     {
  1414.                         if (!SendDlgItemMessage(hWnd,
  1415.                                                 IDC_LIST2,
  1416.                                                 LB_GETSEL,
  1417.                                                 (WPARAM)item,
  1418.                                                 0))
  1419.                         {
  1420.                             item == -1;
  1421.                         }
  1422.                     }
  1423.  
  1424.                     if (item != -1)
  1425.                     {
  1426.                         // get the struct associated with it
  1427.                         pAgent = (PAGENT)SendDlgItemMessage(hWnd,
  1428.                                                                 IDC_LIST2,
  1429.                                                                 LB_GETITEMDATA,
  1430.                                                                 (WPARAM)item,
  1431.                                                                 0);
  1432.  
  1433.                         // delete it from this list
  1434.                         SendDlgItemMessage(hWnd,
  1435.                                            IDC_LIST2,
  1436.                                            LB_DELETESTRING,
  1437.                                            (WPARAM)item,
  1438.                                            0);
  1439.  
  1440.                         // add it to this list
  1441.                         item = SendDlgItemMessage(hWnd,
  1442.                                                   IDC_LIST1,
  1443.                                                   LB_ADDSTRING,
  1444.                                                   0,
  1445.                                                   (LPARAM)pAgent->lpszName);
  1446.  
  1447.                         // set the item data
  1448.                         SendDlgItemMessage(hWnd,
  1449.                                            IDC_LIST1,
  1450.                                            LB_SETITEMDATA,
  1451.                                            item,
  1452.                                            (WPARAM)pAgent);
  1453.  
  1454.                         // remove it from the lists
  1455.                         RemoveFromGroupList(pGroup,
  1456.                                             pAgent);
  1457.                         
  1458.                         return 1;
  1459.                         
  1460.                     }
  1461.                     
  1462.                 }
  1463.                 break;
  1464.  
  1465.  
  1466.                 // bug idcancel doesn't cancel
  1467.                 case IDOK:
  1468.                 case IDCANCEL:
  1469.                 {
  1470.                     UpdateGroupLeaf(pGroup);
  1471.  
  1472.                     EndDialog(hWnd, 1);
  1473.                     return 1;
  1474.                 }
  1475.  
  1476.                 default:
  1477.                     return 0;
  1478.  
  1479.             }
  1480.  
  1481.     }
  1482.  
  1483.     return 0;
  1484. }
  1485.  
  1486.  
  1487. BOOL CALLBACK AgentAddToListProc(HWND   hWnd,
  1488.                                  UINT   uMsg,
  1489.                                  WPARAM wParam,
  1490.                                  LPARAM lParam)
  1491. {
  1492.     static PAGENT           pAgent;
  1493.     PGROUP                  pGroup;
  1494.     PLISTITEM               pList;
  1495.     TV_ITEM                 tvi;
  1496.     DWORD                   dwListBox;
  1497.     BOOL                    bFound;
  1498.     int                     item;
  1499.     TCHAR                   szBuffer[128];
  1500.     
  1501.     
  1502.     switch (uMsg)
  1503.     {
  1504.         case WM_INITDIALOG:
  1505.  
  1506.             // get the item in question
  1507.             tvi.mask    = TVIF_HANDLE | TVIF_PARAM;
  1508.             tvi.hItem   = g.hTreeItemWithMenu;
  1509.  
  1510.             TreeView_GetItem(g.hTreeWnd,
  1511.                              &tvi);
  1512.  
  1513.             pAgent = (PAGENT)tvi.lParam;
  1514.  
  1515.             // init lists
  1516.             if (pAgent)
  1517.             {
  1518.                 // initialize text in dialog
  1519.                 wsprintf(szBuffer, TEXT("Add To %s"), pAgent->lpszName);
  1520.  
  1521.                 SetWindowText(hWnd,
  1522.                               TEXT("Add To Agent"));
  1523.  
  1524.                 SetDlgItemText(hWnd,
  1525.                                IDC_STATICNOTINLIST,
  1526.                                TEXT("Not Member Of"));
  1527.                 SetDlgItemText(hWnd,
  1528.                                IDC_STATICINLIST,
  1529.                                TEXT("Member Of"));
  1530.  
  1531.                 pGroup = g.pGroups;
  1532.  
  1533.                 // walk list and initialize list boxes
  1534.                 while (pGroup)
  1535.                 {
  1536.                     pList = pGroup->pAgentList;
  1537.  
  1538.                     bFound = FALSE;
  1539.                 
  1540.                     while (pList)
  1541.                     {
  1542.                         if (pList->pAgent == pAgent)
  1543.                         {
  1544.                             bFound = TRUE;
  1545.                             break;
  1546.                         }
  1547.  
  1548.                         pList = pList->pNext;
  1549.                     }
  1550.  
  1551.                     // if it was found, it is already a member of
  1552.                     // the group
  1553.                     if (bFound)
  1554.                     {
  1555.                         dwListBox = IDC_LIST2;
  1556.                     }
  1557.                     else
  1558.                     {
  1559.                         dwListBox = IDC_LIST1;
  1560.                     }
  1561.  
  1562.                     // add to correct list box
  1563.                     item = SendDlgItemMessage(hWnd,
  1564.                                               dwListBox,
  1565.                                               LB_ADDSTRING,
  1566.                                               0,
  1567.                                               (LPARAM)pGroup->lpszName);
  1568.  
  1569.                     // set the item data to be the item so we can get back it.
  1570.                     if (item != LB_ERR)
  1571.                     {
  1572.                         SendDlgItemMessage(hWnd,
  1573.                                            dwListBox,
  1574.                                            LB_SETITEMDATA,
  1575.                                            (WPARAM)item,
  1576.                                            (LPARAM)pGroup);
  1577.                     }
  1578.  
  1579.                     pGroup = pGroup->pNext;
  1580.                 }
  1581.             }
  1582.  
  1583.             
  1584.             
  1585.             return 1;
  1586.  
  1587.         case WM_COMMAND:
  1588.  
  1589.             switch (LOWORD(wParam))
  1590.             {
  1591.                 case IDC_ADD:
  1592.                 {
  1593.                     // get the item
  1594.                     item = SendDlgItemMessage(hWnd,
  1595.                                               IDC_LIST1,
  1596.                                               LB_GETCURSEL,
  1597.                                               0,
  1598.                                               0);
  1599.  
  1600.                     if (item == 0)
  1601.                     {
  1602.                         if (!SendDlgItemMessage(hWnd,
  1603.                                                 IDC_LIST1,
  1604.                                                 LB_GETSEL,
  1605.                                                 (WPARAM)item,
  1606.                                                 0))
  1607.                         {
  1608.                             item == -1;
  1609.                         }
  1610.                     }
  1611.  
  1612.                     if (item != -1)
  1613.                     {
  1614.                         // get the PGROUP associated with it
  1615.                         pGroup = (PGROUP)SendDlgItemMessage(hWnd,
  1616.                                                                 IDC_LIST1,
  1617.                                                                 LB_GETITEMDATA,
  1618.                                                                 (WPARAM)item,
  1619.                                                                 0);
  1620.  
  1621.                         // delete it from this listbox
  1622.                         SendDlgItemMessage(hWnd,
  1623.                                            IDC_LIST1,
  1624.                                            LB_DELETESTRING,
  1625.                                            (WPARAM)item,
  1626.                                            0);
  1627.  
  1628.                         // add it to this list box
  1629.                         item = SendDlgItemMessage(hWnd,
  1630.                                                   IDC_LIST2,
  1631.                                                   LB_ADDSTRING,
  1632.                                                   0,
  1633.                                                   (LPARAM)pGroup->lpszName);
  1634.  
  1635.                         // set the item data again
  1636.                         SendDlgItemMessage(hWnd,
  1637.                                            IDC_LIST2,
  1638.                                            LB_SETITEMDATA,
  1639.                                            item,
  1640.                                            (WPARAM)pGroup);
  1641.  
  1642.                         // add it to the item's list
  1643.                         InsertIntoGroupList(pGroup,
  1644.                                             pAgent);
  1645.                         
  1646.                         return 1;
  1647.                         
  1648.                     }
  1649.                 }
  1650.                 break;
  1651.                 
  1652.                 case IDC_REMOVE:
  1653.                 {
  1654.                     // get the item
  1655.                     item = SendDlgItemMessage(hWnd,
  1656.                                               IDC_LIST2,
  1657.                                               LB_GETCURSEL,
  1658.                                               0,
  1659.                                               0);
  1660.  
  1661.                     if (item == 0)
  1662.                     {
  1663.                         if (!SendDlgItemMessage(hWnd,
  1664.                                                 IDC_LIST2,
  1665.                                                 LB_GETSEL,
  1666.                                                 (WPARAM)item,
  1667.                                                 0))
  1668.                         {
  1669.                             item == -1;
  1670.                         }
  1671.                     }
  1672.  
  1673.                     if (item != -1)
  1674.                     {
  1675.                         // get the struct associated with it
  1676.                         pGroup = (PGROUP)SendDlgItemMessage(hWnd,
  1677.                                                                 IDC_LIST2,
  1678.                                                                 LB_GETITEMDATA,
  1679.                                                                 (WPARAM)item,
  1680.                                                                 0);
  1681.  
  1682.                         // delete it from this list
  1683.                         SendDlgItemMessage(hWnd,
  1684.                                            IDC_LIST2,
  1685.                                            LB_DELETESTRING,
  1686.                                            (WPARAM)item,
  1687.                                            0);
  1688.  
  1689.                         // add it to this list
  1690.                         item = SendDlgItemMessage(hWnd,
  1691.                                                   IDC_LIST1,
  1692.                                                   LB_ADDSTRING,
  1693.                                                   0,
  1694.                                                   (LPARAM)pGroup->lpszName);
  1695.  
  1696.                         // set the item data
  1697.                         SendDlgItemMessage(hWnd,
  1698.                                            IDC_LIST1,
  1699.                                            LB_SETITEMDATA,
  1700.                                            item,
  1701.                                            (WPARAM)pGroup);
  1702.  
  1703.                         // remove it from the lists
  1704.                         RemoveFromGroupList(pGroup,
  1705.                                             pAgent);
  1706.                         
  1707.                         return 1;
  1708.                         
  1709.                     }
  1710.                     
  1711.                 }
  1712.                 break;
  1713.  
  1714.  
  1715.                 // bug idcancel doesn't cancel
  1716.                 case IDOK:
  1717.                 case IDCANCEL:
  1718.                 {
  1719.                     EndDialog(hWnd, 1);
  1720.                     return 1;
  1721.                 }
  1722.  
  1723.                 default:
  1724.                     return 0;
  1725.             }
  1726.     }
  1727.     return 0;
  1728. }
  1729.  
  1730. //////////////////////////////////////////////////////////////
  1731. //
  1732. //  BOOL DeleteLeafAndStruct(HTREEITEM hItem)
  1733. //    delete hItem from the tree and deleted associated
  1734. //    structure
  1735. //
  1736. //////////////////////////////////////////////////////////////
  1737. BOOL DeleteLeafAndStruct(HTREEITEM hItem)
  1738. {
  1739.     TV_ITEM     tvi;
  1740.  
  1741.     // get the item
  1742.     tvi.mask = TVIF_PARAM;
  1743.     tvi.hItem = hItem;
  1744.  
  1745.     TreeView_GetItem(g.hTreeWnd,
  1746.                      &tvi);
  1747.  
  1748.     // delete the structure
  1749.     if (((PGENERICSTRUCT)tvi.lParam)->dwKey == GROUPKEY)
  1750.     {
  1751.         DeleteGroup((PGROUP)tvi.lParam);
  1752.     }
  1753.     else
  1754.     {
  1755.         DeleteAgent((PAGENT)tvi.lParam);
  1756.     }
  1757.  
  1758.     // remove it from the tree
  1759.     TreeView_DeleteItem(g.hTreeWnd,
  1760.                         hItem);
  1761.  
  1762.     return TRUE;
  1763. }
  1764.  
  1765.  
  1766. ////////////////////////////////////////////////////////////////////
  1767. //
  1768. //  BOOL BuildLineList(HWND hWnd,
  1769. //                     DWORD dwDeviceID)
  1770. //
  1771. //  Fill in ComboBox with names of all available TAPI
  1772. //  devices
  1773. //
  1774. ////////////////////////////////////////////////////////////////////
  1775. BOOL BuildLineList(HWND hWnd,
  1776.                    DWORD dwDeviceID)
  1777. {
  1778.     DWORD               dwDev;
  1779.     LPLINEDEVCAPS       pLineDevCaps;
  1780.     int                 item;
  1781.     BOOL                bSet = FALSE;
  1782.  
  1783.     // clear dropdown box
  1784.     SendMessage(hWnd,
  1785.                 CB_RESETCONTENT,
  1786.                 0,
  1787.                 0);
  1788.  
  1789.     // loop through all devices
  1790.     for (dwDev = 0; dwDev < g.dwNumDevs; dwDev++)
  1791.     {
  1792.         pLineDevCaps = LineGetDevCaps(g.hLineApp,
  1793.                                       dwDev);
  1794.  
  1795.         // add the string to to list
  1796.         if (pLineDevCaps == NULL || pLineDevCaps->dwLineNameSize == 0)
  1797.         {
  1798.             item = SendMessage(hWnd,
  1799.                                CB_ADDSTRING,
  1800.                                0,
  1801.                                (LPARAM)TEXT("NoName"));
  1802.         }
  1803.         else
  1804.         {
  1805.             item = SendMessage(hWnd,
  1806.                                CB_ADDSTRING,
  1807.                                0,
  1808.                                (LPARAM)((LPTSTR)((LPBYTE)pLineDevCaps + pLineDevCaps->dwLineNameOffset)));
  1809.         }
  1810.  
  1811.         // save the device ID
  1812.         SendMessage(hWnd,
  1813.                     CB_SETITEMDATA,
  1814.                     item,
  1815.                     dwDev);
  1816.  
  1817.         // if this is the device we are looking for
  1818.         // set it to be selected
  1819.         if (dwDev == dwDeviceID)
  1820.         {
  1821.             SendMessage(hWnd,
  1822.                         CB_SETCURSEL,
  1823.                         (WPARAM)item,
  1824.                         0);
  1825.  
  1826.             bSet = TRUE;
  1827.         }
  1828.         
  1829.         if (pLineDevCaps != NULL)
  1830.         {
  1831.             ACDFree((HLOCAL)pLineDevCaps);
  1832.         }
  1833.     }
  1834.  
  1835.     // if we didn't set the selection, default
  1836.     if (!bSet)
  1837.     {
  1838.         SendMessage(hWnd,
  1839.                     CB_SETCURSEL,
  1840.                     0,
  1841.                     0);
  1842.     }
  1843.  
  1844.     return TRUE;
  1845. }
  1846.  
  1847.  
  1848. ///////////////////////////////////////////////////////////////////////////////
  1849. //
  1850. //  BOOL BuildAddressList()
  1851. //
  1852. //  Fill combo box with list of addresses on selected device ID
  1853. //
  1854. ///////////////////////////////////////////////////////////////////////////////
  1855. BOOL BuildAddressList(HWND hWnd,
  1856.                       HWND hParentWnd,
  1857.                       DWORD dwAddress)
  1858. {
  1859.     TCHAR               szBuffer[32];
  1860.     LPLINEDEVCAPS       pLineDevCaps;
  1861.     LPLINEADDRESSCAPS   pLineAddressCaps;
  1862.     DWORD               dwCurAddress, dwDeviceID;
  1863.     int                 iCurSel;
  1864.  
  1865.     // clear box
  1866.     SendMessage(hWnd,
  1867.                 CB_RESETCONTENT,
  1868.                 0,
  1869.                 0);
  1870.  
  1871.     // get the current selected device
  1872.     iCurSel = SendDlgItemMessage(hParentWnd,
  1873.                                  IDC_LINECOMBO,
  1874.                                  CB_GETCURSEL,
  1875.                                  0,
  1876.                                  0);
  1877.  
  1878.     // get associated deviceid
  1879.     dwDeviceID = (DWORD)SendDlgItemMessage(hParentWnd,
  1880.                                            IDC_LINECOMBO,
  1881.                                            CB_GETITEMDATA,
  1882.                                            (WPARAM)iCurSel,
  1883.                                            0);
  1884.     
  1885.     pLineDevCaps = LineGetDevCaps(g.hLineApp,
  1886.                                   dwDeviceID);
  1887.  
  1888.     // loop through all addresses
  1889.     for (dwCurAddress = 0; dwCurAddress < pLineDevCaps->dwNumAddresses; dwCurAddress++)
  1890.     {
  1891.         pLineAddressCaps = LineGetAddressCaps(g.hLineApp,
  1892.                                               dwDeviceID,
  1893.                                               dwCurAddress);
  1894.  
  1895.         // add name to list box
  1896.         if (pLineAddressCaps == NULL || pLineAddressCaps->dwAddressSize == 0)
  1897.         {
  1898.             wsprintf(szBuffer, TEXT("Address %d"), dwCurAddress);
  1899.             
  1900.             SendMessage(hWnd,
  1901.                         CB_ADDSTRING,
  1902.                         0,
  1903.                         (LPARAM)szBuffer);
  1904.         }
  1905.         else
  1906.         {
  1907.             SendMessage(hWnd,
  1908.                         CB_ADDSTRING,
  1909.                         0,
  1910.                         (LPARAM)((LPTSTR)((LPBYTE)pLineAddressCaps + pLineAddressCaps->dwAddressOffset)));
  1911.         }
  1912.         
  1913.         ACDFree((HLOCAL)pLineAddressCaps);
  1914.     }
  1915.  
  1916.     SendMessage(hWnd,
  1917.                 CB_SETCURSEL,
  1918.                 (WPARAM)dwAddress,
  1919.                 0);
  1920.  
  1921.     ACDFree(pLineDevCaps);
  1922.     
  1923.     return TRUE;
  1924. }
  1925.  
  1926. ///////////////////////////////////////////////////////////////////////////
  1927. //
  1928. //  BOOL UpdateGroupLeaf(PGROUP pStruct)
  1929. //
  1930. //  Updates a group in the tree view when a new agent is added to that
  1931. //  group
  1932. //
  1933. ///////////////////////////////////////////////////////////////////////////
  1934. BOOL UpdateGroupLeaf(PGROUP pStruct)
  1935. {
  1936.     HTREEITEM   hItem;
  1937.     PLISTITEM   pItem;
  1938.     TV_ITEM     tvi;
  1939.  
  1940.     // get the item's first child
  1941.     hItem = TreeView_GetChild(g.hTreeWnd,
  1942.                               pStruct->hItem);
  1943.  
  1944.     
  1945.     while (hItem)
  1946.     {
  1947.         // delete all childre
  1948.         TreeView_DeleteItem(g.hTreeWnd,
  1949.                             hItem);
  1950.         hItem = TreeView_GetChild(g.hTreeWnd,
  1951.                                   pStruct->hItem);
  1952.     
  1953.     }
  1954.  
  1955.     pItem = pStruct->pAgentList;
  1956.  
  1957.     // walk the agent list
  1958.     while (pItem)
  1959.     {
  1960.         // add all the agents
  1961.         hItem = AddItemToTree(pStruct->hItem,
  1962.                               ((PAGENT)pItem->pAgent)->lpszName,
  1963.                               (LPARAM)NULL,
  1964.                               (HTREEITEM *)NULL);
  1965.  
  1966.  
  1967.         // if currently logged into that group
  1968.         /// bold that item
  1969.         if (pItem->bLoggedIn)
  1970.         {
  1971.             tvi.mask = TVIF_STATE | TVIF_HANDLE;
  1972.             tvi.hItem = hItem;
  1973.             tvi.state = TVIS_BOLD;
  1974.             tvi.stateMask = TVIS_BOLD;
  1975.  
  1976.             TreeView_SetItem(g.hTreeWnd,
  1977.                              &tvi);
  1978.         }
  1979.  
  1980.         pItem = pItem->pNext;
  1981.     }
  1982.  
  1983.     
  1984.     return TRUE;
  1985. }
  1986.  
  1987.  
  1988. ///////////////////////////////////////////////////////////////////////
  1989. //
  1990. //  BOOL DoGroupView()
  1991. //
  1992. //  Display the tree in a "group view" (show groups, and under the
  1993. //  group, the agents that can log into that group)
  1994. //
  1995. ///////////////////////////////////////////////////////////////////////
  1996. BOOL DoGroupView()
  1997. {
  1998.     PGROUP      pGroupParent, pGroup;
  1999.     TCHAR       szGroupParentName[] = TEXT("Groups");
  2000.     HTREEITEM   hItem;
  2001.     TV_ITEM     tvi;
  2002.  
  2003.     g.bGroupView = TRUE;
  2004.  
  2005.     // get the root
  2006.     hItem = TreeView_GetRoot(g.hTreeWnd);
  2007.  
  2008.     // free resources allocated for root
  2009.     if (hItem)
  2010.     {
  2011.         tvi.mask = TVIF_PARAM | TVIF_HANDLE;
  2012.         tvi.hItem = hItem;
  2013.         TreeView_GetItem(g.hTreeWnd,
  2014.                          &tvi);
  2015.  
  2016.         ACDFree((PAGENT)tvi.lParam);
  2017.     }
  2018.  
  2019.     // clear tree
  2020.     TreeView_DeleteAllItems(g.hTreeWnd);
  2021.  
  2022.     // alloc memory for the structure for the Group parent
  2023.     pGroupParent = (PGROUP)ACDAlloc(sizeof(GROUP));
  2024.  
  2025.     // alloc memory and copy the fixed name
  2026.     pGroupParent->lpszName = (LPTSTR)ACDAlloc((lstrlen(szGroupParentName) + 1) * sizeof(TCHAR));
  2027.     pGroupParent->dwKey = GROUPROOTKEY;
  2028.     
  2029.     lstrcpy(pGroupParent->lpszName, szGroupParentName);
  2030.  
  2031.     // add it to the tree
  2032.     g.hGroupParent = AddItemToTree(TVI_ROOT,
  2033.                                    pGroupParent->lpszName,
  2034.                                    (LPARAM)pGroupParent,
  2035.                                    &pGroupParent->hItem);
  2036.  
  2037.     pGroup = g.pGroups;
  2038.  
  2039.     // walk groups and add them to tree
  2040.     while (pGroup)
  2041.     {
  2042.         AddItemToTree(g.hGroupParent,
  2043.                       pGroup->lpszName,
  2044.                       (LPARAM)pGroup,
  2045.                       &pGroup->hItem);
  2046.  
  2047.         UpdateGroupLeaf(pGroup);
  2048.  
  2049.         pGroup = pGroup->pNext;
  2050.     }
  2051.     
  2052.     return TRUE;
  2053. }
  2054.  
  2055.  
  2056. ////////////////////////////////////////////////////////////////////
  2057. //
  2058. //  BOOL DoAgentView()
  2059. //
  2060. //  Displays the tree in an "agent view"
  2061. //
  2062. ////////////////////////////////////////////////////////////////////
  2063. BOOL DoAgentView()
  2064. {
  2065.     PAGENT      pAgentParent,pAgent;
  2066.     TCHAR       szAgentParentName[] = TEXT("Agents");
  2067.     HTREEITEM   hItem;
  2068.     TV_ITEM     tvi;
  2069.  
  2070.     g.bGroupView = TRUE;
  2071.  
  2072.     // get root, free resources
  2073.     // and clear tree
  2074.     hItem = TreeView_GetRoot(g.hTreeWnd);
  2075.  
  2076.     if (hItem)
  2077.     {
  2078.         tvi.mask = TVIF_PARAM | TVIF_HANDLE;
  2079.         tvi.hItem = hItem;
  2080.         TreeView_GetItem(g.hTreeWnd,
  2081.                          &tvi);
  2082.  
  2083.         ACDFree((PGROUP)tvi.lParam);
  2084.     }
  2085.     
  2086.     TreeView_DeleteAllItems(g.hTreeWnd);
  2087.  
  2088.     // alloc memory for the structure for the Agent parent
  2089.     pAgentParent = (PAGENT)ACDAlloc(sizeof(AGENT));
  2090.  
  2091.     // alloc memory and copy the fixed name
  2092.     pAgentParent->lpszName = (LPTSTR)ACDAlloc((lstrlen(szAgentParentName) + 1) * sizeof(TCHAR));
  2093.     pAgentParent->dwKey = GROUPROOTKEY;
  2094.     
  2095.     lstrcpy(pAgentParent->lpszName, szAgentParentName);
  2096.  
  2097.     // add it to the tree
  2098.     g.hAgentParent = AddItemToTree(TVI_ROOT,
  2099.                                    pAgentParent->lpszName,
  2100.                                    (LPARAM)pAgentParent,
  2101.                                    &pAgentParent->hItem);
  2102.  
  2103.     pAgent = g.pAgents;
  2104.  
  2105.     // walk agents and add all of them
  2106.     while (pAgent)
  2107.     {
  2108.         AddItemToTree(g.hAgentParent,
  2109.                       pAgent->lpszName,
  2110.                       (LPARAM)pAgent,
  2111.                       &pAgent->hItem);
  2112.  
  2113.         pAgent = pAgent->pNext;
  2114.     }
  2115.     
  2116.     return TRUE;
  2117. }
  2118.  
  2119. //////////////////////////////////////////////////////////////////////////////////////
  2120. //
  2121. // FOLLOWING ARE ROUTINES TO SAVE AND RESTORE GROUP / AGENT INFORMATION
  2122. //
  2123. // An INI file has been used for this implementation.
  2124. //
  2125. // This format is used to make it easy for users to create an INI file that can be
  2126. // read in
  2127. //
  2128. // However, a real implementation
  2129. // may want to use the registry, or a private data file to store more detailed and/or
  2130. // secure information
  2131. //
  2132. //
  2133.  
  2134. #define SZGROUPS        TEXT("Groups")
  2135. #define SZAGENTS        TEXT("Agents")
  2136. #define SZGROUP         TEXT("GROUP")
  2137. #define SZAGENT         TEXT("AGENT")
  2138. #define SZINIFILE       TEXT("ACDSMPL.INI")
  2139. #define SZGENERAL       TEXT("General")
  2140. #define SZNUMAGENTS     TEXT("NumAgents")
  2141. #define SZNUMGROUPS     TEXT("NumGroups")
  2142.  
  2143. //////////////////////////////////////////////////////////////////////////////
  2144. //
  2145. //  void MakeAgentIndex(PAGENT * ppAgents)
  2146. //
  2147. //  creates an array of pagents
  2148. //
  2149. //////////////////////////////////////////////////////////////////////////////
  2150. void MakeAgentIndex(PAGENT * ppAgents)
  2151. {
  2152.     PAGENT pAgent;
  2153.  
  2154.     pAgent = g.pAgents;
  2155.     
  2156.     while (pAgent)
  2157.     {
  2158.         *ppAgents = pAgent;
  2159.         pAgent = pAgent->pNext;
  2160.         ppAgents++;
  2161.     }
  2162.                 
  2163. }
  2164.  
  2165. ///////////////////////////////////////////////////////////////////////////////
  2166. //
  2167. // int GetAgentIndex()
  2168. //
  2169. // retreives agent index
  2170. //
  2171. ///////////////////////////////////////////////////////////////////////////////
  2172. int GetAgentIndex(PAGENT * ppAgents,
  2173.                   PAGENT pAgent)
  2174. {
  2175.     DWORD   dwCount;
  2176.  
  2177.     for (dwCount = 0; dwCount < g.dwNumAgents; dwCount++)
  2178.     {
  2179.         if (ppAgents[dwCount] == pAgent)
  2180.         {
  2181.             return dwCount;
  2182.         }
  2183.     }
  2184.  
  2185.     return -1;
  2186.  
  2187. }
  2188.  
  2189.  
  2190. ///////////////////////////////////////////////////////////////////////////////
  2191. //
  2192. //  BOOL WriteToDisk()
  2193. //
  2194. //  save current group/agent config to acdsmpl.ini
  2195. //
  2196. ///////////////////////////////////////////////////////////////////////////////
  2197. BOOL WriteToDisk()
  2198. {
  2199.     int         i;
  2200.     PGROUP      pGroup;
  2201.     PAGENT      pAgent;
  2202.     PLISTITEM   pEntry;
  2203.     TCHAR       szGroupName[32], szAgentName[32], szLineBuffer[512];
  2204.     PAGENT *    ppAgents;
  2205.  
  2206.     // create an index of agents
  2207.     ppAgents = (PAGENT *)ACDAlloc(sizeof(PAGENT) * g.dwNumAgents);
  2208.     MakeAgentIndex(ppAgents);
  2209.     
  2210.     pGroup = g.pGroups;
  2211.  
  2212.     i = 0;
  2213.  
  2214.     // walk groups
  2215.     while (pGroup)
  2216.     {
  2217.         wsprintf(szGroupName,
  2218.                  TEXT("%s%d"),
  2219.                  SZGROUP,
  2220.                  i);
  2221.  
  2222.         wsprintf(szLineBuffer,
  2223.                  TEXT("%s,%d,%d"),
  2224.                  pGroup->lpszName,
  2225.                  g.pdwPermIDs[pGroup->dwDeviceID],
  2226.                  pGroup->dwAddress);
  2227.  
  2228.         // add group to [groups] section
  2229.         WritePrivateProfileString(SZGROUPS,
  2230.                                   szGroupName,
  2231.                                   szLineBuffer,
  2232.                                   SZINIFILE);
  2233.  
  2234.         pEntry = pGroup->pAgentList;
  2235.  
  2236.         // walk agents in group
  2237.         while (pEntry)
  2238.         {
  2239.             wsprintf(szAgentName,
  2240.                      TEXT("%s%d"),
  2241.                      SZAGENT,
  2242.                      GetAgentIndex(ppAgents,
  2243.                                    pEntry->pAgent));
  2244.  
  2245.             // write agent index to [groupx] section
  2246.             WritePrivateProfileString(szGroupName,
  2247.                                       szAgentName,
  2248.                                       TEXT("1"),
  2249.                                       SZINIFILE);
  2250.  
  2251.             pEntry = pEntry->pNext;
  2252.         }
  2253.  
  2254.         pGroup = pGroup->pNext;
  2255.  
  2256.         i++;
  2257.     }
  2258.  
  2259.     pAgent = g.pAgents;
  2260.  
  2261.     i = 0;
  2262.  
  2263.     //walk agents
  2264.     while (pAgent)
  2265.     {
  2266.         wsprintf(szAgentName,
  2267.                  TEXT("%s%d"),
  2268.                  SZAGENT,
  2269.                  i);
  2270.  
  2271.         wsprintf(szLineBuffer,
  2272.                  TEXT("%s,%s,%lu"),
  2273.                  pAgent->lpszName,
  2274.                  pAgent->lpszNumber,
  2275.                  g.pdwPermIDs[pAgent->dwDeviceID]);
  2276.  
  2277.         // write agent to [agents] section
  2278.         WritePrivateProfileString(SZAGENTS,
  2279.                                   szAgentName,
  2280.                                   szLineBuffer,
  2281.                                   SZINIFILE);
  2282.  
  2283.         pAgent = pAgent->pNext;
  2284.  
  2285.         i++;
  2286.                  
  2287.     }
  2288.  
  2289.     // save # of agents and groups
  2290.     wsprintf(szLineBuffer,
  2291.              TEXT("%lu"),
  2292.              g.dwNumGroups);
  2293.     
  2294.     WritePrivateProfileString(SZGENERAL,
  2295.                               SZNUMGROUPS,
  2296.                               szLineBuffer,
  2297.                               SZINIFILE);
  2298.     
  2299.     wsprintf(szLineBuffer,
  2300.              TEXT("%lu"),
  2301.              g.dwNumAgents);
  2302.  
  2303.     WritePrivateProfileString(SZGENERAL,
  2304.                               SZNUMAGENTS,
  2305.                               szLineBuffer,
  2306.                               SZINIFILE);
  2307.  
  2308.     ACDFree(ppAgents);
  2309.     
  2310.     return TRUE;
  2311. }
  2312.  
  2313.  
  2314. ////////////////////////////////////////////////////////////////////////////////////
  2315. //
  2316. //  BOOL ReadInFile()
  2317. //
  2318. //   Read in ACDSMPL.INI
  2319. //
  2320. ////////////////////////////////////////////////////////////////////////////////////
  2321. BOOL ReadInFile()
  2322. {
  2323.     TCHAR       szAgentLabel[32],
  2324.                 szGroupLabel[32];
  2325.     DWORD       dwID, dwAddress, dwNumAgents, dwNumGroups;
  2326.     DWORD       dwCount, dwCount2;
  2327.     PAGENT *    ppAgents = NULL;
  2328.     LPTSTR      lpszName, lpszNumber, lpszDeviceID;
  2329.     LPTSTR      lpszHold, szLineBuffer = NULL;
  2330.     PGROUP      pGroup;
  2331.     
  2332.     dwNumAgents = GetPrivateProfileInt(SZGENERAL,
  2333.                                          SZNUMAGENTS,
  2334.                                          0,
  2335.                                          SZINIFILE);
  2336.  
  2337.     dwNumGroups = GetPrivateProfileInt(SZGENERAL,
  2338.                                          SZNUMGROUPS,
  2339.                                          0,
  2340.                                          SZINIFILE);
  2341.  
  2342.     ppAgents = (PAGENT *)ACDAlloc(sizeof(PAGENT) * dwNumAgents);
  2343.     szLineBuffer = (LPTSTR)ACDAlloc(512 * sizeof(WCHAR));
  2344.  
  2345.     if (!ppAgents || !szLineBuffer)
  2346.     {
  2347.         ACDFree(ppAgents);
  2348.         ACDFree(szLineBuffer);
  2349.         return FALSE;
  2350.     }
  2351.  
  2352.     lpszHold = szLineBuffer;
  2353.  
  2354.     for (dwCount = 0; dwCount < dwNumAgents; dwCount++)
  2355.     {
  2356.         wsprintf(szAgentLabel,
  2357.                  TEXT("%s%lu"),
  2358.                  SZAGENT,
  2359.                  dwCount);
  2360.  
  2361.         GetPrivateProfileString(SZAGENTS,
  2362.                                 szAgentLabel,
  2363.                                 TEXT(""),
  2364.                                 szLineBuffer,
  2365.                                 512,
  2366.                                 SZINIFILE);
  2367.  
  2368.         lpszName = (LPTSTR)szLineBuffer;
  2369.         
  2370.         while (szLineBuffer && *szLineBuffer)
  2371.         {
  2372.             if (*szLineBuffer == TEXT(','))
  2373.             {
  2374.                 *szLineBuffer = TEXT('\0');
  2375.                 szLineBuffer++;
  2376.                 break;
  2377.             }
  2378.  
  2379.             szLineBuffer++;
  2380.         }
  2381.  
  2382.         lpszNumber = (LPTSTR)szLineBuffer;
  2383.         
  2384.         while (szLineBuffer && *szLineBuffer)
  2385.         {
  2386.             if (*szLineBuffer == TEXT(','))
  2387.             {
  2388.                 *szLineBuffer = TEXT('\0');
  2389.                 szLineBuffer++;
  2390.                 dwID = _wtol(szLineBuffer);
  2391.                 dwID = GetDeviceID(dwID);
  2392.                 
  2393.                 ppAgents[dwCount] = AddAgent(lpszName,
  2394.                                              lpszNumber,
  2395.                                              dwID);
  2396.  
  2397.                 break;
  2398.             }
  2399.  
  2400.             szLineBuffer++;
  2401.         }
  2402.  
  2403.     }
  2404.  
  2405.     for (dwCount = 0; dwCount < dwNumGroups; dwCount++)
  2406.     {
  2407.         wsprintf(szGroupLabel,
  2408.                  TEXT("%s%lu"),
  2409.                  SZGROUP,
  2410.                  dwCount);
  2411.  
  2412.         GetPrivateProfileString(SZGROUPS,
  2413.                                 szGroupLabel,
  2414.                                 TEXT(""),
  2415.                                 szLineBuffer,
  2416.                                 512,
  2417.                                 SZINIFILE);
  2418.  
  2419.         lpszName = (LPTSTR)szLineBuffer;
  2420.  
  2421.         while (szLineBuffer && *szLineBuffer)
  2422.         {
  2423.             if (*szLineBuffer == TEXT(','))
  2424.             {
  2425.                 *szLineBuffer = TEXT('\0');
  2426.                 szLineBuffer++;
  2427.                 lpszDeviceID = szLineBuffer;
  2428.                 break;
  2429.             }
  2430.  
  2431.             szLineBuffer++;
  2432.         }
  2433.  
  2434.         while (szLineBuffer && *szLineBuffer)
  2435.         {
  2436.             if (*szLineBuffer == TEXT(','))
  2437.             {
  2438.                 *szLineBuffer = TEXT('\0');
  2439.                 szLineBuffer++;
  2440.  
  2441.                 dwAddress = _wtol(szLineBuffer);
  2442.  
  2443.                 break;
  2444.             }
  2445.  
  2446.             szLineBuffer++;
  2447.         }
  2448.  
  2449.         dwID = _wtol(lpszDeviceID);
  2450.         dwID = GetDeviceID(dwID);
  2451.  
  2452.  
  2453.         pGroup = AddGroup(lpszName,
  2454.                           dwID,
  2455.                           dwAddress);
  2456.  
  2457.         if (!pGroup)
  2458.         {
  2459.             continue;
  2460.         }
  2461.         
  2462.         for (dwCount2 = 0; dwCount2 < dwNumAgents; dwCount2++)
  2463.         {
  2464.             wsprintf(szAgentLabel,
  2465.                      TEXT("%s%lu"),
  2466.                      SZAGENT,
  2467.                      dwCount2);
  2468.             
  2469.             if (GetPrivateProfileString(szGroupLabel,
  2470.                                         szAgentLabel,
  2471.                                         TEXT(""),
  2472.                                         szLineBuffer,
  2473.                                         512,
  2474.                                         SZINIFILE) != 0)
  2475.             {
  2476.                 InsertIntoGroupList(pGroup,
  2477.                                     ppAgents[dwCount2]);
  2478.             }
  2479.             
  2480.         }  // for dwcount2
  2481.  
  2482.     }  // for dwcount
  2483.  
  2484.     ACDFree(ppAgents);
  2485.     ACDFree(lpszHold);
  2486.  
  2487.     DoGroupView();
  2488.     
  2489.     return TRUE;
  2490. }
  2491.  
  2492.  
  2493.           
  2494.