添加virtualTileBox项目

This commit is contained in:
evilbeast 2019-07-06 12:45:48 +08:00
parent f8cd48cbfe
commit 8adeea0606
23 changed files with 1580 additions and 4 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 767 B

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<Window>
<ListContainerElement class="listitem">
<HBox mouse="false" padding="10,5,10,5">
<Control name="control_img" width="auto" height="auto" margin="0,0,10,0" mouse="false"/>
<VBox margin="0,3,0,5" mouse="false">
<HBox height="auto" mouse="false">
<Label name="label_title" width="stretch" mouse="false"/>
<Button class="btn_recycle" name="btn_del" width="auto" height="auto"/>
</HBox>
<Control height="stretch" mouse="false"/>
<Progress class="progress_blue" name="progress" value="30" mouse="false"/>
</VBox>
</HBox>
</ListContainerElement>
</Window>

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<Window size="1200,800" caption="0,0,0,35">
<VBox bkcolor="bk_wnd_darkcolor">
<HBox width="stretch" height="35" bkcolor="bk_wnd_lightcolor">
<Label text="TileBox数据懒加载实现" font="system_14" valign="center" margin="8"/>
<Control />
<Button class="btn_wnd_min" name="minbtn" margin="4,6,0,0"/>
<Box width="21" margin="4,6,0,0">
<Button class="btn_wnd_max" name="maxbtn"/>
<Button class="btn_wnd_restore" name="restorebtn" visible="false"/>
</Box>
<Button class="btn_wnd_close" name="closebtn" margin="4,6,8,0"/>
</HBox>
<HBox childmargin="5" bkcolor="white" padding="5,5,5,10">
<VBox width="300" bordersize="1" bordercolor="splitline_level2" padding="5,10,5,10" childmargin="10">
<HBox height="30" childmargin="10">
<Label font="system_bold_14" text="列设置:" width="auto" height="auto" valign="center" />
<Option class="circle_option_2" name="option_column_auto" group="option_group" text="自动计算" margin="0,5,0,10" selected="true"/>
<Option class="circle_option_2" name="option_column_fix" group="option_group" text="固定列数" margin="0,5,0,10">
<Event type="select" receiver="box_column_op" applyattribute="visible=&quot;true&quot;" />
<Event type="unselect" receiver="box_column_op" applyattribute="visible=&quot;false&quot;" />
</Option>
</HBox>
<HBox name="box_column_op" height="30" childmargin="10" visible="false">
<Control width="45" />
<Box bordersize="1" bordercolor="splitline_level1" width="80" height="26">
<RichEdit name="edit_column" margin="10,0,10,0" font="system_14" width="stretch" height="auto" valign="center" normaltextcolor="black" multiline="false" promptmode="true" prompttext="列数" align="vcenter,hcenter" text="3" promptcolor="splitline_level1" autohscroll="true" />
</Box>
<CheckBox class="checkbox_font12" name="checkbox_item_center" text="列表居中" margin="0,5,0,10" selected="true" />
</HBox>
<Control height="1" bkcolor="splitline_level2" />
<HBox height="30" childmargin="10">
<Label font="system_bold_14" text="子项间隙:" width="auto" height="auto" valign="center" />
<Box bordersize="1" bordercolor="splitline_level1" width="80" height="26">
<RichEdit name="edit_child_margin" margin="10,0,10,0" font="system_14" width="stretch" height="auto" valign="center" normaltextcolor="black" multiline="false" promptmode="true" prompttext="子项间隙" align="vcenter,hcenter" text="" promptcolor="splitline_level1" autohscroll="true" />
</Box>
</HBox>
<HBox height="30" childmargin="10">
<Label font="system_bold_14" text="总数据:" width="auto" height="auto" valign="center" />
<Box bordersize="1" bordercolor="splitline_level1" width="180" >
<RichEdit name="edit_total" margin="10,0,10,0" font="system_14" width="stretch" height="auto" valign="center" normaltextcolor="black" multiline="false" promptmode="true" prompttext="总数据" promptcolor="splitline_level1" autohscroll="true" />
</Box>
</HBox>
<Box height="30" childmargin="10" width="stretch">
<Button class="btn_global_blue_80x30" halign="center" valign="center" name="btn_set_total" text="更改/设置" />
</Box>
<Control height="1" bkcolor="splitline_level2" />
<HBox height="30" childmargin="10">
<Label font="system_bold_14" text="改变数据:" width="auto" height="auto" valign="center" />
<Box bordersize="1" bordercolor="splitline_level1" height="26">
<RichEdit name="edit_update" margin="10,0,10,0" font="system_14" width="stretch" height="auto" valign="center" normaltextcolor="black" multiline="false" promptmode="true" prompttext="序号(下标1)" promptcolor="splitline_level1" autohscroll="true" align="vcenter,hcenter" />
</Box>
<Box bordersize="1" bordercolor="splitline_level1" height="26">
<RichEdit name="edit_task_name" margin="10,0,10,0" font="system_14" width="stretch" height="auto" valign="center" normaltextcolor="black" multiline="false" promptmode="true" prompttext="新的任务名称" promptcolor="splitline_level1" autohscroll="true" />
</Box>
</HBox>
<Box height="30" childmargin="10" width="stretch">
<Button class="btn_global_blue_80x30" halign="center" valign="center" name="btn_update" text="更新数据" />
</Box>
<Control height="1" bkcolor="splitline_level2" />
<HBox height="30" childmargin="10">
<Label font="system_bold_14" text="删除数据:" width="auto" height="auto" valign="center" />
<Box bordersize="1" bordercolor="splitline_level1" >
<RichEdit name="edit_delete" margin="10,0,10,0" font="system_14" width="stretch" height="auto" valign="center" normaltextcolor="black" multiline="false" promptmode="true" prompttext="序号(下标1)" promptcolor="splitline_level1" autohscroll="true" align="vcenter,hcenter" />
</Box>
<Button class="btn_global_red_80x30" halign="center" valign="center" name="btn_delete" text="删除数据" />
</HBox>
</VBox>
<!--column="3" width="auto" halign="center" childmargin="10" -->
<Box>
<VirtualTileBox class="list" name="list" vscrollunit="70" itemsize="220,60" bordersize="1" bordercolor="splitline_level2" padding="1,1,1,1">
</VirtualTileBox>
</Box>
</HBox>
</VBox>
</Window>

View File

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013 # Visual Studio 2013
VisualStudioVersion = 12.0.40629.0 VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tool_kits", "tool_kits", "{66F85B8F-11B7-4964-B51E-99DF85D8FE00}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tool_kits", "tool_kits", "{66F85B8F-11B7-4964-B51E-99DF85D8FE00}"
EndProject EndProject
@ -31,6 +31,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcef_dll_wrapper", "..\th
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "controls", "controls\controls.vcxproj", "{8BD95440-9000-4745-8011-27DD553EF06F}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "controls", "controls\controls.vcxproj", "{8BD95440-9000-4745-8011-27DD553EF06F}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VirtualBox", "VirtualBox\VirtualBox.vcxproj", "{E35589C6-9509-4116-996F-1D045C2DACAE}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
@ -127,6 +129,12 @@ Global
{8BD95440-9000-4745-8011-27DD553EF06F}.Release|Win32.Build.0 = Release|Win32 {8BD95440-9000-4745-8011-27DD553EF06F}.Release|Win32.Build.0 = Release|Win32
{8BD95440-9000-4745-8011-27DD553EF06F}.Release|x64.ActiveCfg = Release|x64 {8BD95440-9000-4745-8011-27DD553EF06F}.Release|x64.ActiveCfg = Release|x64
{8BD95440-9000-4745-8011-27DD553EF06F}.Release|x64.Build.0 = Release|x64 {8BD95440-9000-4745-8011-27DD553EF06F}.Release|x64.Build.0 = Release|x64
{E35589C6-9509-4116-996F-1D045C2DACAE}.Debug|Win32.ActiveCfg = Debug|Win32
{E35589C6-9509-4116-996F-1D045C2DACAE}.Debug|Win32.Build.0 = Debug|Win32
{E35589C6-9509-4116-996F-1D045C2DACAE}.Debug|x64.ActiveCfg = Debug|Win32
{E35589C6-9509-4116-996F-1D045C2DACAE}.Release|Win32.ActiveCfg = Release|Win32
{E35589C6-9509-4116-996F-1D045C2DACAE}.Release|Win32.Build.0 = Release|Win32
{E35589C6-9509-4116-996F-1D045C2DACAE}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -134,15 +142,16 @@ Global
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{E106ACD7-4E53-4AEE-942B-D0DD426DB34E} = {66F85B8F-11B7-4964-B51E-99DF85D8FE00} {E106ACD7-4E53-4AEE-942B-D0DD426DB34E} = {66F85B8F-11B7-4964-B51E-99DF85D8FE00}
{8D9A6595-717A-41C8-B468-0011A72BE3D1} = {66F85B8F-11B7-4964-B51E-99DF85D8FE00} {8D9A6595-717A-41C8-B468-0011A72BE3D1} = {66F85B8F-11B7-4964-B51E-99DF85D8FE00}
{9951345F-620B-4BED-BB51-4F928CAFD454} = {66F85B8F-11B7-4964-B51E-99DF85D8FE00}
{0149BA6E-3C0A-426D-AA0A-0B9EC7742F19} = {66F85B8F-11B7-4964-B51E-99DF85D8FE00}
{F1A9371F-9A34-45A0-98EB-83FF371F067F} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA} {F1A9371F-9A34-45A0-98EB-83FF371F067F} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA}
{2BFFA1EE-039D-479E-9BCC-2D12F8AEDD16} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA} {2BFFA1EE-039D-479E-9BCC-2D12F8AEDD16} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA}
{B8588C07-9CE2-456C-83B1-86E4B65D4108} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA} {B8588C07-9CE2-456C-83B1-86E4B65D4108} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA}
{878F5BF0-652A-4FDB-992B-BB7F26D62F0D} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA} {878F5BF0-652A-4FDB-992B-BB7F26D62F0D} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA}
{FDB5539F-1060-4975-B603-B66454C8C897} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA} {FDB5539F-1060-4975-B603-B66454C8C897} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA}
{9951345F-620B-4BED-BB51-4F928CAFD454} = {66F85B8F-11B7-4964-B51E-99DF85D8FE00}
{0149BA6E-3C0A-426D-AA0A-0B9EC7742F19} = {66F85B8F-11B7-4964-B51E-99DF85D8FE00}
{A9D6DC71-C0DC-4549-AEA0-3B15B44E86A9} = {1DA0A8E2-5832-42FC-83F7-2CDCAD379C90}
{8BD95440-9000-4745-8011-27DD553EF06F} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA} {8BD95440-9000-4745-8011-27DD553EF06F} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA}
{E35589C6-9509-4116-996F-1D045C2DACAE} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA}
{A9D6DC71-C0DC-4549-AEA0-3B15B44E86A9} = {1DA0A8E2-5832-42FC-83F7-2CDCAD379C90}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {68CA0970-4242-4E4F-94D2-C19760FCA05D} SolutionGuid = {68CA0970-4242-4E4F-94D2-C19760FCA05D}

View File

@ -0,0 +1,31 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by VirtualBox.rc
//
#define IDS_APP_TITLE 103
#define IDR_MAINFRAME 128
#define IDD_VIRTUALBOX_DIALOG 102
#define IDD_ABOUTBOX 103
#define IDM_ABOUT 104
#define IDM_EXIT 105
#define IDI_VIRTUALBOX 107
#define IDI_SMALL 108
#define IDC_VIRTUALBOX 109
#define IDC_MYICON 2
#ifndef IDC_STATIC
#define IDC_STATIC -1
#endif
// жÔÏóµÄÏÂÒ»×éĬÈÏÖµ
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 130
#define _APS_NEXT_RESOURCE_VALUE 129
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif

View File

@ -0,0 +1,545 @@
#include "stdafx.h"
#include "VirtualTileBox.h"
VirtualTileInterface::VirtualTileInterface()
:m_CountChangedNotify()
, m_DataChangedNotify()
{
}
void VirtualTileInterface::RegNotifys(const DataChangedNotify& dcNotify, const CountChangedNotify& ccNotify)
{
m_DataChangedNotify = dcNotify;
m_CountChangedNotify = ccNotify;
}
void VirtualTileInterface::EmitDataChanged(int nStartIndex, int nEndIndex)
{
if (m_DataChangedNotify) m_DataChangedNotify(nStartIndex, nEndIndex);
}
void VirtualTileInterface::EmitCountChanged()
{
if (m_CountChangedNotify) m_CountChangedNotify();
}
VirtualTileLayout::VirtualTileLayout()
:m_bAutoCalcColumn(true)
{
m_nColumns = -1;
}
ui::CSize VirtualTileLayout::ArrangeChild(const std::vector<ui::Control*>& items, ui::UiRect rc)
{
ui::CSize sz(rc.GetWidth(), rc.GetHeight());
VirtualTileBox *pList = dynamic_cast<VirtualTileBox*>(m_pOwner);
ASSERT(pList);
int nTotalHeight = GetElementsHeight(-1);
sz.cy = max(nTotalHeight, sz.cy);
LazyArrangeChild();
return sz;
}
ui::CSize VirtualTileLayout::AjustSizeByChild(const std::vector<ui::Control*>& items, ui::CSize szAvailable)
{
VirtualTileBox *pList = dynamic_cast<VirtualTileBox*>(m_pOwner);
ASSERT(pList);
ui::CSize size = m_pOwner->Control::EstimateSize(szAvailable);
if (size.cx == DUI_LENGTH_AUTO || size.cx == 0)
{
size.cx = m_szItem.cx * m_nColumns + m_iChildMargin * (m_nColumns - 1);
}
return size;
}
bool VirtualTileLayout::SetAttribute(const std::wstring& strName, const std::wstring& strValue)
{
if (strName == L"column")
{
int iValue = _ttoi(strValue.c_str());
if (iValue > 0)
{
SetColumns(iValue);
m_bAutoCalcColumn = false;
}
else {
m_bAutoCalcColumn = true;
}
return true;
}
else {
return __super::SetAttribute(strName, strValue);
}
}
int VirtualTileLayout::GetElementsHeight(int nCount)
{
if (nCount < m_nColumns && nCount != -1) return m_szItem.cy + m_iChildMargin;
VirtualTileBox *pList = dynamic_cast<VirtualTileBox*>(m_pOwner);
ASSERT(pList);
if (nCount < 0)
nCount = pList->GetElementCount();
int rows = nCount / m_nColumns;
if (nCount % m_nColumns != 0) {
rows += 1;
}
if (nCount > 0) {
int childMarginTotal;
if (nCount % m_nColumns == 0) {
childMarginTotal = (nCount / m_nColumns - 1) * m_iChildMargin;
}
else {
childMarginTotal = (nCount / m_nColumns) * m_iChildMargin;
}
return m_szItem.cy * (rows+ 1) + childMarginTotal;
}
return 0;
}
void VirtualTileLayout::LazyArrangeChild()
{
VirtualTileBox *pList = dynamic_cast<VirtualTileBox*>(m_pOwner);
ASSERT(pList);
// 列在SetPos时已经设置好
ASSERT(m_nColumns);
// 获取VirtualTileBox的Rect
ui::UiRect rc = pList->GetPaddingPos();
// 子项的左边起始位置
int iPosLeft = rc.left;
// 子项的顶部起始位置
int iPosTop = rc.top + pList->GetScrollPos().cy;
ui::CPoint ptTile(iPosLeft, iPosTop);
// 顶部index
int nTopBottom = 0;
int nTopIndex = pList->GetTopElementIndex(nTopBottom);
int iCount = 0;
for (auto pControl : pList->m_items)
{
// Determine size
ui::UiRect rcTile(ptTile.x, ptTile.y, ptTile.x + m_szItem.cx, ptTile.y + m_szItem.cy);
pControl->SetPos(rcTile);
// 填充数据
int nElementIndex = nTopIndex + iCount;
if (nElementIndex < pList->GetElementCount())
{
if (!pControl->IsVisible()) pControl->SetVisible(true);
pList->FillElement(pControl, nElementIndex);
}
else {
if (pControl->IsVisible()) pControl->SetVisible(false);
}
if ((++iCount % m_nColumns) == 0) {
ptTile.x = iPosLeft;
ptTile.y += m_szItem.cy + m_iChildMargin;
}
else {
ptTile.x += rcTile.GetWidth() + m_iChildMargin;
}
}
}
int VirtualTileLayout::AjustMaxItem()
{
ui::UiRect rc = m_pOwner->GetPaddingPos();
if (m_bAutoCalcColumn)
{
if (m_szItem.cx > 0) m_nColumns = (rc.right - rc.left) / (m_szItem.cx + m_iChildMargin / 2);
if (m_nColumns == 0) m_nColumns = 1;
}
int nHeight = m_szItem.cy + m_iChildMargin;
int nRow = (rc.bottom - rc.top) / nHeight + 1;
return nRow * m_nColumns;
}
VirtualTileBox::VirtualTileBox(ui::Layout* pLayout /*= new VirtualTileLayout*/)
: ui::ListBox(pLayout)
, m_pDataProvider(nullptr)
, m_nMaxItemCount(0)
, m_nOldYScrollPos(0)
, m_bArrangedOnce(false)
, m_bForceArrange(false)
{
}
void VirtualTileBox::SetDataProvider(VirtualTileInterface *pProvider)
{
ASSERT(pProvider);
m_pDataProvider = pProvider;
// 注册模型数据变动通知回调
pProvider->RegNotifys(
nbase::Bind(&VirtualTileBox::OnModelDataChanged, this, std::placeholders::_1, std::placeholders::_2),
nbase::Bind(&VirtualTileBox::OnModelCountChanged, this));
}
void VirtualTileBox::Refresh()
{
m_nMaxItemCount = GetTileLayout()->AjustMaxItem();
int nElementCount = GetElementCount();
int nItemCount = GetCount();
// 如果现有子项总数大于数据总数, 移出比数据总数多出的子项
if (nItemCount > nElementCount)
{
int n = nItemCount - nElementCount;
for (int i = 0; i < n; i++)
this->RemoveAt(0);
}
// 如果子项总数据小于数据总数
else if (nItemCount < nElementCount) {
int n = 0;
if (nElementCount <= m_nMaxItemCount)
{
n = nElementCount - nItemCount;
}
else {
n = m_nMaxItemCount - nItemCount;
}
for (int i = 0; i < n; i++) {
Control *pControl = CreateElement();
this->Add(pControl);
}
}
if (nElementCount <= 0)
return;
ReArrangeChild(true);
Arrange();
}
void VirtualTileBox::RemoveAll()
{
__super::RemoveAll();
if (m_pVerticalScrollBar)
m_pVerticalScrollBar->SetScrollPos(0);
m_nOldYScrollPos = 0;
m_bArrangedOnce = false;
m_bForceArrange = false;
}
void VirtualTileBox::SetForceArrange(bool bForce)
{
m_bForceArrange = bForce;
}
void VirtualTileBox::GetDisplayCollection(std::vector<int>& collection)
{
collection.clear();
if (GetCount() == 0)
return;
// 获取Box的Rect
ui::UiRect rcThis = this->GetPaddingPos();
int nEleHeight = GetRealElementHeight();
int min = (GetScrollPos().cy / nEleHeight) * GetColumns();
int max = min + (rcThis.GetHeight() / nEleHeight) * GetColumns();
int nCount = GetElementCount();
if (max >= nCount)
max = nCount - 1;
for (auto i = min; i <= max; i++)
collection.push_back(i);
}
void VirtualTileBox::EnsureVisible(int iIndex, bool bToTop /*= false*/)
{
if (iIndex < 0 || iIndex >= GetElementCount())
return;
if (!m_pVerticalScrollBar)
return;
auto nPos = GetScrollPos().cy;
int nTopIndex = (nPos / GetRealElementHeight()) * GetColumns();
int nNewPos = 0;
if (bToTop)
{
nNewPos = CalcElementsHeight(iIndex);
if (nNewPos >= m_pVerticalScrollBar->GetScrollRange())
return;
}
else {
if (IsElementDisplay(iIndex))
return;
if (iIndex > nTopIndex)
{
// 向下
int height = CalcElementsHeight(iIndex + 1);
nNewPos = height - m_rcItem.GetHeight();
}
else {
// 向上
nNewPos = CalcElementsHeight(iIndex);
}
}
ui::CSize sz(0, nNewPos);
SetScrollPos(sz);
}
void VirtualTileBox::SetScrollPos(ui::CSize szPos)
{
m_nOldYScrollPos = GetScrollPos().cy;
ListBox::SetScrollPos(szPos);
ReArrangeChild(false);
}
void VirtualTileBox::HandleMessage(ui::EventArgs& event)
{
if (!IsMouseEnabled() && event.Type > ui::kEventMouseBegin && event.Type < ui::kEventMouseEnd) {
if (m_pParent != nullptr)
m_pParent->HandleMessageTemplate(event);
else
ui::ScrollableBox::HandleMessage(event);
return;
}
switch (event.Type) {
case ui::kEventKeyDown: {
switch (event.chKey) {
case VK_UP: {
OnKeyDown(VK_UP);
return;
}
case VK_DOWN: {
OnKeyDown(VK_DOWN);
return;
}
case VK_HOME:
SetScrollPosY(0);
return;
case VK_END: {
int range = GetScrollPos().cy;
SetScrollPosY(range);
return;
}
}
}
case ui::kEventKeyUp: {
switch (event.chKey) {
case VK_UP: {
OnKeyUp(VK_UP);
return;
}
case VK_DOWN: {
OnKeyUp(VK_DOWN);
return;
}
}
}
}
__super::HandleMessage(event);
}
void VirtualTileBox::SetPos(ui::UiRect rc)
{
bool bChange = false;
if (!m_rcItem.Equal(rc))
bChange = true;
ListBox::SetPos(rc);
if (bChange) {
Refresh();
}
}
void VirtualTileBox::ReArrangeChild(bool bForce)
{
ScrollDirection direction = kScrollUp;
if (!bForce && !m_bForceArrange) {
if (!NeedReArrange(direction))
return;
}
LazyArrangeChild();
}
ui::Control* VirtualTileBox::CreateElement()
{
if (m_pDataProvider)
return m_pDataProvider->CreateElement();
return nullptr;
}
void VirtualTileBox::FillElement(Control *pControl, int iIndex)
{
if (m_pDataProvider)
m_pDataProvider->FillElement(pControl, iIndex);
}
int VirtualTileBox::GetElementCount()
{
if (m_pDataProvider)
return m_pDataProvider->GetElementtCount();
return 0;
}
int VirtualTileBox::CalcElementsHeight(int nCount)
{
return GetTileLayout()->GetElementsHeight(nCount);
}
int VirtualTileBox::GetTopElementIndex(int &bottom)
{
int nPos = GetScrollPos().cy;
int nHeight = GetRealElementHeight();
int iIndex = (nPos / nHeight) * GetColumns();
bottom = iIndex * nHeight;
return iIndex;
}
bool VirtualTileBox::IsElementDisplay(int iIndex)
{
if (iIndex < 0)
return false;
int nPos = GetScrollPos().cy;
int nElementPos = CalcElementsHeight(iIndex);
if (nElementPos >= nPos) {
int nHeight = this->GetHeight();
if (nElementPos + GetRealElementHeight() <= nPos + nHeight)
return true;
}
return false;
}
bool VirtualTileBox::NeedReArrange(ScrollDirection &direction)
{
direction = kScrollUp;
if (!m_bArrangedOnce) {
m_bArrangedOnce = true;
return true;
}
int nCount = GetCount();
if (nCount <= 0)
return false;
if (GetElementCount() <= nCount)
return false;
ui::UiRect rcThis = this->GetPos();
if (rcThis.GetWidth() <= 0)
return false;
int nPos = GetScrollPos().cy;
ui::UiRect rcItem;
rcItem = m_items[0]->GetPos();
if (nPos >= m_nOldYScrollPos) {
// 下
rcItem = m_items[nCount - 1]->GetPos();
int nSub = (rcItem.bottom - rcThis.top) - (nPos + rcThis.GetHeight());
if (nSub < 0) {
direction = kScrollDown;
return true;
}
}
else {
// 上
rcItem = m_items[0]->GetPos();
if (nPos < (rcItem.top - rcThis.top)) {
direction = kScrollUp;
return true;
}
}
return false;
}
VirtualTileLayout* VirtualTileBox::GetTileLayout()
{
auto* pLayout = dynamic_cast<VirtualTileLayout*>(m_pLayout.get());
return pLayout;
}
int VirtualTileBox::GetRealElementHeight()
{
return GetTileLayout()->GetElementsHeight(1);
}
int VirtualTileBox::GetColumns()
{
return GetTileLayout()->GetColumns();
}
void VirtualTileBox::LazyArrangeChild()
{
GetTileLayout()->LazyArrangeChild();
}
void VirtualTileBox::OnModelDataChanged(int nStartIndex, int nEndIndex)
{
for (auto i = nStartIndex; i <= nEndIndex; i++)
{
if (IsElementDisplay(i))
{
int nTopItemHeight = 0;
int nItemIndex = i - GetTopElementIndex(nTopItemHeight);
ASSERT(nItemIndex > 0);
FillElement(m_items[nItemIndex], i);
}
}
}
void VirtualTileBox::OnModelCountChanged()
{
Refresh();
}

View File

@ -0,0 +1,203 @@
#pragma once
typedef function<void(int nStartIndex, int nEndIndex)> DataChangedNotify;
typedef function<void()> CountChangedNotify;
class UILIB_API VirtualTileInterface
{
public:
VirtualTileInterface();
/**
* @brief
* @return
*/
virtual ui::Control* CreateElement() = 0;
/**
* @brief
* @param[in] control
* @param[in] index
* @return
*/
virtual void FillElement(ui::Control *control, int index) = 0;
/**
* @brief
* @return
*/
virtual int GetElementtCount() = 0;
void RegNotifys(const DataChangedNotify& dcNotify, const CountChangedNotify& ccNotify);
protected:
void EmitDataChanged(int nStartIndex, int nEndIndex);
void EmitCountChanged();
private:
DataChangedNotify m_DataChangedNotify;
CountChangedNotify m_CountChangedNotify;
};
class UILIB_API VirtualTileLayout : public ui::TileLayout
{
public:
VirtualTileLayout();
virtual ui::CSize ArrangeChild(const std::vector<ui::Control*>& items, ui::UiRect rc) override;
virtual ui::CSize AjustSizeByChild(const std::vector<ui::Control*>& items, ui::CSize szAvailable) override;
virtual bool SetAttribute(const std::wstring& strName, const std::wstring& strValue) override;
virtual int GetElementsHeight(int nCount);
virtual void LazyArrangeChild();
virtual int AjustMaxItem();
private:
bool m_bAutoCalcColumn;
};
class UILIB_API VirtualTileBox : public ui::ListBox
{
friend class VirtualTileLayout;
public:
VirtualTileBox(ui::Layout* pLayout = new VirtualTileLayout);
/**
* @brief
* @param[in] pProvider VirtualListInterface
* @return
*/
virtual void SetDataProvider(VirtualTileInterface *pProvider);
/**
* @brief
* @return
*/
virtual void Refresh();
/**
* @brief
* @return
*/
virtual void RemoveAll() override;
/**
* @brief
* @param[in] bForce true
* @return
*/
void SetForceArrange(bool bForce);
/**
* @brief
* @param[out] collection
* @return
*/
void GetDisplayCollection(std::vector<int>& collection);
/**
* @brief
* @param[in] iIndex
* @param[in] bToTop
* @return
*/
void EnsureVisible(int iIndex, bool bToTop = false);
protected:
/// 重写父类接口,提供个性化功能
virtual void SetScrollPos(ui::CSize szPos) override;
virtual void HandleMessage(ui::EventArgs& event) override;
virtual void SetPos(ui::UiRect rc) override;
/**
* @brief
* @param[in] bForce
* @return
*/
void ReArrangeChild(bool bForce);
/**
* @brief
* @param[in] ch
* @return
*/
virtual void OnKeyDown(TCHAR ch) {}
/**
* @brief
* @param[in] ch
* @return
*/
virtual void OnKeyUp(TCHAR ch) {}
private:
enum ScrollDirection
{
kScrollUp = -1,
kScrollDown = 1
};
/**
* @brief
* @return
*/
Control* CreateElement();
/**
* @brief
* @param[in] control
* @param[in] index
* @return
*/
void FillElement(Control *pControl, int iIndex);
/**
* @brief
* @return
*/
int GetElementCount();
/**
* @brief n个元素对应的高度和
* @param[in] nCount -1
* @return
*/
int CalcElementsHeight(int nCount);
/**
* @brief
* @param[out] bottom bottom
* @return
*/
int GetTopElementIndex(int &bottom);
/**
* @brief
* @param[in] iIndex
* @return true
*/
bool IsElementDisplay(int iIndex);
/**
* @brief
* @param[out] direction
* @return true false
*/
bool NeedReArrange(ScrollDirection &direction);
VirtualTileLayout* GetTileLayout();
int GetRealElementHeight();
int GetColumns();
void LazyArrangeChild();
void OnModelDataChanged(int nStartIndex, int nEndIndex);
void OnModelCountChanged();
private:
VirtualTileInterface *m_pDataProvider;
int m_nMaxItemCount; // 列表真实控件数量上限
int m_nOldYScrollPos;
bool m_bArrangedOnce;
bool m_bForceArrange; // 强制布局标记
};

View File

@ -0,0 +1,47 @@
#include "stdafx.h"
#include "item.h"
Item::Item()
:control_img_(nullptr)
{
}
Item::~Item()
{
}
void Item::InitSubControls(const std::wstring& img, const std::wstring& title)
{
// 查找 Item 下的控件
if (control_img_ == nullptr)
{
control_img_ = dynamic_cast<ui::Control*>(FindSubControl(L"control_img"));
label_title_ = dynamic_cast<ui::Label*>(FindSubControl(L"label_title"));
progress_ = dynamic_cast<ui::Progress*>(FindSubControl(L"progress"));
btn_del_ = dynamic_cast<ui::Button*>(FindSubControl(L"btn_del"));
// 模拟进度条进度
auto timestamp = shared::tools::GenerateTimeStamp();
int64_t timestamp_num = 0;
nbase::StringToInt64(timestamp, &timestamp_num);
t_time = timestamp_num;
progress_->SetValue((double)(timestamp_num % 100));
// 设置图标和任务名称
control_img_->SetBkImage(img);
// 绑定删除任务处理函数
btn_del_->AttachClick(nbase::Bind(&Item::OnRemove, this, std::placeholders::_1));
}
label_title_->SetText(nbase::StringPrintf(L"%s %d%%", title.c_str(), t_time % 100));
}
bool Item::OnRemove(ui::EventArgs* args)
{
// 删除时,只需删除数据就可以了,不要删除界面上的元素
return true;
}

24
samples/virtualbox/item.h Normal file
View File

@ -0,0 +1,24 @@
#pragma once
// 从 ui::ListContainerElement 中继承所有可用功能
class Item : public ui::ListContainerElement
{
public:
Item();
~Item();
// 提供外部调用来初始化 item 数据
void InitSubControls(const std::wstring& img, const std::wstring& title);
private:
bool OnRemove(ui::EventArgs* args);
private:
ui::ListBox* list_box_;
ui::Control* control_img_;
ui::Label* label_title_;
ui::Progress* progress_;
ui::Button* btn_del_;
int64_t t_time;
};

View File

@ -0,0 +1,69 @@
// VirtualBox.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "main.h"
#include "main_form.h"
#include "VirtualTileBox.h"
ui::Control* MyCreateControlCallback(const std::wstring& sName)
{
if (sName == L"VirtualTileBox")
{
return new VirtualTileBox();
}
return nullptr;
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// 创建主线程
MainThread thread;
// 执行主线程循环
thread.RunOnCurrentThreadWithLoop(nbase::MessageLoop::kUIMessageLoop);
return 0;
}
void MainThread::Init()
{
nbase::ThreadManager::RegisterThread(kThreadUI);
// 获取资源路径,初始化全局参数
std::wstring theme_dir = QPath::GetAppPath();
#ifdef _DEBUG
// Debug 模式下使用本地文件夹作为资源
// 默认皮肤使用 resources\\themes\\default
// 默认语言使用 resources\\lang\\zh_CN
// 如需修改请指定 Startup 最后两个参数
ui::GlobalManager::Startup(theme_dir + L"resources\\", MyCreateControlCallback, false);
#else
// Release 模式下使用资源中的压缩包作为资源
// 资源被导入到资源列表分类为 THEME资源名称为 IDR_THEME
// 如果资源使用的是本地的 zip 文件而非资源中的 zip 压缩包
// 可以使用 OpenResZip 另一个重载函数打开本地的资源压缩包
ui::GlobalManager::OpenResZip(MAKEINTRESOURCE(IDR_THEME), L"THEME", "");
// ui::GlobalManager::OpenResZip(L"resources.zip", "");
ui::GlobalManager::Startup(L"resources\\", ui::CreateControlCallback(), false);
#endif
// 创建一个默认带有阴影的居中窗口
MainForm* window = new MainForm();
window->Create(NULL, MainForm::kClassName.c_str(), WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX, 0);
window->CenterWindow();
window->ShowWindow();
}
void MainThread::Cleanup()
{
ui::GlobalManager::Shutdown();
SetThreadWasQuitProperly(true);
nbase::ThreadManager::UnregisterThread();
}

23
samples/virtualbox/main.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include "resource.h"
class MainThread : public nbase::FrameworkThread
{
public:
MainThread() : nbase::FrameworkThread("MainThread") {}
virtual ~MainThread() {}
private:
/**
* 线
* @return void
*/
virtual void Init() override;
/**
* 线退
* @return void
*/
virtual void Cleanup() override;
};

View File

@ -0,0 +1,105 @@
#include "stdafx.h"
#include "main_form.h"
#include "provider.h"
const std::wstring MainForm::kClassName = L"VirtualBoxDemo";
MainForm::MainForm()
= default;
MainForm::~MainForm()
= default;
std::wstring MainForm::GetSkinFolder()
{
return L"virtualbox";
}
std::wstring MainForm::GetSkinFile()
{
return L"main.xml";
}
std::wstring MainForm::GetWindowClassName() const
{
return kClassName;
}
void MainForm::InitWindow()
{
m_EditColumn = dynamic_cast<ui::RichEdit*>(FindControl(L"edit_column"));
m_CheckBoxItemCenter = dynamic_cast<ui::CheckBox*>(FindControl(L"checkbox_item_center"));
m_EditTotal = dynamic_cast<ui::RichEdit*>(FindControl(L"edit_total"));
m_pTileList = dynamic_cast<VirtualTileBox*>(FindControl(L"list"));
m_OptionColumnFix = dynamic_cast<ui::Option*>(FindControl(L"option_column_fix"));
m_EditUpdate = dynamic_cast<ui::RichEdit*>(FindControl(L"edit_update"));
m_EditTaskName = dynamic_cast<ui::RichEdit*>(FindControl(L"edit_task_name"));
m_EditDelete = dynamic_cast<ui::RichEdit*>(FindControl(L"edit_delete"));
m_EditChildMargin = dynamic_cast<ui::RichEdit*>(FindControl(L"edit_child_margin"));
m_pRoot->AttachBubbledEvent(ui::kEventClick, nbase::Bind(&MainForm::OnClicked, this, std::placeholders::_1));
// ÉèÖÃÌṩÕß
m_DataProvider = new Provider;
m_pTileList->SetDataProvider(m_DataProvider);
}
LRESULT MainForm::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
PostQuitMessage(0L);
return __super::OnClose(uMsg, wParam, lParam, bHandled);
}
bool MainForm::OnClicked(ui::EventArgs* args)
{
auto sName = args->pSender->GetName();
if (sName == L"btn_set_total")
{
if (!m_EditChildMargin->GetText().empty())
{
m_pTileList->SetAttribute(L"childmargin", m_EditChildMargin->GetText());
}
if (m_OptionColumnFix->IsSelected())
{
m_pTileList->SetAttribute(L"column", m_EditColumn->GetText());
if (m_CheckBoxItemCenter->IsSelected())
{
m_pTileList->SetAttribute(L"width", L"auto");
m_pTileList->SetAttribute(L"halign", L"center");
}
else {
m_pTileList->SetAttribute(L"width", L"stretch");
}
}
else {
m_pTileList->SetAttribute(L"width", L"stretch");
m_pTileList->SetAttribute(L"column", L"-1");
}
int nTotal = _ttoi(m_EditTotal->GetText().c_str());
if (nTotal > 0) {
m_DataProvider->SetTotal(nTotal);
}
}
else if (sName == L"btn_update")
{
m_DataProvider->ChangeTaskName(_ttoi(m_EditUpdate->GetText().c_str())-1,
m_EditTaskName->GetText());
}
else if (sName == L"btn_delete")
{
m_DataProvider->RemoveTask(_ttoi(m_EditDelete->GetText().c_str()) - 1);
}
return true;
}

View File

@ -0,0 +1,49 @@
#pragma once
#include "VirtualTileBox.h"
#include "provider.h"
class MainForm : public ui::WindowImplBase
{
public:
MainForm();
~MainForm();
/**
*
* GetSkinFolder
* GetSkinFile xml
* GetWindowClassName
*/
virtual std::wstring GetSkinFolder() override;
virtual std::wstring GetSkinFile() override;
virtual std::wstring GetWindowClassName() const override;
/**
* WM_CREATE
*/
virtual void InitWindow() override;
/**
* WM_CLOSE
*/
virtual LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
static const std::wstring kClassName;
private:
bool OnClicked(ui::EventArgs* args);
private:
VirtualTileBox* m_pTileList;
Provider* m_DataProvider;
private:
ui::RichEdit* m_EditColumn;
ui::CheckBox* m_CheckBoxItemCenter;
ui::RichEdit* m_EditTotal;
ui::Option* m_OptionColumnFix;
ui::RichEdit* m_EditUpdate;
ui::RichEdit* m_EditTaskName;
ui::RichEdit* m_EditDelete;
ui::RichEdit* m_EditChildMargin;
};

View File

@ -0,0 +1,89 @@
#include "stdafx.h"
#include "provider.h"
#include "item.h"
int g_index = 1;
Provider::Provider()
:m_nTotal(0)
{
}
Provider::~Provider()
= default;
ui::Control* Provider::CreateElement()
{
Item* item = new Item;
ui::GlobalManager::FillBoxWithCache(item, L"virtualbox/item.xml");
return item;
}
void Provider::FillElement(ui::Control *control, int index)
{
Item* pItem = dynamic_cast<Item*>(control);
std::wstring img = L"icon.png";
std::wstring title = nbase::StringPrintf(L"%s [%02d]", m_vTasks[index].sName.c_str(), m_vTasks[index].nId);
pItem->InitSubControls(img, title);
}
int Provider::GetElementtCount()
{
// 加锁
nbase::NAutoLock auto_lock(&lock_);
return m_vTasks.size();
}
void Provider::SetTotal(int nTotal)
{
if (nTotal == m_nTotal) return;
if (nTotal <= 0) return;
// 加锁
lock_.Lock();
m_vTasks.clear();
for (auto i=1; i <= nTotal; i++)
{
DownloadTask task;
task.nId = i;
task.sName = L"任务名称";
m_vTasks.emplace_back(task);
}
lock_.Unlock();
// 通知TileBox数据总数变动
EmitCountChanged();
}
void Provider::RemoveTask(int nIndex)
{
// 加锁
nbase::NAutoLock auto_lock(&lock_);
lock_.Lock();
auto iter = m_vTasks.begin() + nIndex;
m_vTasks.erase(iter);
lock_.Unlock();
// 通知TileBox数据总数变动
EmitCountChanged();
}
void Provider::ChangeTaskName(int nIndex, const wstring& sName)
{
if (nIndex > 0 && nIndex < m_vTasks.size())
{
m_vTasks[nIndex].sName = sName;
}
// 发送数据变动通知
EmitDataChanged(nIndex, nIndex);
}

View File

@ -0,0 +1,44 @@
#pragma once
#include "VirtualTileBox.h"
#include <map>
struct DownloadTask
{
int nId;
wstring sName;
};
class Provider : public VirtualTileInterface
{
public:
Provider();
~Provider();
virtual ui::Control* CreateElement() override;
/**
* @brief
* @param[in] control
* @param[in] index
* @return
*/
virtual void FillElement(ui::Control *control, int index) override;
/**
* @brief
* @return
*/
virtual int GetElementtCount() override;
public:
void SetTotal(int nTotal);
void RemoveTask(int nIndex);
void ChangeTaskName(int nIndex, const wstring& sName);
private:
int m_nTotal;
std::vector<DownloadTask> m_vTasks;
nbase::NLock lock_;
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,8 @@
// stdafx.cpp : 只包括标准包含文件的源文件
// VirtualBox.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息
#include "stdafx.h"
// TODO: 在 STDAFX.H 中
// 引用任何所需的附加头文件,而不是在此文件中引用

View File

@ -0,0 +1,30 @@
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的信息
// Windows 头文件:
#include <windows.h>
// C 运行时头文件
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
// base header
#include "base/base.h"
// shared project
#include "shared/shared.h"
// duilib
#include "duilib/UIlib.h"

View File

@ -0,0 +1,8 @@
#pragma once
// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h并将
// WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
#include <SDKDDKVer.h>

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="源文件">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="头文件">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="资源文件">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="Resource.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="main_form.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="main.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="main_form.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="VirtualBox.rc">
<Filter>资源文件</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<Image Include="small.ico">
<Filter>资源文件</Filter>
</Image>
<Image Include="VirtualBox.ico">
<Filter>资源文件</Filter>
</Image>
</ItemGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

View File

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{E35589C6-9509-4116-996F-1D045C2DACAE}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>VirtualBox</RootNamespace>
<ProjectName>virtualbox</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(ProjectDir)..\..\tmp\$(PlatformName)\$(ProjectName)\$(Configuration)\</IntDir>
<OutDir>..\..\bin\</OutDir>
<TargetName>$(ProjectName)_d</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(ProjectDir)..\..\tmp\$(PlatformName)\$(ProjectName)\$(Configuration)\</IntDir>
<OutDir>..\..\bin\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>..\..\tool_kits\;</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\..\tool_kits\;</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="item.h" />
<ClInclude Include="main_form.h" />
<ClInclude Include="provider.h" />
<ClInclude Include="Resource.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="main.h" />
<ClInclude Include="VirtualTileBox.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="item.cpp" />
<ClCompile Include="main_form.cpp" />
<ClCompile Include="provider.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="main.cpp" />
<ClCompile Include="VirtualTileBox.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="VirtualBox.rc" />
</ItemGroup>
<ItemGroup>
<Image Include="small.ico" />
<Image Include="VirtualBox.ico" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\tool_kits\base\base.vcxproj">
<Project>{8d9a6595-717a-41c8-b468-0011a72be3d1}</Project>
</ProjectReference>
<ProjectReference Include="..\..\tool_kits\duilib\duilib.vcxproj">
<Project>{e106acd7-4e53-4aee-942b-d0dd426db34e}</Project>
</ProjectReference>
<ProjectReference Include="..\..\tool_kits\shared\shared.vcxproj">
<Project>{9951345f-620b-4bed-bb51-4f928cafd454}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>