xj qian
2024-12-05 bd09edf1b441dcc6ab098f277bea86a72c009879
jrj/xframe/devloper/XDevEditXMSSQL.cpp
@@ -4,187 +4,177 @@
#include <wobject/xaserverarg.hpp>
#include <xcontrol/xtreeview.hpp>
#include <xcontrol/xlayersheet.hpp>
#include <xcontrol/xtreeview.hpp>
#include <xcontrol/xlayersheet.hpp>
#include <xcontrol/xsedit.hpp>
#include <xcontrol/xdwgrid.hpp>
#include "XDevEditPage.hpp"
using xml = KXMLDOMDocument;
class export XDeveloper : public xwin
class export XDevEditXMSSQL : public XDevEditPage
{
   public:
   XDeveloper(void* implPtr, HWND hWnd) :xwin(implPtr, hWnd),mle_output(nullptr) {}
public:
   static XDeveloper* CreateInstance(void* implPtr, void* hWnd)
   XDevEditXMSSQL(void* implPtr, HWND hWnd) :XDevEditPage(implPtr, hWnd) {}
public:
   static XDevEditXMSSQL* CreateInstance(void* implPtr, void* hWnd)
   {
      XDeveloper* pWin = new XDeveloper(implPtr, (HWND)hWnd);
      XDevEditXMSSQL* pWin = new XDevEditXMSSQL(implPtr, (HWND)hWnd);
      return pWin;
   }
private:   //
   xtreeview tv_folder;
   xcontrol mle_output;
   int sheet_Count;
public:
   int trace(xstring msg)
   xtreeview tv_db;
   xlayersheet list;
   //xnode   m_agentNode;   //Agent Condition
   //xstring   m_agentCond;   //Agent Node
   int SetAgent()
   {
      xstring t = mle_output.GetText();
      mle_output.SetText(t + msg);
      return 1;
   }
   int OnProcessUrl(xstring kind, xstring url)
   {
      xml x ;
      xaserverarg xarg;
      xarg.AddArg(L"url", url);
      xarg.AddArg(L"kind", kind);
      xaserver::ExecXQuery(GetServerUrl(), L"[service.url.info.xq]", xarg.GetString(), x);
      alert(x.xml());
      return 1;
   }
   xstring ProcessDevCmd(xstring cmd, xstring ext)
   {
      int nlen = 0;
      BYTE* pdata=nullptr;
      xaserver::ProcessCmd(GetServerUrl(),( L"uri.hxsoft.com/xaserver/developer " + cmd).c_str(), ext.c_str(), pdata, nlen);
      xstring str = ((LPARAM)pdata) + L"";
      return str;
   }
   int SetAgent(xstring node)
   {
      auto n = GetElement().selectSingleNode(L"agent/projects/node()[1]");
      if (n)
      {
         xstring agent = n.xml();
         xstring xfNodeAgentArea = L"agentarea";
         xnode anode = GetAgentNode(xfNodeAgentArea);
         SetAgentNode(anode, agent);
      }
      return 1;
   }
   HTREEITEM GetProjectItem(HTREEITEM hItem)
   {
      HTREEITEM pitem = hItem;
      xstring typ;
      while (true)
      {
         typ = ((KXMLDOMElement)tv_folder.GetItemData(pitem)).tagName();
         if (typ == L"project")break;
         pitem = tv_folder.GetParentItem(pitem);
         if (!pitem )break;
      }
      return pitem;
   }
   HTREEITEM GetP2Item(HTREEITEM hItem)
   {
      HTREEITEM hDomainItem;
      HTREEITEM hP2Item = hItem;
      while (true)
      {
         hDomainItem = tv_folder.GetParentItem(hP2Item);
         if (!tv_folder.GetParentItem(hDomainItem))break;
         hP2Item = hDomainItem;
      }
      return hP2Item;
   }
   //树展开事件
   int OnTreeExpanding(TEvent* evt, HTREEITEM param)
   {
      NMTREEVIEW& nmtv = *(NMTREEVIEW*)evt->notify.pnmh;
      HTREEITEM hItem = nmtv.itemNew.hItem;
      return 1;
   }
   xstring GetData(HTREEITEM hItem)
   {
      KXMLDOMElement e = tv_folder.GetItemData(hItem);
      xstring node = e.tagName();
      if (node == L"File" || node == L"file")
      {
         HTREEITEM hP2Item = 0;
         HTREEITEM hDomainItem = 0;
         if (!tv_folder.GetParentItem(hItem))
         {
            hDomainItem = hItem;
         }
         else
         {
            hP2Item = GetP2Item(hItem);
            hDomainItem = tv_folder.GetParentItem(hP2Item);
         }
         //find project folder
         xstring prjguid = L"";
         HTREEITEM pitem = GetProjectItem(hItem);
         if (pitem)
            prjguid = ((KXMLDOMElement)tv_folder.GetItemData(pitem)).getAttribute(L"guid");
         xaserverarg arg;
         arg.AddArg(L"project.guid", prjguid);
         if (hP2Item)
         {
            if (hP2Item != hItem)
      /*      xstring xfNodeAgentArea  = L"agentarea";
            xnode anode = GetAgentNode(xfNodeAgentArea);
            var xframeElement =  GetElement();
            var agent = xframeElement.selectSingleNode(L"agent/"+xfNodeAgentArea+L"[1]/*");
            if(agent)
            {
               xstring guid = e.getAttribute(L"guid");
               arg.AddArg(L"guid", guid);
               xstring s = agent.xml;
               m_agentNode =  SetAgentNodeContent (anode,s);
            }
            KXMLDOMElement p = tv_folder.GetItemData(hP2Item);
            xstring guid = p.getAttribute(L"guid");
            arg.AddArg(L"root.guid", guid);
      */      return 1;
         }
         else if (hDomainItem)
         {
            KXMLDOMElement d = tv_folder.GetItemData(hDomainItem);
            xstring guid = d.getAttribute(L"guid");
            arg.AddArg(L"domain.guid", guid);
         }
         xstring str = ProcessDevCmd(L"getobject", arg.GetString());
         return str + L"";
      }
      else
         return L"";
   //焦点激活处理函数
   int OnSetFocus(TEvent* evt,LPARAM param)
   {
      SetAgent();
      //重置工具条
      return 1;
   }
   int OnTreeDblClick(TEvent* evt, int param)
   xstring getLink(HTREEITEM item)
   {
      HTREEITEM hItem = tv_folder.GetSelectedItem();
      if (!hItem) return 0;
      xlayersheet layer = GetControl(L"mdilayer");
      int i = 0;
      int nIndex = layer.GetSheetCount();
      for (i = 0; i < nIndex; i++)
      HTREEITEM p = tv_db.GetParentItem(item);
      while (tv_db.GetParentItem(p) > 0)
      {
         if (hItem == layer.GetParam(i))break;
         item = tv_db.GetParentItem(item);
         p = tv_db.GetParentItem(item);
      }
      if (i < nIndex)
      xstring link = tv_db.GetItemData(item);
      return link;
   }
   KXMLDOMElement OnXQuery(xstring data)
   {
      HTREEITEM item = tv_db.GetSelectedItem();
      xstring link = getLink(item);
      xml x ;
      xaserverarg arg;
      arg.AddArg(L"type",data);
      arg.AddArg(L"link",link);
      if (xaserver::ExecXQuery(GetServerUrl(),L"[MSSQL.list.xq]",arg.GetString(),x) != 1)
      {
         layer.SelectSheet(i);
         trace(x.xml());
         return 1;
      }
      KXMLDOMElement e = tv_folder.GetItemData(hItem);
      xstring node = e.tagName();
      if (node == L"File" || node == L"file")
      return x.documentElement();
   }
   int setGrid(KXMLDOMElement e,xstring caption)
   {
      xml x;
      xdwgrid grid = GetControl(caption);
      if (!e.selectSingleNode(L"grid/sheet")) return 0;
      x.loadXML(e.selectSingleNode(L"grid/sheet").xml());
      grid.SetDataObject(x);
      if (!e.selectSingleNode(L"datas")) return 0;
      x.loadXML(e.selectSingleNode(L"datas").xml());
      grid.Retrieve(x);
      grid.Redraw();
      return 1;
   }
   xstring replace(xstring a, xstring b, xstring c, int s=0)
   {
      int k = a.find(b,s);
      if (k > -1)
      {
         //xstring str =  ProcessDevCmd(L"getobject",arg.GetString());
         xstring typ = e.getAttribute(L"type");
         xstring str;
         if (k == 0)
            str = L"" + c + a.right(a.length() - k - b.length());
         else if (k + b.length() == a.length())
            str = L"" + a.left(k) + c;
         else
            str = L"" + a.left(k) + c + a.right(a.length() - k - b.length());
         replace(str, b, c, k + b.length() + 1);
      }
      else
         return a;
   }
         xml x ;
         xaserver::FetchXml(GetServerUrl(), L"dev:xpage[XDevEdit.xml]", L"", x);
         auto n = x.selectSingleNode(L"//editor[@filetype='" + typ + L"']/@xpage");
         if (n)
         {
            xstring xpage = n.text();
            OpenWindow(L"dev:xpage[" + xpage + L"]", (LPARAM)hItem);
            //layer.
            if (nIndex < layer.GetSheetCount())
               layer.SetParam(nIndex, hItem);
         }
   int OnOpen(xstring caption,xstring node)
   {
      int s = list.GetSheetCount();
      int i;
      xstring pa = node + L"." + caption;
      for (i = 0; i < s; i++)
      {
         xstring p = (wchar_t*)list.GetParam(i);
         if (pa == p)
            break;
      }
      if (i < s)
      {
         list.SelectSheet(i);
         return 0;
      }
      KXMLDOMElement xframeElement = GetElement();
      KXMLDOMElement agent = xframeElement.selectSingleNode(L"agent/" + node + L"/*");
      xstring str = replace(agent.xml(), L"{#1}", caption);
      xml x ;
      x.loadXML(str);
      int k = list.InsertSheet(-1,(LPTSTR)caption.c_str(), x.documentElement());
      list.SelectSheet(k);
      list.SetParam(k,(void*)pa.c_str(true));
      return 1;
   }
   int onShow()
   {
      while (tv_db.GetRootItem() > 0)
         tv_db.DeleteItem(tv_db.GetRootItem());
      xsedit xs = GetControl(L"xcontent");
      xstring content;
      xs.GetContent(content);
      xml x ;
      x.loadXML(content);
      KXMLDOMElement e = x.documentElement();
      xstring name = e.getAttribute(L"name");
      HTREEITEM root = tv_db.InsertItem(name.c_str(), NULL, 16);
      auto lists = e.selectNodes(L"*");
      int i;
      int s = lists.length();
      for (i = 0; i < s; i++)
      {
         KXMLDOMElement ele = lists.item(i);
         xstring name = ele.getAttribute(L"name");
         xstring link = ele.getAttribute(L"link");
         HTREEITEM k = tv_db.InsertChildItem(root,L"" + name,L"" + link,15);
         HTREEITEM j = tv_db.InsertChildItem(k,L"表",L"table",22);
         tv_db.SetItemChild1(j,1);
         j = tv_db.InsertChildItem(k,L"视图",L"view",23);
         tv_db.SetItemChild1(j,1);
         j = tv_db.InsertChildItem(k,L"存储过程",L"procedure",24);
         tv_db.SetItemChild1(j,1);
         j = tv_db.InsertChildItem(k,L"自定义函数",L"function",25);
         tv_db.SetItemChild1(j,1);
      }
      tv_db.ExpandItem(root);
      if (list.GetSheetCount() < 1)
      {
         xstring caption = L"Query";
         if (OnOpen(caption,L"query") == 0) return 0;
         xsedit xs = GetControl(L"sql_" + caption);
         xs.LoadContent(L"",L".sql");
      }
      return 1;
   }
@@ -192,356 +182,411 @@
   //命令发布函数
   int OnCmdDispatch(xstring comdid)
   {
      //
      if (comdid == L"xmSqlWatch")
      HCURSOR hCursor = xutil::SetCursorWait();
      xsedit xs = GetControl(L"xcontent");
      xstring content;
      xs.GetContent(content);
      if (comdid == L"xmFileSave")
      {
         OpenWindow(L"dev:xpage[sqlWatch.vx]");
         return 1;
         //save xml content
         SaveContent(content);
      }
      if (comdid == L"xmCheckUrl")
      else if (comdid == L"xmValid")
      {
         xcontrol xc = GetControl(L"url");
         xstring url = xc.GetText();
         return OnProcessUrl(L"info", url);
      }
      else if (comdid == L"xmClearBuffer")
      {
         xcontrol xc = GetControl(L"url");
         xstring url = xc.GetText();
         return OnProcessUrl(L"clearbuffer", url);
      }
      if (comdid == L"xmNewFolder" || comdid == L"xmNewProject" || comdid == L"xmNewFile")
      {
         HTREEITEM hItem = tv_folder.GetSelectedItem();
         if (!hItem) return 1;
         //find project folder
         xstring prjguid = L"";
         HTREEITEM pitem = GetProjectItem(hItem);
         if (pitem)
            prjguid = ((KXMLDOMElement)tv_folder.GetItemData(pitem)).getAttribute(L"guid");
         if (comdid == L"xmNewProject" && prjguid != L"") return 1;
         if (comdid == L"xmNewFile" && !tv_folder.GetParentItem(hItem)) return 1;
         xaserverarg arg;
         if (comdid == L"xmNewProject")
            OpenWindow(L"dev:xpage[XDevProjectDlg.xpage]", arg);
         else if (comdid == L"xmNewFolder")
            OpenWindow(L"dev:xpage[XDevItemDlg.xpage]", arg);
         else
            OpenWindow(L"dev:xpage[XDevFileDlg.xpage]", arg);
         if (arg.GetArgString(L"__process") != L"true") return 1;
         arg.SetArg(L"project.guid", prjguid);
         HTREEITEM hP2Item = 0;
         HTREEITEM hDomainItem = 0;
         KXMLDOMElement e;
         if (!tv_folder.GetParentItem(hItem))
         xml x ;
         if (!x.loadXML(content))
         {
            hDomainItem = hItem;
         }
         else
         {
            hP2Item = GetP2Item(hItem);
            hDomainItem = tv_folder.GetParentItem(hP2Item);
         }
         e = tv_folder.GetItemData(hItem);
         if (hP2Item)
         {
            if (hP2Item != hItem)
            KXMLDOMParseError pError = x.parseError();
            if (pError)
            {
               xstring guid = e.getAttribute(L"guid");
               arg.AddArg(L"parent.guid", guid);
               xstring str = pError.srcText();
               xstring sError = L"\r\nMSSQL错误: " + str.trim() + L"\r\n";
               int s = pError.errorCode();
               sError += L"     代码: " + xstring(s) + L"\r\n";
               s = pError.line();
               sError += L"     位置: 第" + xstring(s) + L"行,L";
               s = pError.linepos();
               sError += L"第" + xstring(s) + L"列" + L"\r\n";
               str = pError.reason();
               sError += L"     原因: " + str;
               trace(sError);
            }
            KXMLDOMElement p = tv_folder.GetItemData(hP2Item);
            xstring guid = p.getAttribute(L"guid");
            arg.AddArg(L"root.guid", guid);
         }
         else if (hDomainItem)
         {
            KXMLDOMElement d = tv_folder.GetItemData(hDomainItem);
            xstring guid = d.getAttribute(L"guid");
            arg.AddArg(L"domain.guid", guid);
         }
         if (hP2Item)
         {
            if (comdid == L"xmNewFolder")
            else
            {
               if (arg.GetArgString(L"image") == L"")
                  arg.AddArg(L"image", L"15");
               arg.AddArg(L"folder", L"folder");
               arg.AddArg(L"type", L"folder");
               trace(L"XML 错误");
            }
            return -1;
         }
         else
         {
            if (comdid == L"xmNewFolder")
            {
               if (arg.GetArgString(L"image") == L"")
                  arg.AddArg(L"image", L"17");
               arg.AddArg(L"folder", L"folder");
               arg.AddArg(L"type", L"folder");
            }
         }
         xstring str = ProcessDevCmd(L"addfolder", arg.GetString());
         if (str != L"")
         {
            xml x;
            x.loadXML(str);
            auto e1 = x.documentElement();
            e.appendChild(e1);
            int himage = xstring(e1.getAttribute(L"image")).toInt();
            tv_folder.InsertChildItem(hItem, arg.GetArgString(L"name"), e1, himage);
         }
         return 1;
      }
      else if (comdid == L"xmDeleteObject")
      else if (comdid == L"show")
      {
         HTREEITEM hItem = tv_folder.GetSelectedItem();
         if (!hItem) return 1;
         //find project folder
         xstring prjguid = L"";
         HTREEITEM pitem = GetProjectItem(hItem);
         if (pitem)
            prjguid = ((KXMLDOMElement)tv_folder.GetItemData(pitem)).getAttribute(L"guid");
         HTREEITEM hP2Item = 0;
         HTREEITEM hDomainItem = 0;
         KXMLDOMElement e;
         if (!tv_folder.GetParentItem(hItem) ) return 1;
         hP2Item = hItem;
         while (true)
         {
            hDomainItem = tv_folder.GetParentItem(hP2Item);
            if (!tv_folder.GetParentItem(hDomainItem))break;
            hP2Item = hDomainItem;
         }
         e = tv_folder.GetItemData(hItem);
         xstring guid = e.getAttribute(L"guid");
         xaserverarg arg;
         arg.SetArg(L"project.guid", prjguid);
         arg.AddArg(L"guid", guid);
         KXMLDOMElement p = tv_folder.GetItemData(hP2Item);
         guid = p.getAttribute(L"guid");
         arg.AddArg(L"root.guid", guid);
         int MB_YESNO = 0x00000004;
         int IDYES = 6;
         if (MessageBox(GetHWND(), L"确认删除指定的项", L"提示", MB_YESNO) != IDYES) return 1;
         ProcessDevCmd(L"deletefolder", arg.GetString());
         tv_folder.DeleteItem(hItem);
         return 1;
         if (OnCmdDispatch(L"xmValid") == -1)
            return -1;
         onShow();
      }
      else if (comdid == L"xmUpdateProject")
      else if (comdid == L"xmQuery")
      {
         HTREEITEM hItem = tv_folder.GetSelectedItem();
         if (!hItem) return 1;
         //find project folder
         xstring prjguid = L"";
         HTREEITEM pitem = GetProjectItem(hItem);
         if (pitem && pitem != hItem)
            prjguid = ((KXMLDOMElement)tv_folder.GetItemData(pitem)).getAttribute(L"guid");
         HTREEITEM hP2Item = 0;
         HTREEITEM hDomainItem = 0;
         KXMLDOMElement e;
         if (!tv_folder.GetParentItem(hItem) ) return 1;
         hP2Item = hItem;
         while (true)
         {
            hDomainItem = tv_folder.GetParentItem(hP2Item);
            if (!tv_folder.GetParentItem(hDomainItem))break;
            hP2Item = hDomainItem;
         }
         e = tv_folder.GetItemData(hItem);
         xstring guid = e.getAttribute(L"guid");
         xaserverarg arg;
         arg.SetArg(L"project.guid", prjguid);
         arg.AddArg(L"guid", guid);
         KXMLDOMElement p = tv_folder.GetItemData(hP2Item);
         //trace(p.xml);
         guid = p.getAttribute(L"guid");
         arg.AddArg(L"root.guid", guid);
         xstring str;
         str = e.getAttribute(L"caption");
         arg.AddArg(L"name", str);
         str = e.getAttribute(L"desc");
         arg.AddArg(L"desc", str);
         str = e.getAttribute(L"uri");
         arg.AddArg(L"uri", str);
         str = e.getAttribute(L"guid");
         arg.AddArg(L"guid", str);
         str = e.getAttribute(L"src");
         arg.AddArg(L"src", str);
         str = e.getAttribute(L"type");
         arg.AddArg(L"type", str);
         OpenWindow(L"dev:xpage[XDevItemDlg.xpage]", arg);
         if (arg.GetArgString(L"__process") != L"true") return 1;
         ProcessDevCmd(L"updatefolder", arg.GetString());
         str = arg.GetArgString(L"name");
         e.setAttribute(L"caption", str);
         str = arg.GetArgString(L"desc");
         e.setAttribute(L"desc", str);
         str = arg.GetArgString(L"uri");
         e.setAttribute(L"uri", str);
         tv_folder.SetItemLabel(hItem, arg.GetArgString(L"name"));
         return 1;
         xstring guid = win32::GetGuid();
         xstring caption = L"Query_" + guid.mid(1,8);
         if (OnOpen(caption,L"query") == 0) return 0;
         xsedit xs = GetControl(L"sql_" + caption);
         xs.LoadContent(L"",L".sql");
      }
      else if (comdid == L"xmEditObject")
      else if (comdid.left(8) == L"xmClose_")
      {
         HTREEITEM hItem = tv_folder.GetSelectedItem();
         if (!hItem) return 1;
         xlayersheet layer = GetControl(L"mdilayer");
         int i = 0;
         int nIndex = layer.GetSheetCount();
         for (i = 0; i < nIndex; i++)
         {
            if (hItem == layer.GetParam(i))break;
         }
         if (i < nIndex)
         {
            layer.SelectSheet(i);
            return 1;
         }
         KXMLDOMElement e = tv_folder.GetItemData(hItem);
         xstring node = e.tagName();
         if (node == L"File" || node == L"file")
         {
            //xstring str =  ProcessDevCmd(L"getobject",arg.GetString());
            xstring typ = e.getAttribute(L"type");
            xml x ;
            xaserver::FetchXml(GetServerUrl(), L"dev:xpage[XDevEdit.xml]", L"", x);
            auto n = x.selectSingleNode((xstring)L"//editor[@filetype='" + L"xml" + L"']/@xpage");
            if (n)
            {
               xstring xpage = n.text();
               OpenWindow(L"dev:xpage[" + xpage + L"]", (LPARAM)hItem);
               //layer.
               if (nIndex < layer.GetSheetCount())
                  layer.SetParam(nIndex, hItem);
            }
         }
         list.DeleteSheet(list.GetSheetIndex());
      }
      else if (comdid.left(6) == L"xmRun_")
      {
         xstring table = comdid.mid(6,comdid.length());
         xsedit xs = GetControl(L"sql_" + table);
         xstring content;
         xs.GetContent(content);
         xstring sql = L"xquery@" + content + L" for xml path('data'),root('datas'),type";
         KXMLDOMElement e = OnXQuery(sql);
         if (e)
            setGrid(e,L"grid_" + table);
      }
      xutil::RestoreCursor(hCursor);
      return 0;
   }
   //树选择事件
   int OnTreeSelChanged(TEvent* evt, LPARAM param)
   {
      NMTREEVIEW& nmtv = *(NMTREEVIEW*)evt->notify.pnmh;
      HTREEITEM hItem = nmtv.itemNew.hItem;
      //root node
      KXMLDOMElement e = tv_folder.GetItemData(hItem);
      SetAgent(L"projects");
      return 1;
   }
   //命令处理事件
   int OnXCommand(TEvent* evt, int param)
   int OnXCommand(TEvent* evt,LPARAM param)
   {
      return OnCmdDispatch(evt->xcommand.pStrID);
   }
   int OnSelChanged(TEvent* evt, int param)
   int OnTreeAdd(HTREEITEM item, xstring data,KXMLDOMElement e)
   {
      xlayersheet layer = GetControl(L"mdilayer");
      LYSNMHDR& nmtv = *(LYSNMHDR*)evt->notify.pnmh;
      int sheet = nmtv.nSheet;
      int s = layer.GetSheetCount();
      //状态栏显示完成路径
      HTREEITEM hitem = tv_folder.GetSelectedItem();
      xstring path = L"" + tv_folder.GetItemLabel(hitem);
      while (tv_folder.GetParentItem(hitem))
      auto list = e.selectNodes(L"*");
      int i;
      int s = list.length();
      for (i = 0; i < s; i++)
      {
         hitem = tv_folder.GetParentItem(hitem);
         xstring p = L"" + tv_folder.GetItemLabel(hitem);
         path = p + L"\\" + path;
         KXMLDOMElement ele = list.item(i);
         xstring name = ele.getAttribute(L"name");
         xstring image = ele.getAttribute(L"image");
         xstring d = ele.getAttribute(L"data");
         image = L"" + image;
         if (d == L"")
            d = data + L"@" + name;
         HTREEITEM j = tv_db.InsertChildItem(item,(LPTSTR)name.c_str(), (LPARAM)d.c_str(true), image.toInt());
         if (image.toInt() > 9)
            tv_db.SetItemChild1(j,1);
         OnTreeAdd(j,d,ele);
      }
      xcontrol xc = GetControl(L"statusbar");
      xc.SetText(L"" + path);
      /*
            if(sheet<s)
            {
               param p=layer.GetParam(sheet);
               int hitem = p;
               onPrintPath(hitem);
            }
      */
      return 1;
   }
   int OnSelChangedEx(TEvent* evt, int param)
   int OnTreeExpand(HTREEITEM item)
   {
      xlayersheet layer = GetControl(L"mdilayer");
      LYSNMHDR& nmtv = *(LYSNMHDR*)evt->notify.pnmh;
      int sheet = nmtv.nSheet;
      int s = layer.GetSheetCount();
      int k = sheet_Count;
      if (k < s)
      xstring data = tv_db.GetItemData(item);
      xstring link = getLink(item);
      xml x ;
      xaserverarg arg;
      arg.AddArg(L"type",data);
      arg.AddArg(L"link",link);
      if (xaserver::ExecXQuery(GetServerUrl(),L"[MSSQL.list.xq]",arg.GetString(),x) != 1)
      {
         void* p = nullptr;
         layer.SetParam(s - 1, p);
         trace(x.xml());
         return 0;
      }
      sheet_Count = s;
      KXMLDOMElement e = x.documentElement();
      OnTreeAdd(item,data,e);
      return 1;
   }
   int OnTreeExpanding(TEvent* evt,LPARAM param)
   {
      NMTREEVIEW& nmtv = *(NMTREEVIEW*)evt->notify.pnmh;
      HTREEITEM item = nmtv.itemNew.hItem;
      if (tv_db.GetChildItem(item) > 0) return 0;
      OnTreeExpand(item);
      return 1;
   }
   int OnGroupAction(xstring guid,xstring name,xstring flag)
   {
      xaserverarg arg;
      arg.AddArg(L"type",flag);
      HTREEITEM item = tv_db.GetSelectedItem();
      xstring str = L"<group guid='" + guid + L"' name='" + name + L"'";
      if (flag.mid(5,7) == L".table.")
      {
         str += L"/>";
      }
      else
      {
         xstring link = getLink(item);
         str += L" link='" + link + L"'/>";
      }
      //trace(str);
      arg.AddArg(L"context",str);
      return xaserver::ExecXAction(GetServerUrl(),L"[MSSQL.action.xa]",arg.GetString());
   }
   int OnNewGroup(HTREEITEM item)
   {
      tv_db.ExpandItemEx(item);
      HTREEITEM gitem = tv_db.GetChildItem(item);
      while (gitem > 0)
      {
         xstring data = L"" + tv_db.GetItemData(gitem);
         if (data.left(6) != L"group@") break;
         gitem = tv_db.GetNextItem(gitem);
      }
      xstring guid = win32::GetGuid();
      if (OnGroupAction(guid,L"",L"group.update") != 1) return 0;
      HTREEITEM j = tv_db.InsertItem(item,gitem,L"",L"group@" + guid,25);
      tv_db.ItemEdit(j);
      return 1;
   }
   int OnDel(HTREEITEM item)
   {
      xstring data = tv_db.GetItemData(item);
      if (data.left(6) == L"group@")
      {
         xstring guid = data.mid(6,data.length());
         if (OnGroupAction(guid,L"",L"group.del") != 1) return 0;
         tv_db.DeleteItem(item);
      }
      else if (data.left(6) == L"table@")
      {
         HTREEITEM pitem = tv_db.GetParentItem(item);
         xstring pdata = tv_db.GetItemData(pitem);
         if (pdata.left(6) == L"group@")
         {
            xstring guid = pdata.mid(6,pdata.length());
            xstring table = data.mid(6,data.length());
            if (OnGroupAction(guid,table,L"group.table.del") != 1) return 0;
            tv_db.DeleteItem(item);
         }
      }
      return 1;
   }
   int OnRefresh(HTREEITEM item)
   {
      while (tv_db.GetChildItem(item) > 0)
         tv_db.DeleteItem(tv_db.GetChildItem(item));
      OnTreeExpand(item);
      return 1;
   }
   int OnQuery(xstring caption)
   {
      if (OnOpen(caption,L"query") == 0) return 0;
      KXMLDOMElement e = OnXQuery(L"column@" + caption);
      if (!e) return 0;
      auto list = e.selectNodes(L"columns/column");
      int i;
      int s = list.length();
      xstring str;
      str = L"SELECT TOP 500 \r\n";
      for (i = 0; i < s; i++)
      {
         KXMLDOMElement ele = list.item(i);
         xstring tmp = ele.getAttribute(L"name");
         if (i < s - 1) tmp = tmp + L",L";
         str += L"\t" + tmp + L"\r\n";
      }
      str += L"FROM " + caption;
      xsedit xs = GetControl(L"sql_" + caption);
      xs.LoadContent(str,L".sql");
      setGrid(e,L"grid_" + caption);
      return 1;
   }
   int OnEdit(xstring caption)
   {
      if (OnOpen(caption,L"edit") == 0) return 0;
      KXMLDOMElement e = OnXQuery(L"edit@" + caption);
      if (!e) return 0;
      setGrid(e,L"editgrid_" + caption);
      return 1;
   }
   int OnDesign(xstring caption)
   {
      if (OnOpen(caption,L"design") == 0) return 0;
      KXMLDOMElement e = OnXQuery(L"design@" + caption);
      if (!e) return 0;
      setGrid(e,L"designgrid_" + caption);
      return 1;
   }
   xstring getCaption(xstring str)
   {
      while (str.find(L"@", 0) > 0)
      {
         xstring tmp = str.mid(str.find(L"@", 0) + 1, str.length());
         str = tmp;
      }
      return str;
   }
   int OnTreeRClick(TEvent* evt,int param)
   {
      TVNNMHDR& nmtv = *(TVNNMHDR*)evt->notify.pnmh;
      HTREEITEM item = nmtv.FromItem;
      xstring data = tv_db.GetItemData(item);
      xstring popup;
      if (data == L"table")
      {
         xstring memu = L"<root>";
         memu += L"<Item>新建表</Item>";
         memu += L"<Item>新建分组</Item>";
         memu += L"<Item>-</Item>";
         memu += L"<Item>刷新</Item>";
         memu += L"</root>";
         xstring str = tv_db.PopupMenu(memu);
         popup = str;
      }
      else if (data.left(6) == L"table@" && data.find(L"@",7) < 0)
      {
         xstring memu = L"<root>";
         memu += L"<Item>新建表</Item>";
         memu += L"<Item>设计</Item>";
         memu += L"<Item>-</Item>";
         memu += L"<Item>打开前500行</Item>";
         memu += L"<Item>编辑前200行</Item>";
         memu += L"<Item>-</Item>";
         memu += L"<Item>重命名</Item>";
         memu += L"<Item>刷新</Item>";
         memu += L"<Item>删除</Item>";
         memu += L"</root>";
         xstring str = tv_db.PopupMenu(memu);
         popup = str;
      }
      else if (data.left(6) == L"group@")
      {
         xstring memu = L"<root>";
         memu += L"<Item>重命名</Item>";
         memu += L"<Item>刷新</Item>";
         memu += L"<Item>删除</Item>";
         memu += L"</root>";
         xstring str = tv_db.PopupMenu(memu);
         popup = str;
      }
      else if (data.left(5) == L"view@" || data.left(10) == L"procedure@" || data.left(9) == L"function@")
      {
         xstring memu = L"<root>";
         memu += L"<Item>重命名</Item>";
         memu += L"<Item>修改</Item>";
         memu += L"<Item>删除</Item>";
         memu += L"</root>";
         xstring str = tv_db.PopupMenu(memu);
         popup = str;
      }
      //trace(L"   "+data+L"-->"+getCaption(data));
      xstring caption = getCaption(data);//data.mid(6,data.length());
      if (popup == L"新建分组")
         OnNewGroup(item);
      else if (popup == L"删除")
         OnDel(item);
      else if (popup == L"刷新")
         OnRefresh(item);
      else if (popup == L"打开前500行")
         OnQuery(caption);
      else if (popup == L"编辑前200行")
         OnEdit(caption);
      else if (popup == L"设计")
         OnDesign(caption);
      else if (popup == L"新建表")
      {
         xstring guid = win32::GetGuid();
         xstring text = L"Table_" + guid.mid(1,8);
         OnDesign(text);
      }
      else if (popup == L"修改")
         OnOpen(caption,L"query");
      return 1;
   }
   int OnTreeBeginDrag(TEvent* evt,LPARAM param)
   {
      NMTREEVIEW& nmtv =*(NMTREEVIEW*) evt->notify.pnmh;
      HTREEITEM item = nmtv.itemNew.hItem;
      xstring data = tv_db.GetItemData(item);
      if (data.left(6) != L"table@" || data.find(L"@",7) > 0)
      {
         int WM_LBUTTONUP = 0x0202;
         SendMessage(tv_db.GetHWND(),WM_LBUTTONUP,0,0);
      }
      return 1;
   }
   int OnTreeEndDrag(TEvent* evt, LPARAM param)
   {
      TVNNMHDR& nmtv = *(TVNNMHDR*)evt->notify.pnmh;
      HTREEITEM fitem = nmtv.FromItem;
      HTREEITEM titem = nmtv.ToItem;
      xstring fdata = tv_db.GetItemData(fitem);
      xstring tdata = tv_db.GetItemData(titem);
      if (fdata.left(6) == L"table@" && tdata.left(6) == L"group@")
      {
         xstring table = fdata.mid(6,fdata.length());
         xstring guid = tdata.mid(6,tdata.length());
         if (OnGroupAction(guid,table,L"group.table.update") != 1) return 0;
         tv_db.DeleteItem(fitem);
      }
      return 1;
   }
   int OnTreeEndEdit(TEvent* evt, LPARAM param)
   {
      NMTVDISPINFO& nmtv = *(NMTVDISPINFO*)evt->notify.pnmh;
      HTREEITEM item = nmtv.item.hItem;
      xstring pszText = nmtv.item.pszText;
      if (pszText != L"")
      {
         xstring data = tv_db.GetItemData(item);
         if (data.left(6) == L"group@")
         {
            xstring guid = data.mid(6,data.length());
            if (OnGroupAction(guid,pszText,L"group.update") != 1) return 0;
         }
         tv_db.SetItemLabel(item,pszText);
      }
      return 1;
   }
   int OnAttachEvent()
   {
      //绑定工具条点击事件
      AttachEvent(L"WM_XCOMMAND", (FEvent)&XDeveloper::OnXCommand);
      AttachEvent(L"DevExplorer", L"NM_DBLCLK", (FEvent)&XDeveloper::OnTreeDblClick);
      AttachEvent(L"WM_XCOMMAND",(FEvent)XDevEditXMSSQL::OnXCommand);
      //获取焦点事件,用于重置工具条
      AttachEvent(L"WM_SETFOCUS", (FEvent)XDevEditXMSSQL::OnSetFocus);
      //获得树的展开事件
      //AttachEvent(L"DevExplorer", L"TVN_ITEMEXPANDING",(FEvent)&XDeveloper::OnTreeExpanding);
      AttachEvent(L"tv_db", L"TVN_ITEMEXPANDING", (FEvent)XDevEditXMSSQL::OnTreeExpanding);
      //获得树的选择事件
      AttachEvent(L"DevExplorer", L"TVN_SELCHANGED", (FEvent)&XDeveloper::OnTreeSelChanged);
      //改变页签
      //AttachEvent(L"mdilayer", L"LYSN_SELECTEDSHEET",(FEvent)&XDeveloper::OnSelChanged);
      AttachEvent(L"mdilayer", L"LYSN_SELECTEDSHEET", (FEvent)&XDeveloper::OnSelChangedEx);
      //AttachEvent(L"tv_db", L"TVN_SELCHANGED",(FEvent)XDevEditXMSSQL::OnTreeSelChanged);
      AttachEvent(L"tv_db", L"TVN_RCLICK", (FEvent)XDevEditXMSSQL::OnTreeRClick);
      AttachEvent(L"tv_db", L"TVN_BEGINDRAG", (FEvent)XDevEditXMSSQL::OnTreeBeginDrag);
      AttachEvent(L"tv_db", L"TVN_ENDDRAG", (FEvent)XDevEditXMSSQL::OnTreeEndDrag);
      AttachEvent(L"tv_db", L"TVN_ENDLABELEDIT", (FEvent)XDevEditXMSSQL::OnTreeEndEdit);
   }
   int LoadData()
   {
      if (!GetWinParam()) return 1;
      xsedit xs = GetControl(L"xcontent");
      xstring content = GetData();
      if (content != L"")
      {
         xs.LoadContent(content,L".xml");
      }
      return 1;
   }
   int OnInitial()
   {
      SetAgent();
      OnAttachEvent();
      return 1;
@@ -549,13 +594,13 @@
   int onload()
   {
      sheet_Count = -1;
      tv_db = GetControl(L"tv_db");
      list = GetControl(L"list");
      OnInitial();
      tv_folder = GetControl(L"DevExplorer");
      mle_output = GetControl(L"output");
      SetAgent(L"projects");
      LoadData();
      //OnCmdDispatch(L"xmQuery");
      return 1;
   }
};