home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 58 / pcpp58a.iso / extras / quake 3 source / Q3A_ToolSource.exe / Main / GroupDlg.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-02  |  15.7 KB  |  635 lines

  1. // GroupDlg.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "Radiant.h"
  6. #include "GroupDlg.h"
  7. #include "NameDlg.h"
  8.  
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14.  
  15. #define IMG_PATCH 0
  16. #define IMG_BRUSH 1
  17. #define IMG_GROUP 2
  18. #define IMG_ENTITY 3
  19. #define IMG_ENTITYGROUP 4
  20. #define IMG_MODEL 5
  21. #define IMG_SCRIPT 6
  22.  
  23. // misc group support
  24. #define MAX_GROUPS 4096
  25. #define GROUP_DELIMETER '@'
  26. #define GROUPNAME "QER_Group_%i"
  27.  
  28. CGroupDlg g_wndGroup;
  29. CGroupDlg *g_pGroupDlg = &g_wndGroup;
  30.  
  31. // group_t are loaded / saved through "group_info" entities
  32. // they hold epairs for group settings and additionnal access info (tree nodes)
  33. group_t *g_pGroups = NULL;
  34.  
  35. void Group_Add(entity_t *e)
  36. {
  37.   group_t *g = (group_t*)qmalloc(sizeof(group_t));
  38.   g->epairs = e->epairs;
  39.   g->next = NULL;
  40.   e->epairs = NULL;
  41.   // create a new group node
  42.   HTREEITEM hItem = g_wndGroup.m_wndTree.GetSelectedItem();
  43.   TVINSERTSTRUCT tvInsert;
  44.   memset(&tvInsert, 0, sizeof(TVINSERTSTRUCT));
  45.   tvInsert.item.iImage = IMG_GROUP;
  46.   tvInsert.item.iSelectedImage = tvInsert.item.iImage;
  47.     //++timo wasat?
  48.   // tvInsert.hParent = (hItem) ? hItem : m_hWorld;
  49.   tvInsert.hParent = g_wndGroup.m_hWorld;
  50.   tvInsert.hInsertAfter = NULL;
  51.   tvInsert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  52.   char *pipo = ValueForKey(e->epairs, "group");
  53.   tvInsert.item.pszText = _T(ValueForKey(g->epairs, "group"));
  54.     g->itemOwner = g_wndGroup.m_wndTree.InsertItem(&tvInsert);
  55.   g->next = g_pGroups;
  56.     g_pGroups = g;
  57. }
  58.  
  59. group_t* Group_Alloc(char *name)
  60. {
  61.   group_t *g = (group_t*)qmalloc(sizeof(group_t));
  62.     SetKeyValue( g->epairs, "group", name );
  63.   return g;
  64. }
  65.  
  66. group_t* Group_ForName(const char * name)
  67. {
  68.     group_t *g = g_pGroups;
  69.     while (g != NULL)
  70.     {
  71.         if (strcmp( ValueForKey(g->epairs,"group"), name ) == 0)
  72.             break;
  73.         g = g->next;
  74.     }
  75.     return g;
  76. }
  77.  
  78. void Group_AddToItem(brush_t *b, HTREEITEM item)
  79. {
  80.   char cBuff[1024];
  81.   int nImage = IMG_BRUSH;
  82.     if (!g_qeglobals.m_bBrushPrimitMode)
  83.   {
  84.     return;
  85.   }
  86.   const char *pName = NULL;
  87.   const char *pNamed = Brush_GetKeyValue(b, "name");
  88.  
  89.   if (!b->owner || (b->owner == world_entity))
  90.   {
  91.     if (b->patchBrush) 
  92.     {
  93.       pName = "Generic Patch";
  94.       nImage = IMG_PATCH;
  95.     } 
  96.     else 
  97.     {
  98.       pName = "Generic Brush";
  99.       nImage = IMG_BRUSH;
  100.     }
  101.   } 
  102.   else 
  103.   {
  104.     pName = b->owner->eclass->name;
  105.     if (b->owner->eclass->fixedsize) 
  106.     {
  107.       nImage = IMG_ENTITY;
  108.     } 
  109.     else 
  110.     {
  111.       nImage = IMG_ENTITYGROUP;
  112.     }
  113.   }
  114.  
  115.   strcpy(cBuff, pName);
  116.  
  117.   TVINSERTSTRUCT tvInsert;
  118.   memset(&tvInsert, 0, sizeof(TVINSERTSTRUCT));
  119.   tvInsert.item.iImage = (b->patchBrush) ? IMG_PATCH : IMG_BRUSH;
  120.   tvInsert.item.iSelectedImage = tvInsert.item.iImage;
  121.   tvInsert.hParent = item;
  122.   tvInsert.hInsertAfter = NULL;
  123.   tvInsert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  124.   tvInsert.item.pszText = cBuff;
  125.   HTREEITEM itemNew = g_pGroupDlg->m_wndTree.InsertItem(&tvInsert);
  126.   g_pGroupDlg->m_wndTree.SetItemData(itemNew, reinterpret_cast<DWORD>(b));
  127.   b->itemOwner = itemNew;
  128.   g_pGroupDlg->m_wndTree.RedrawWindow();
  129.  
  130. }
  131.  
  132. void Group_RemoveBrush(brush_t *b)
  133. {
  134.     if (!g_qeglobals.m_bBrushPrimitMode)
  135.     {
  136.         return;
  137.     }
  138.     if (b->itemOwner)
  139.     {
  140.         g_pGroupDlg->m_wndTree.DeleteItem(b->itemOwner);
  141.         b->itemOwner = NULL;
  142.         g_pGroupDlg->m_wndTree.RedrawWindow();
  143.     }
  144.     DeleteKey(b->epairs, "group");
  145. }
  146.  
  147. void Group_AddToWorld(brush_t *b)
  148. {
  149.     if (!g_qeglobals.m_bBrushPrimitMode)
  150.   {
  151.     return;
  152.   }
  153.   HTREEITEM itemParent = g_pGroupDlg->m_wndTree.GetRootItem();
  154.   Group_AddToItem(b, itemParent);
  155. }
  156.  
  157. void Group_AddToProperGroup(brush_t *b)
  158. {
  159.     if (!g_qeglobals.m_bBrushPrimitMode)
  160.     {
  161.         return;
  162.     }
  163.     // NOTE: we do a local copy of the "group" key because it gets erased by Group_RemoveBrush
  164.     const char *pGroup = Brush_GetKeyValue(b, "group");
  165.   // remove the entry in the tree if there's one
  166.   if (b->itemOwner)
  167.   {
  168.         g_pGroupDlg->m_wndTree.DeleteItem(b->itemOwner);
  169.         b->itemOwner = NULL;
  170.         g_pGroupDlg->m_wndTree.RedrawWindow();
  171.   }
  172.  
  173.     if (*pGroup != 0)
  174.     {
  175.         // find the item
  176.         group_t *g = Group_ForName(pGroup);
  177.         if (g)
  178.             Group_AddToItem(b, g->itemOwner);
  179. #ifdef _DEBUG
  180.         else
  181.             Sys_Printf("WARNING: unexpected Group_ForName not found in Group_AddToProperGroup\n");
  182. #endif
  183.     }
  184.     else
  185.     {
  186.         Group_AddToWorld(b);
  187.     }
  188. }
  189.  
  190. void Group_AddToSelected(brush_t *b)
  191. {
  192.     if (!g_qeglobals.m_bBrushPrimitMode)
  193.   {
  194.     return;
  195.   }
  196.   HTREEITEM hItem = g_pGroupDlg->m_wndTree.GetSelectedItem();
  197.   if (hItem == NULL)
  198.   {
  199.     hItem = g_pGroupDlg->m_wndTree.GetRootItem();
  200.   }
  201.   Group_AddToItem(b, hItem);
  202. }
  203.  
  204. void Group_Save(FILE *f)
  205. {
  206.     group_t *g = g_pGroups;
  207.     while (g)
  208.   {
  209.     fprintf(f,"{\n\"classname\" \"group_info\"\n\"group\" \"%s\"\n}\n", ValueForKey( g->epairs, "group" ));
  210.     g = g->next;
  211.   }
  212. }
  213.  
  214. void Group_Init()
  215. {
  216.     if (!g_qeglobals.m_bBrushPrimitMode)
  217.   {
  218.     return;
  219.   }
  220.     // start by cleaning everything
  221.   // clean the groups
  222.   //++timo FIXME: we leak, delete the groups on the way (I don't have time to do it now)
  223. #ifdef _DEBUG
  224.   Sys_Printf("TODO: fix leak in Group_Init\n");
  225. #endif
  226.   group_t *g = g_pGroups;
  227.   while (g)
  228.   {
  229.     epair_t *ep,*enext;
  230.       for (ep = g->epairs ; ep ; ep=enext )
  231.       {
  232.           enext = ep->next;
  233.           free (ep->key);
  234.           free (ep->value);
  235.           free (ep);
  236.       }
  237.     g = g->next;
  238.   }
  239.   g_pGroups = NULL;
  240.     g_wndGroup.m_wndTree.DeleteAllItems();
  241.   TVINSERTSTRUCT tvInsert;
  242.   memset(&tvInsert, 0, sizeof(TVINSERTSTRUCT));
  243.   tvInsert.hParent = NULL;
  244.   tvInsert.hInsertAfter = NULL;
  245.   tvInsert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  246.   tvInsert.item.pszText = _T("World");
  247.   tvInsert.item.iImage = IMG_GROUP;
  248.   tvInsert.item.iSelectedImage = IMG_GROUP;
  249.   HTREEITEM hWorld = g_wndGroup.m_wndTree.InsertItem(&tvInsert);
  250.     // walk through all the brushes, remove the itemOwner key and add them back where they belong
  251.     brush_t *b;
  252.     for (b = active_brushes.next; b != &active_brushes; b = b->next)
  253.     {
  254.         b->itemOwner = NULL;
  255.         Group_AddToProperGroup(b);
  256.     }
  257.     for (b = selected_brushes.next ; b != &selected_brushes ; b = b->next)
  258.     {
  259.         b->itemOwner = NULL;
  260.         Group_AddToProperGroup(b);
  261.     }
  262. }
  263.  
  264. // scan through world_entity for groups in this map?
  265. // we use GROUPNAME "QER_group_%i" to look for existing groups and their naming
  266. //++timo FIXME: is this actually needed for anything?
  267. void Group_GetListFromWorld(CStringArray *pArray)
  268. {
  269.     if (!g_qeglobals.m_bBrushPrimitMode)
  270.   {
  271.     return;
  272.   }
  273.  
  274.   if (world_entity == NULL)
  275.   {
  276.     return;
  277.   }
  278.  
  279.   pArray->RemoveAll();
  280.   char cBuff[1024];
  281.   for (int i =0; i < MAX_GROUPS; i++)
  282.   {
  283.     sprintf(cBuff, GROUPNAME, i);
  284.     char *pGroup = ValueForKey(world_entity, cBuff);
  285.     if (pGroup && strlen(pGroup) > 0)
  286.     {
  287.       pArray->Add(pGroup);
  288.     }
  289.     else
  290.     {
  291.       break;
  292.     }
  293.   }
  294. }
  295.  
  296. void Group_RemoveListFromWorld()
  297. {
  298.     if (!g_qeglobals.m_bBrushPrimitMode)
  299.   {
  300.     return;
  301.   }
  302.   CStringArray array;
  303.   Group_GetListFromWorld(&array);
  304.   int nCount = array.GetSize();
  305.   for (int i = 0; i < nCount; i++)
  306.   {
  307.     DeleteKey(world_entity, array.GetAt(i));
  308.   }
  309. }
  310.  
  311. /*
  312. void Group_SetListToWorld(CStringArray *pArray)
  313. {
  314.     if (!g_qeglobals.m_bBrushPrimitMode)
  315.   {
  316.     return;
  317.   }
  318.   char cBuff[1024];
  319.   Group_RemoveListFromWorld();
  320.   int nCount = pArray->GetSize();
  321.   for (int i = 0; i < nCount; i++)
  322.   {
  323.     sprintf(cBuff, GROUPNAME, i);
  324.     SetKeyValue(world_entity, cBuff, pArray->GetAt(i));
  325.   }
  326. }
  327. */
  328.  
  329. int CountChar(const char *p, char c)
  330. {
  331.   int nCount = 0;
  332.   int nLen = strlen(p)-1;
  333.   while (nLen-- >= 0)
  334.   {
  335.     if (p[nLen] == c)
  336.     {
  337.       nCount++;
  338.     }
  339.   }
  340.   return nCount;
  341. }
  342.  
  343. /*
  344. // this is not very efficient but should get the job done
  345. // as our trees should never be too big
  346. void Group_BuildTree(CTreeCtrl *pTree)
  347. {
  348.     if (!g_qeglobals.m_bBrushPrimitMode)
  349.   {
  350.     return;
  351.   }
  352.   CStringArray array;
  353.   int i;
  354.   CString strTemp;
  355.   CString strRight;
  356.  
  357.   //++timo WARNING: this is very dangerous! delete all tree items, without checking the brushes
  358.   pTree->DeleteAllItems();
  359.   TVINSERTSTRUCT tvInsert;
  360.   memset(&tvInsert, 0, sizeof(TVINSERTSTRUCT));
  361.   tvInsert.hParent = NULL;
  362.   tvInsert.hInsertAfter = NULL;
  363.   tvInsert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  364.   tvInsert.item.pszText = _T("World");
  365.   tvInsert.item.iImage = IMG_GROUP;
  366.   tvInsert.item.iSelectedImage = IMG_GROUP;
  367.   HTREEITEM hWorld = pTree->InsertItem(&tvInsert);
  368.  
  369.   Group_GetListFromWorld(&array);
  370.  
  371.   // groups use @ to delimit levels, the number of @ signs
  372.   // start with ROOT item
  373.   // nothing is a peer with world, it is ancestor to everything 
  374.   // expects things in order so first entry should be a 2nd level item
  375.   HTREEITEM itemParent = pTree->GetRootItem();
  376.   HTREEITEM itemLast = itemParent;
  377.   int nCount = array.GetSize();
  378.   int nLastLevel = 1;
  379.   for (i = 0; i < nCount; i++)
  380.   {
  381.     strTemp = array.GetAt(i);
  382.     int nLevel = CountChar(strTemp, GROUP_DELIMETER);
  383.     if (nLevel < nLastLevel)
  384.     {
  385.       int nLevelsUp = nLastLevel - nLevel;
  386.       while (nLevelsUp-- > 0)
  387.       {
  388.         itemParent = pTree->GetParentItem(itemParent);
  389.       }
  390.     }
  391.     else if (nLevel > nLastLevel)
  392.     {
  393.       itemParent = itemLast;
  394.     }
  395.     nLastLevel = nLevel;
  396.     char *pLast = strrchr(strTemp, GROUP_DELIMETER);
  397.     pLast++;
  398.     itemLast = pTree->InsertItem(pLast, itemParent);
  399.   }
  400. }
  401. */
  402.  
  403. void DecomposeSiblingList(const char *p, CStringArray *pArray, CTreeCtrl *pTree, HTREEITEM itemChild)
  404. {
  405.   CString str = p;
  406.   str += GROUP_DELIMETER;
  407.   while (itemChild)
  408.   {
  409.     CString strAdd = str;
  410.     strAdd += pTree->GetItemText(itemChild);
  411.     // do not want to add brushes or things, just groups 
  412.     if (pTree->GetItemData(itemChild) == 0)
  413.     {
  414.       pArray->Add(strAdd);
  415.     }
  416.     if (pTree->ItemHasChildren(itemChild))
  417.     {
  418.       HTREEITEM itemOffspring = pTree->GetChildItem(itemChild);
  419.       DecomposeSiblingList(strAdd, pArray, pTree, itemOffspring); 
  420.     }
  421.     itemChild = pTree->GetNextSiblingItem(itemChild);
  422.   }
  423. }
  424.  
  425. /*
  426. void Group_DecomposeTree(CTreeCtrl *pTree)
  427. {
  428.     if (!g_qeglobals.m_bBrushPrimitMode)
  429.   {
  430.     return;
  431.   }
  432.   CStringArray array;
  433.   HTREEITEM itemParent = pTree->GetRootItem();
  434.   if (pTree->ItemHasChildren(itemParent))
  435.   {
  436.     HTREEITEM itemChild = pTree->GetChildItem(itemParent);
  437.     DecomposeSiblingList(pTree->GetItemText(itemParent), &array, pTree, itemChild);
  438.   }
  439.   Group_SetListToWorld(&array);
  440. }
  441. */
  442.  
  443. /////////////////////////////////////////////////////////////////////////////
  444. // CGroupDlg dialog
  445.  
  446.  
  447. CGroupDlg::CGroupDlg(CWnd* pParent /*=NULL*/)
  448.     : CDialog(CGroupDlg::IDD, pParent)
  449. {
  450.     //{{AFX_DATA_INIT(CGroupDlg)
  451.         // NOTE: the ClassWizard will add member initialization here
  452.     //}}AFX_DATA_INIT
  453. }
  454.  
  455.  
  456. void CGroupDlg::DoDataExchange(CDataExchange* pDX)
  457. {
  458.     CDialog::DoDataExchange(pDX);
  459.     //{{AFX_DATA_MAP(CGroupDlg)
  460.     DDX_Control(pDX, IDC_TREE_GROUP, m_wndTree);
  461.     DDX_Control(pDX, IDC_BTN_EDIT, m_wndEdit);
  462.     DDX_Control(pDX, IDC_BTN_DEL, m_wndDel);
  463.     DDX_Control(pDX, IDC_BTN_ADD, m_wndAdd);
  464.     //}}AFX_DATA_MAP
  465. }
  466.  
  467.  
  468. BEGIN_MESSAGE_MAP(CGroupDlg, CDialog)
  469.     //{{AFX_MSG_MAP(CGroupDlg)
  470.     ON_WM_SIZE()
  471.     ON_BN_CLICKED(IDC_BTN_ADD, OnBtnAdd)
  472.     ON_BN_CLICKED(IDC_BTN_DEL, OnBtnDel)
  473.     ON_BN_CLICKED(IDC_BTN_EDIT, OnBtnEdit)
  474.     ON_NOTIFY(NM_RCLICK, IDC_TREE_GROUP, OnRclickTreeGroup)
  475.     ON_NOTIFY(TVN_ENDLABELEDIT, IDC_TREE_GROUP, OnEndlabeleditTreeGroup)
  476.     ON_NOTIFY(NM_CLICK, IDC_TREE_GROUP, OnClickTreeGroup)
  477.     ON_NOTIFY(TVN_SETDISPINFO, IDC_TREE_GROUP, OnSetdispinfoTreeGroup)
  478.     ON_NOTIFY(TVN_BEGINDRAG, IDC_TREE_GROUP, OnBegindragTreeGroup)
  479.     //}}AFX_MSG_MAP
  480. END_MESSAGE_MAP()
  481.  
  482. /////////////////////////////////////////////////////////////////////////////
  483. // CGroupDlg message handlers
  484.  
  485. void CGroupDlg::OnSize(UINT nType, int cx, int cy) 
  486. {
  487.     CDialog::OnSize(nType, cx, cy);
  488.     CRect rct;
  489.   GetClientRect(rct);
  490.  
  491.   if ( m_wndAdd.GetSafeHwnd())
  492.   {
  493.     //all borders at 4, spacing at 6
  494.     CRect rctButton;
  495.     m_wndAdd.GetWindowRect(rctButton);
  496.     int nWidth = rctButton.Width();
  497.     int nHeight = rctButton.Height();
  498.  
  499.     int nTop = rct.Height() - nHeight - 4;
  500.  
  501.     m_wndAdd.SetWindowPos(NULL, 4, nTop, 0, 0, SWP_NOSIZE);
  502.     m_wndEdit.SetWindowPos(NULL, 8 + nWidth , nTop, 0, 0, SWP_NOSIZE);
  503.     m_wndDel.SetWindowPos(NULL, 12 + (nWidth * 2), nTop, 0, 0, SWP_NOSIZE);
  504.     rct.bottom = nTop;
  505.     m_wndTree.SetWindowPos(NULL, rct.left + 4, rct.top + 4, rct.Width() - 8, rct.Height() - 8, SWP_SHOWWINDOW);
  506.   }
  507. }
  508.  
  509. BOOL CGroupDlg::OnInitDialog() 
  510. {
  511.     CDialog::OnInitDialog();
  512.     m_imgList.Create(IDB_BITMAP_GROUPS, 16, 0, ILC_COLOR);
  513.     m_wndTree.SetImageList(&m_imgList, TVSIL_NORMAL);
  514.     InitGroups();
  515.     return TRUE;  // return TRUE unless you set the focus to a control
  516.     // EXCEPTION: OCX Property Pages should return FALSE
  517. }
  518.  
  519. void CGroupDlg::InitGroups()
  520. {
  521.     Group_Init();
  522. }
  523.  
  524. // add a new group, put all selected brushes into the group
  525. void CGroupDlg::OnBtnAdd() 
  526. {
  527.   CNameDlg dlg("New Group", this);
  528.   if (dlg.DoModal() == IDOK)
  529.   {
  530.         // create a new group node
  531.     HTREEITEM hItem = m_wndTree.GetSelectedItem();
  532.     TVINSERTSTRUCT tvInsert;
  533.     memset(&tvInsert, 0, sizeof(TVINSERTSTRUCT));
  534.     tvInsert.item.iImage = IMG_GROUP;
  535.     tvInsert.item.iSelectedImage = tvInsert.item.iImage;
  536.         //++timo wasat?
  537.     // tvInsert.hParent = (hItem) ? hItem : m_hWorld;
  538.     tvInsert.hParent = m_hWorld;
  539.     tvInsert.hInsertAfter = NULL;
  540.     tvInsert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  541.     tvInsert.item.pszText = _T(dlg.m_strName.GetBuffer(0));
  542.         // create a new group
  543.         group_t *g = Group_Alloc( dlg.m_strName.GetBuffer(0) );
  544.         g->itemOwner = m_wndTree.InsertItem(&tvInsert);
  545.         g->next = g_pGroups;
  546.         g_pGroups = g;
  547.         // now add the selected brushes
  548.         // NOTE: it would be much faster to give the group_t for adding
  549.         // but Select_AddToGroup is the standard way for all other cases
  550.         Select_AddToGroup( dlg.m_strName.GetBuffer(0) );
  551.   }
  552. }
  553.  
  554. void CGroupDlg::OnBtnDel() 
  555. {
  556. }
  557.  
  558. void CGroupDlg::OnBtnEdit() 
  559. {
  560. }
  561.  
  562. BOOL CGroupDlg::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult) 
  563. {
  564.     return CDialog::OnChildNotify(message, wParam, lParam, pLResult);
  565. }
  566.  
  567. BOOL CGroupDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) 
  568. {
  569.   return CDialog::OnNotify(wParam, lParam, pResult);
  570. }
  571.  
  572. void CGroupDlg::OnRclickTreeGroup(NMHDR* pNMHDR, LRESULT* pResult) 
  573. {
  574.     // TODO: Add your control notification handler code here
  575.     
  576.     *pResult = 0;
  577. }
  578.  
  579. void CGroupDlg::OnEndlabeleditTreeGroup(NMHDR* pNMHDR, LRESULT* pResult) 
  580. {
  581.     TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
  582.   const char *pText = pTVDispInfo->item.pszText;
  583.   if (pText && strlen(pText) > 0)
  584.   {
  585.     HTREEITEM item = pTVDispInfo->item.hItem;
  586.     if (m_wndTree.GetRootItem() != item)
  587.     {
  588.       m_wndTree.SetItemText(item, pText);
  589.       if (pTVDispInfo->item.iImage != IMG_GROUP)
  590.       {
  591.         // if it is an entity
  592.       }
  593.     }
  594.     else
  595.     {
  596.       Sys_Printf("Cannot rename the world\n");
  597.     }
  598.   }
  599.   m_wndTree.RedrawWindow();
  600.     *pResult = 0;
  601. }
  602.  
  603. void CGroupDlg::OnClickTreeGroup(NMHDR* pNMHDR, LRESULT* pResult) 
  604. {
  605.     // TODO: Add your control notification handler code here
  606.     
  607.     *pResult = 0;
  608. }
  609.  
  610. void CGroupDlg::OnSetdispinfoTreeGroup(NMHDR* pNMHDR, LRESULT* pResult) 
  611. {
  612.     TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
  613.     // TODO: Add your control notification handler code here
  614.     
  615.     *pResult = 0;
  616. }
  617.  
  618. void CGroupDlg::OnCancel()
  619. {
  620.   TreeView_EndEditLabelNow(m_wndTree.GetSafeHwnd(), TRUE);
  621. }
  622.  
  623. void CGroupDlg::OnOK()
  624. {
  625.   TreeView_EndEditLabelNow(m_wndTree.GetSafeHwnd(), FALSE);
  626. }
  627.  
  628. void CGroupDlg::OnBegindragTreeGroup(NMHDR* pNMHDR, LRESULT* pResult) 
  629. {
  630.     NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  631.     // TODO: Add your control notification handler code here
  632.     
  633.     *pResult = 0;
  634. }
  635.