alroyso 3 years ago
parent
commit
a0fb059929

+ 42 - 11
SProxy/CLashConfig.cpp

@@ -7,7 +7,7 @@
 
 CLashConfig::CLashConfig() : m_socks_port(9200), m_http_port(9300), m_c_port(9090), m_process(nullptr), m_Asyntask(1), m_AsyntaskProcessMonitor(1), m_is_qut(false), m_log(nullptr)
 {
-
+	SNotifyCenter::getSingleton().addEvent(EVENTID(EventClashPreOceeQut));
 	_hEvent = nullptr;
 
 }
@@ -224,8 +224,6 @@ BOOL CLashConfig::StartClash()
 	{
 		CApp::getSingletonPtr()->SetCLashRuning(true);
 		m_AsyntaskProcessMonitor.AddTask(&CLashConfig::ThreadFun_ProcessMonitor_Config, this, (LPARAM)CProcessManager::getSingletonPtr());
-
-		
 	}
 	
 	/*if (m_process)
@@ -450,17 +448,50 @@ void CLashConfig::ThreadFun_ProcessMonitor_Config(LPARAM lParam)
 	CProcessManager* p = (CProcessManager*)lParam;
 	if (p)
 	{
-		HANDLE hClashProcess = nullptr;
-		HANDLE hSubProcess = nullptr;
+		HANDLE hClashProcess = p->GetClashProcessInfo().hProcess;
+		HANDLE hSubProcess = p->GetSubProcessInfo().hProcess;
  
-		do 
+		WaitForSingleObject(hClashProcess, INFINITE);
+
+		CApp::getSingletonPtr()->SetCLashRuning(false);
+
+
+		if (p->IsRunning() != State::Running)
+		{
+			return;
+		}
+
+		DWORD exitCode = 0;
+		THROW_IF_WIN32_BOOL_FALSE(GetExitCodeProcess(hClashProcess, &exitCode));
+
+		LOG_HR_MSG(E_FAIL, "syscode.exe exited with code: %ul", exitCode);
+
+		FILETIME creationTime = {}, exitTime = {}, kernelTime = {}, userTime = {};
+		THROW_IF_WIN32_BOOL_FALSE(GetProcessTimes(hClashProcess, &creationTime, &exitTime, &kernelTime, &userTime));
+		auto creation = winrt::clock::from_FILETIME(creationTime);
+		auto exit = winrt::clock::from_FILETIME(exitTime);
+		if (exit - creation < 5s)
 		{
-			if (p->IsRunning() != State::Running)
-			{
-				break;
-			}
+			/*g_balloonClickAction = BalloonClickAction::ShowConsoleWindow;
+			ShowBalloon(_(L"Clash process was alive less than 5 seconds\nTap to view console log"), _(L"Error"), NIIF_ERROR);
+			co_await winrt::resume_on_signal(hSubProcess);*/
+			WaitForSingleObject(hSubProcess, INFINITE);
+		}
 
-		} while (hClashProcess = p->GetClashProcessInfo().hProcess);
+		if (p->IsRunning() != State::Running)
+		{
+			return;
+		}
+
+		p->Stop();
+
+		EventClashPreOceeQut* pEvt = new EventClashPreOceeQut(nullptr);
+		pEvt->status = 200;
+		pEvt->msg = L"";
+		SNotifyCenter::getSingleton().FireEventAsync(pEvt);
+		pEvt->Release();
+
+		
 	}
 	 
 }

+ 1 - 0
SProxy/CManageNetWork.cpp

@@ -27,6 +27,7 @@ void CManageNetWork::init()
 
 	SNotifyCenter::getSingleton().addEvent(EVENTID(EventLogin));
 	SNotifyCenter::getSingleton().addEvent(EVENTID(EventDoWNload));
+	SNotifyCenter::getSingleton().addEvent(EVENTID(EventNodeList));
 
 
 	if (!m_base_curl)

+ 24 - 11
SProxy/CNetWork.cpp

@@ -78,10 +78,10 @@ std::string CNetWork::GetUrl(std::string path, std::vector<cpr::Parameter> param
 
 	if (parame.empty())
 	{
-		r = cpr::Get(cpr::Url{ s.c_str() });
+		r = cpr::Get(cpr::Url{ s.c_str() }, hander, cpr::Timeout{ 30 * 100});
 	}
 	else {
-		r = cpr::Get(cpr::Url{ s.c_str() });
+		r = cpr::Get(cpr::Url{ s.c_str() }, hander, cpr::Timeout{ 30 * 100 });
 	}
 	if (r.status_code == 200 || r.status_code == 201)
 	{
@@ -89,29 +89,41 @@ std::string CNetWork::GetUrl(std::string path, std::vector<cpr::Parameter> param
 	}
 	else {
 		m_http_status = r.status_code;
-		if (m_http_status == 0)
+		if (r.error.message.empty())
 		{
-			//m_http_status = r.error.code;
+			m_error_msg = r.status_line;
+		}
+		else {
 			m_error_msg = r.error.message;
 		}
-
+		
 		return "";
 	}
 	return std::string("");
 }
 
-std::string CNetWork::PostUrl(std::string path, std::vector<cpr::Pair> parame)
+std::string CNetWork::PostUrl(std::string path, std::vector<cpr::Pair> parame, std::string token)
 {
 	auto s = fmt::format("{0}{1}", m_url, path.c_str());
 
+	cpr::Header hander;
+
+	if (!token.empty())
+	{
+		hander = cpr::Header{ {"accept", "application/json"} , {"Authorization", "bearer " + token} };
+	}
+	else {
+		hander = cpr::Header{ {"accept", "application/json"} };
+	}
+
 	cpr::Response r;
 
 	if (parame.empty())
 	{
-		r = cpr::Get(cpr::Url{ s.c_str() });
+		r = cpr::Get(cpr::Url{ s.c_str() },hander , cpr::Timeout{ 30 * 100 });
 	}
 	else {
-		r = cpr::Post(cpr::Url{ s.c_str() }, cpr::Payload{ parame.begin(),parame.end() }, cpr::Header{ {"accept", "application/json"} });
+		r = cpr::Post(cpr::Url{ s.c_str() }, cpr::Payload{ parame.begin(),parame.end() }, hander, cpr::Timeout{ 30 * 100 });
 	}
 
 	if (r.status_code == 200 || r.status_code == 201)
@@ -120,12 +132,13 @@ std::string CNetWork::PostUrl(std::string path, std::vector<cpr::Pair> parame)
 	}
 	else {
 		m_http_status = r.status_code;
-		if (m_http_status == 0)
+		if (r.error.message.empty())
 		{
-			//m_http_status = r.error.code;
+			m_error_msg = r.status_line;
+		}
+		else {
 			m_error_msg = r.error.message;
 		}
-
 		return "";
 	}
 

+ 1 - 1
SProxy/CNetWork.h

@@ -24,7 +24,7 @@ public:
 
 private:
 	std::string GetUrl(std::string path, std::vector<cpr::Parameter> parame, std::string token = "");
-	std::string PostUrl(std::string path, std::vector<cpr::Pair> parame);
+	std::string PostUrl(std::string path, std::vector<cpr::Pair> parame,std::string token = "");
 
 	 
 	void Init();

+ 127 - 0
SProxy/CNodeAdapter.hpp

@@ -0,0 +1,127 @@
+#pragma once
+#include "../__INCLUDE/LvSTileViewAdapterHandle.hpp"
+
+class CNodeAdapter : public LvAdapterHandle
+{
+public:
+	CNodeAdapter(STileView* pOwner) : LvAdapterHandle(pOwner)
+		, m_funBtnDel(&CNodeAdapter::OnEventDelBtn, this)
+		, m_callBackItemClick(nullptr)
+		, m_callBackBtnClick(nullptr)
+		, m_count(0)
+		, m_callshowview(nullptr)
+	{
+		m_seleset = true;
+	}
+	~CNodeAdapter()
+	{
+
+	}
+
+	virtual SStringT GetColumnName(int iCol) const
+	{
+		return L"col_nick";
+	}
+
+	void SetItemClickCallBack(std::function<void(int)> fun)
+	{
+		m_callBackItemClick = fun;
+	}
+	void SetBtnClickCallBack(std::function<void(int)> fun)
+	{
+		m_callBackBtnClick = fun;
+	}
+
+	void SetCount(int count) {
+		m_count = count;
+		notifyDataSetChanged();
+	}
+
+	void SetShowView(std::function<void(int nItem, SWindow* pItem)> fun) {
+		m_callshowview = fun;
+	}
+
+private:
+	int getCount()
+	{
+		return m_count;
+	}
+
+	void ShowView(int nItem, SWindow* pItem)
+	{
+		if (m_callshowview)
+		{
+			m_callshowview(nItem, pItem);
+		}
+		/*auto process_info = Clogin_info::getSingletonPtr()->m_server_gourp_tiles[nItem];
+		pItem->FindChildByName2<SStatic>(L"titile")->SetWindowTextW(S_CA2W(process_info.title.c_str(), CP_UTF8));*/
+	}
+
+
+
+	void ItemHover(int nItem, SItemPanel* pItem, const CPoint& pt)
+	{
+		SWindow* pBtn = pItem->FindChildByName(L"ml_btn_del");
+		if (NULL != pBtn)
+			pBtn->SetVisible(TRUE, TRUE);
+
+		SWindow* pCount = pItem->FindChildByName(L"ml_count");
+		if (NULL != pCount)
+			pCount->SetVisible(FALSE, TRUE);
+	}
+	void ItemLeave(int nItem, SItemPanel* pItem)
+	{
+		SWindow* pBtn = pItem->FindChildByName(L"ml_btn_del");
+		if (NULL != pBtn)
+			pBtn->SetVisible(FALSE, TRUE);
+
+		SWindow* pCount = pItem->FindChildByName(L"ml_count");
+		if (NULL != pCount && !pCount->GetWindowText().IsEmpty())
+		{
+			pCount->SetVisible(TRUE, TRUE);
+		}
+	}
+
+
+	void ItemClick(int nItem, SItemPanel* pItem, const CPoint& pt)
+	{
+		if (nullptr != m_callBackItemClick)
+			m_callBackItemClick(nItem);
+	}
+	bool IsItemClick(int nItem, const SStringT& szSndName)
+	{
+		if (0 == szSndName.CompareNoCase(L"ml_btn_del"))
+			return false;
+
+		return true;
+	}
+
+	bool OnEventDelBtn(EventArgs* e)
+	{
+		e->bubbleUp = false;
+		EventCmd* pEvt = sobj_cast<EventCmd>(e);
+		if (NULL == pEvt) return true;
+
+		SImageButton* pBtn = sobj_cast<SImageButton>(pEvt->sender);
+		if (NULL == pBtn) return true;
+
+		SItemPanel* pItem = sobj_cast<SItemPanel>(pBtn->GetParent());
+		if (NULL == pItem) return true;
+
+		if (nullptr != m_callBackBtnClick)
+			m_callBackBtnClick(static_cast<int>(pItem->GetItemIndex()));
+
+		return true;
+	}
+
+
+private:
+
+	std::function<void(int)>						m_callBackItemClick;		// item ���� �ص�
+	std::function<void(int)>						m_callBackBtnClick;			//  item  btn �ص�
+	std::function<void(int nItem, SWindow* pItem)>	m_callshowview;
+	int m_count;
+	INT m_nCurCheck;
+	bool m_seleset;
+	MemberFunctionSlot<CNodeAdapter, EventArgs>			m_funBtnDel;
+};

+ 1 - 1
SProxy/CProcessManager.cpp

@@ -4,7 +4,7 @@ CProcessManager* SSingleton<CProcessManager>::ms_Singleton = NULL;
 
 CProcessManager::CProcessManager()
 {
-
+	
 }
 
 CProcessManager::~CProcessManager()

+ 3 - 0
SProxy/CProcessManager.h

@@ -1,4 +1,7 @@
 #pragma once
+
+#include "event.h"
+
 #define OBJPREFIX LR"(Local\)"
 constexpr size_t guidSize = std::size(L"{00000000-0000-0000-0000-000000000000}"); // including the null terminator
 constexpr size_t prefixSize = std::size(OBJPREFIX) - 1;

+ 1 - 0
SProxy/CServerList.cpp

@@ -32,6 +32,7 @@ bool CServerList::Init(std::string data)
 				m_serverlist_mode.name = data[i]["name"].get<std::string>();
 				m_serverlist_mode.host = data[i]["host"].get<std::string>();
 				m_serverlist_mode.group = data[i]["group"].get<std::string>();
+				m_serverlist_mode.online_users = data[i]["online_users"].get<int>();
 
 				if (m_serverlist_mode.type == "shadowsocks")
 				{

BIN
SProxy/MainDlg.cpp


BIN
SProxy/MainDlg.h


BIN
SProxy/SProxy.cpp


+ 1 - 0
SProxy/SProxy.vcxproj

@@ -234,6 +234,7 @@
     <ClInclude Include="ClashModel.h" />
     <ClInclude Include="CManageNetWork.h" />
     <ClInclude Include="CNetWork.h" />
+    <ClInclude Include="CNodeAdapter.hpp" />
     <ClInclude Include="comm.h" />
     <ClInclude Include="CProcess.h" />
     <ClInclude Include="CProcessManager.h" />

+ 3 - 0
SProxy/SProxy.vcxproj.filters

@@ -216,6 +216,9 @@
     <ClInclude Include="CBaseMode.h">
       <Filter>Model</Filter>
     </ClInclude>
+    <ClInclude Include="CNodeAdapter.hpp">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="res\soui_res.rc2">

+ 2 - 1
SProxy/comm.h

@@ -17,4 +17,5 @@ constexpr auto DSPROXY_CONFIG_DIR_NAME = L"Config";
 constexpr auto DSPROXY_EXE_NAME = L"syscode.exe"; 
 
 
-constexpr auto CONNECT_NODE_MSG = L"正在获取节点..";
+constexpr auto CONNECT_NODE_MSG = L"正在获取节点..不能操作"; 
+constexpr auto SUEECS_NODE_MSG = L"获取节点成功..";

+ 19 - 0
SProxy/event.h

@@ -55,6 +55,25 @@ public:
 		EventID = EVT_NODELIST
 	};
 
+	int		 status;
+	SStringW msg;
+};
+
+
+#define EVT_CLASH_PREOCEE_QUT (SOUI::EVT_EXTERNAL_BEGIN + 1003)
+
+class EventClashPreOceeQut : public TplEventArgs<EventClashPreOceeQut>
+{
+	SOUI_CLASS_NAME(EventClashPreOceeQut, L"on_event_clash_qut")
+public:
+	EventClashPreOceeQut(SOUI::SWindow* pSender) : TplEventArgs<EventClashPreOceeQut>(pSender)
+	{
+
+	}
+	enum {
+		EventID = EVT_CLASH_PREOCEE_QUT
+	};
+
 	int		 status;
 	SStringW msg;
 };

BIN
SProxy/res/resource.h


BIN
SProxy/res/soui_res.rc2


BIN
SProxy/stdafx.h


BIN
SProxy/uires/image/ress.png


+ 1 - 0
SProxy/uires/uires.idx

@@ -31,6 +31,7 @@
 	<file name="default" path="image\default.png"/>
 	<file name="btn-selection" path="image\btn-selection.png"/>
 	<file name="btn-back" path="image\btn-back.png"/>
+	<file name="imgress" path="image\ress.png"/>
   </IMG>
 	<ICON>
 		<file name="ICON_LOGO" path="image\soui.ico" />

+ 1 - 0
SProxy/uires/values/skin.xml

@@ -15,5 +15,6 @@
 	<imglist name="skin_default" src="img:default" />
 	<imglist name="skin_btnselection" src="img:btn-selection" states="4"/>
 	<imglist name="skin_btnback" src="img:btn-back"  states="4"/>
+	<imglist name="skin_imgress" src="img:imgress"  states="4"/>
 	<vscrollbar name="skin.common.vscroll" src="IMG:ID_DEF_VSCROLL" states="3" margin="3" hasgripper="0"/> 
 </skin>

+ 1 - 1
SProxy/uires/xml/dlg_main.xml

@@ -1,4 +1,4 @@
-<SOUI name="loginwindow" title="@string/title" bigIcon="ICON_LOGO:32" smallIcon="ICON_LOGO:16"  width="414" height="736" margin="5,5,5,5"  resizable="1" wndType="appMain"
+<SOUI name="loginwindow" title="@string/title" bigIcon="ICON_LOGO:32" smallIcon="ICON_LOGO:16"  width="414" height="736" margin="5,5,5,5"  resizable="0" wndType="appMain"
 appWnd="1"
 >
   <root skin="bg-home_png" cache="1">

+ 30 - 33
SProxy/uires/xml/page_node.xml

@@ -2,15 +2,22 @@
   <caption pos="0,0,-0,99" show="1" font="adding:0">
   
       <imgbtn name="list_back" skin="skin_btnback" pos="15,30" tip="Back to Home" animate="1"/>
-      
+      <!-- skin_imgress -->
+
+      <text pos="[25,38" colorText="#ffffff88" font="adding:5,bold:1" >选择节点切换线路</text>
 
-      <text pos="[100,38" colorText="#ffffff88" font="adding:5,bold:1" >选择节点</text>
- 
+      <imgbtn name="onRefresh" skin="skin_imgress" pos="-45,30" tip="刷新线路" animate="1"/>
+      <!-- <link pos="-120,30" name="onRefresh" colorText="#ffffff88" font="adding:5,bold:0"  extend="0,0,0,0">刷新线路</link>  -->
+      
     </caption>
     <window pos="5,[2,-5,-5">
          <window size="-2,-2" layout="vbox" gravity="center"  extend="0,0,0,0">
 
-                 <!-- <window name="nodeclass" size="-2,51" layout="hbox"  skin="skin_group"  gravity="center" extend="0,0,0,0"> 
+               <window name="nodeclass" size="-2,25" layout="hbox"  skin=""  gravity="center" extend="0,0,0,0"> 
+                     <text colorText="#ffffff88" font="adding:5,bold:1" >更新状态</text>
+               </window>
+
+                 <!-- <window name="nodeclass" size="-2,51" layout="hbox"  skin=""  gravity="center" extend="0,0,0,0"> 
                           <radio2 size="0,-1" name="" colorTextPush="#D8D8D8" colorText="#D8D8D844" font="adding:12,bold:1" checked="1" skin="skin_tyteselection" align="center" weight="1" extend="0,0,0,0" >US</radio2>
                          <radio2 size="0,-1" name="" colorTextPush="#D8D8D8" colorText="#D8D8D844" font="adding:12,bold:1" checked="0" skin="skin_tyteselection" align="center"  weight="1" extend="5,0,0,0"  >ES</radio2>
                          <radio2 size="0,-1" name="" colorTextPush="#D8D8D8" colorText="#D8D8D844" font="adding:12,bold:1" checked="0" skin="skin_tyteselection"  align="center" weight="1" extend="5,0,0,0"  >AC</radio2>
@@ -19,40 +26,30 @@
                 </window> -->
                  
                 <!-- <tabtypecontrol name="nodeclass" size="400,45" gravity="center" extend="5,0,0,5"/> -->
-            
-                <window size="-2,0" weight="1.5" layout="hbox"  gravity="center" extend="0,0,0,0">
-
-                  <listview size="-2,-2" colorBkgnd="" extend="5,5,5,15" name="nodelistview" dividerSize="15" wantTab="1" sbSkin="skin.common.vscroll" hotTrack="1" > 
-									<template itemHeight="46" color="#D8D8D8"  colorHover="#D8D8D844" colorSelected="#D8D8D844" trackMouseEvent="1">
-										<window size="-2,-2" layout="hbox" colorBkgnd="">
-											<window size="0,-2" weight="2.5" layout="hbox" gravity="center" extend="10,0,0,0">
-
-                        <img skin="skin_default" size="43,23" extend="5,0,0,0"/>
 
-												<text name="servername" size="100,23" extend="10,0,0,0" colorText="#D8D8D8" dotted="1" >US 01</text>
-											</window>
-                      <window size="0,-2" weight="2" layout="hbox" gravity="center" extend="10,0,0,0">
-												<text name="serverms" pos="5,5" colorText="#D8D8D8" > 0 ms</text>
-											</window>
-
-											<!-- <window size="0,-2" weight="2" layout="hbox" gravity="center" extend="10,0,0,0">
-												<text name="serverms" pos="5,5" colorText="#D8D8D8" > 0 ms</text>
-											</window>
-
-                      <window size="0,-2" weight="2" layout="hbox" gravity="center" extend="10,0,0,0">
-												<text name="servercount" pos="5,5" colorText="#D8D8D8" > 0</text>
-											</window> -->
-
-
-										</window>
-									</template>
-								</listview>
+               
+            
+                <window size="-2,0" weight="1.5" layout="hbox"  gravity="center" extend="0,10,0,0">
+                    <tileview name="nodeList" size="-2,-2" colorBkgnd="" wantTab="1" marginSize="0" sbSkin="skin.common.vscroll" >
+                      <template itemHeight="66" itemWidth="130" color="#D8D8D8" colorHover="#D8D8D844" colorSelected="#D8D8D844" trackMouseEvent="1">
+                        <window size="-2,-2" layout="vbox" colorBkgnd="" gravity="center" >
+                              <window size="-2,-2" layout="vbox" colorBkgnd="#ffffff" gravity="center" extend="10,10,10,10" >
+                            <text name="servername" pos="5,5" extend="0,10,0,0" colorText="#000000" > 0 ms</text>
+                            
+                            <text name="serverms" pos="5,5" extend="0,5,0,0" colorText="#000000" > 0 ms</text>
+        
+                        </window>
+                        </window>
+                      </template>
+                  </tileview>
+
+         
 
                 </window>
 
-                <window size="-2,0" weight="0.2" layout="vbox"  gravity="center" extend="0,0,0,0">
+                <!-- <window size="-2,0" weight="0.2" layout="vbox"  gravity="center" extend="0,0,0,0">
                     <imgbtn name="start_Acc" skin="skin_btnborder"  colorText="#A79BB8" font="adding:12,bold:1"  extend="0,0,0,0">开始加速</imgbtn>
-                </window>
+                </window> -->
          </window>
        
     </window>

+ 243 - 0
__INCLUDE/LvSTileViewAdapterHandle.hpp

@@ -0,0 +1,243 @@
+/*
+SListView 的数据适配器
+扩展了 SAdapterBase  
+自己处理 ItemClick 等 5个 事件 且 设置了 bubbleup 不让 其他调用
+这样就可以 点击 item里的按钮 而不会导致整个item 选中 
+*/
+
+#pragma once 
+#include <helper/SAdapterBase.h>
+
+
+// SListView 数据适配器 封装
+class LvAdapterHandle : public SAdapterBase
+{
+public:
+	LvAdapterHandle(STileView*	pOwner)
+		: m_pOwner(pOwner)
+		, m_evtSlot_ItemClick(&LvAdapterHandle::OnEventItemClick, this)
+		, m_evtSlot_ItemDbClick(&LvAdapterHandle::OnEventItemDbClick, this)
+		, m_evtSlot_ItemRClick(&LvAdapterHandle::OnEventItemRClick, this)
+		, m_evtSlot_ItemHover(&LvAdapterHandle::OnEventItemHover, this)
+		, m_evtSlot_ItemLeave(&LvAdapterHandle::OnEventItemLeave, this)
+	{
+		 
+		if(NULL != m_pOwner)
+		{
+			m_pOwner->GetEventSet()->subscribeEvent(&LvAdapterHandle::OnEventLvSelChangeing, this);
+		}
+	}
+
+    virtual ~LvAdapterHandle()
+	{
+	
+	}
+	
+	void SelectItem(int nItem, bool bNotify=false)
+	{
+		m_pOwner->SetSel(nItem, bNotify ? TRUE : FALSE);
+	}
+	int GetSelectItem()
+	{
+		return m_pOwner->GetSel();
+	}
+protected:
+	// 这个用来 显示 数据  在 getView 里 调用 这里去掉了  模版加载  
+	virtual void ShowView(int nItem, SWindow* pItem)
+	{
+
+	}
+	// item click 回调 可以
+	virtual void ItemClick(int nItem, SItemPanel* pItem, const CPoint& pt)
+	{
+
+	}
+	// 
+	virtual void ItemDbClick(int nItem, SItemPanel* pItem, const CPoint& pt)
+	{
+
+	}
+	virtual void ItemRClick(int nItem, SItemPanel* pItem, const CPoint& pt)
+	{
+
+	}
+	virtual void ItemHover(int nItem, SItemPanel* pItem, const CPoint& pt)
+	{
+
+	}
+	virtual void ItemLeave(int nItem, SItemPanel* pItem)
+	{
+
+	}
+	// 判断 是否 点击item 用来 item 里 有按钮等  控件 判断
+	virtual bool IsItemClick(int nItem, const SStringT& szSndName)
+	{
+		return true;
+	}
+protected:    
+	virtual void InitByTemplate(pugi::xml_node xmlTemplate)
+	{
+		//auto ite = xmlTemplate.attribute(L"colorSelected");
+		//m_szSelectColor = ite.as_string();
+		//ite = L"#FFFFFF00";			// 设置成 透明 的  
+	}
+	      
+	//virtual SIZE getViewDesiredSize(int position, SOUI::SWindow *pItem, LPCRECT prcContainer)
+	//{
+
+	//}
+	/*virtual int getItemViewType(int position)
+	{
+
+	}*/
+	//virtual SStringT GetColumnName(int iCol) const
+	//{
+	//	return L"col_nick";
+	//}
+	virtual void getView(int nPosition, SWindow* pItem, pugi::xml_node xmlTemplate)
+	{		
+		if(0 == pItem->GetChildrenCount())
+		{
+			pItem->InitFromXml(xmlTemplate);
+
+			auto eventItem = pItem->GetEventSet();
+			eventItem->subscribeEvent(EventItemPanelClick::EventID, m_evtSlot_ItemClick);
+			eventItem->subscribeEvent(EventItemPanelDbclick::EventID, m_evtSlot_ItemDbClick);
+			eventItem->subscribeEvent(EventItemPanelRclick::EventID, m_evtSlot_ItemRClick);
+			eventItem->subscribeEvent(EventItemPanelHover::EventID, m_evtSlot_ItemHover);
+			eventItem->subscribeEvent(EventItemPanelLeave::EventID, m_evtSlot_ItemLeave);
+		}
+
+		
+		
+		
+
+		ShowView(nPosition, pItem);
+	}
+	bool OnEventLvSelChangeing(EventLVSelChanging* pEvt)
+	{
+		if(NULL == pEvt)
+			return true;
+		
+		pEvt->bubbleUp = false;
+
+		if(-1 == pEvt->iNewSel)				// 不能设置 -1 
+			pEvt->bCancel = TRUE;
+
+		return true;
+	}
+	bool OnEventItemClick(EventArgs* e)
+	{
+		EventItemPanelClick* pEvt = sobj_cast<EventItemPanelClick>(e);
+		if(NULL == pEvt) return true;
+
+		SItemPanel* pItem = sobj_cast<SItemPanel>(pEvt->sender);
+		if(NULL == pItem) return true;
+			
+		int nItem = static_cast<int>(pItem->GetItemIndex());
+
+		CPoint pt;
+		pt.x = GET_X_LPARAM(pEvt->lParam);
+		pt.y = GET_Y_LPARAM(pEvt->lParam);
+		
+		// 判断 点击 的 是否是  删除按钮
+		SWND hHover = pItem->SwndFromPoint(pt, FALSE);
+		SWindow* pChild = SWindowMgr::GetWindow(hHover);
+	
+		if(NULL != pChild)			// 如果 有 消息 就 不选中
+		{
+			if(!IsItemClick(nItem, pChild->GetName())	)
+			{
+				e->bubbleUp = false; // 设置了   点击事件 只在 这里处理 SListView 不处理 
+				return true;
+			}
+		}
+		
+		ItemClick(nItem, pItem, pt);
+				
+		return true;
+
+	}
+	
+	bool OnEventItemDbClick(EventArgs* e)
+	{
+		EventItemPanelDbclick* pEvt = sobj_cast<EventItemPanelDbclick>(e);
+		if(NULL == pEvt) return true;
+
+		SItemPanel* pItem = sobj_cast<SItemPanel>(pEvt->sender);
+		if(NULL == pItem) return true;
+
+		int nItem = static_cast<int>(pItem->GetItemIndex());
+
+		CPoint pt;
+		pt.x = GET_X_LPARAM(pEvt->lParam);
+		pt.y = GET_Y_LPARAM(pEvt->lParam);
+
+		ItemDbClick(nItem, pItem, pt);
+
+		return true;
+	}
+	bool OnEventItemRClick(EventArgs* e)
+	{
+		EventItemPanelRclick* pEvt = sobj_cast<EventItemPanelRclick>(e);
+		if(NULL == pEvt) return true;
+
+		SItemPanel* pItem = sobj_cast<SItemPanel>(pEvt->sender);
+		if(NULL == pItem) return true;
+
+		int nItem = static_cast<int>(pItem->GetItemIndex());
+		
+		CPoint pt;
+		pt.x = GET_X_LPARAM(pEvt->lParam);
+		pt.y = GET_Y_LPARAM(pEvt->lParam);
+
+		ItemRClick(nItem, pItem, pt);
+
+		return true;
+	}
+
+	bool OnEventItemHover(EventArgs* e)
+	{
+		EventItemPanelHover* pEvt = sobj_cast<EventItemPanelHover>(e);
+		if(NULL == pEvt)
+			return true;
+		
+		SItemPanel* pItem = sobj_cast<SItemPanel>(pEvt->sender);
+		if(NULL == pItem) return true;
+
+		int nItem = static_cast<int>(pItem->GetItemIndex());
+
+		CPoint pt;
+		pt.x = GET_X_LPARAM(pEvt->lParam);
+		pt.y = GET_Y_LPARAM(pEvt->lParam);
+
+		ItemHover(nItem, pItem, pt);
+
+		return true;
+	}
+
+	bool OnEventItemLeave(EventArgs* e)
+	{
+		EventItemPanelLeave* pEvt = sobj_cast<EventItemPanelLeave>(e);
+		if(NULL == pEvt)
+			return true;
+		
+		SItemPanel* pItem = sobj_cast<SItemPanel>(pEvt->sender);
+		if(NULL == pItem) return true;
+
+		int nItem = static_cast<int>(pItem->GetItemIndex());
+		
+		ItemLeave(nItem, pItem);
+
+		return true;
+	}
+
+protected:
+	STileView*						m_pOwner;
+private:	
+	MemberFunctionSlot<LvAdapterHandle, EventArgs>			m_evtSlot_ItemClick;
+	MemberFunctionSlot<LvAdapterHandle, EventArgs>			m_evtSlot_ItemDbClick;
+	MemberFunctionSlot<LvAdapterHandle, EventArgs>			m_evtSlot_ItemRClick;
+	MemberFunctionSlot<LvAdapterHandle, EventArgs>			m_evtSlot_ItemHover;
+	MemberFunctionSlot<LvAdapterHandle, EventArgs>			m_evtSlot_ItemLeave;
+};