涉及知识点:
- 获取可用的屏幕个数以及分辨率
- SOUI中的线性布局的使用
- SOUI中的动态插入xml的方法(也就是动态的创建控件)
- 对动态创建出来的控件,进行一个点击事件的注册
目的:获取屏幕个数,生成对应的按钮,点击对应的按钮,设置窗体到对应的屏幕上;
和上一个例子的基础代码一致 这边直接上代码
void CMainDlg::OnGetScreenInfo()
{
EnumDisplayMonitors(NULL, NULL, &MonitorEnumProc, reinterpret_cast<LPARAM>(&m_vctStSPCfg));
//显示获取到的屏幕信息
//SMessageBox(this->m_hWnd, L"Info", L"Title", MB_OK);
//根据获取到的屏幕个数 动态创建两个按钮
int num = m_vctStSPCfg.size();
//Step1 先获取窗口的name
SWindow* pwnd = FindChildByName(L"wnd_insert");
pwnd->SetAttribute(L"layout", L"hbox"); //将布局方式设置为线性布局 那么后面的按钮 就不用考虑位置 直接设置大小即可
pugi::xml_document xml;
SStringT KPageXml = L"<button size=\"52,52\" colorText=\"#000000\" skin=\"_skin.sys.btn.normal\" name=\"btn_screen%d\" text=\"屏幕%d\"/>";
for (int i = 0; i < num; i++)
{
SStringT strTemp = KPageXml;
strTemp = SStringT().Format(strTemp, i, i);
xml.load(strTemp);
pwnd->CreateChildren(xml);
SStringT buttonName = L"btn_screen";
buttonName += SStringT().Format(L"%d", i);
SWindow* pwnd = FindChildByName(buttonName);
pwnd->GetEventSet()->subscribeEvent(SOUI_EVENTS::EVT_CMD, Subscriber(&CMainDlg::OnTestInsertButton, this));
}
}
bool CMainDlg::OnTestInsertButton(EventArgs* arg)
{
SStringT name = arg->nameFrom;
//SMessageBox(NULL, name, L"Title", MB_OK);
if (name.Compare(L"btn_screen0") == 0)
{
SMessageBox(NULL, L"点击了按钮0", L"", MB_OK);
CRect rect = m_vctStSPCfg[0].rcScreen;
MoveWindow(rect);
//this->Move(rect);
}
else if (name.Compare(L"btn_screen1") == 0)
{
SMessageBox(NULL, L"点击了按钮1", L"", MB_OK);
CRect rect = m_vctStSPCfg[1].rcScreen;
MoveWindow(rect);
}
return false;
}
BOOL CALLBACK CMainDlg::MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
std::vector<SCREEN_ITEM>* pVctScreen = (std::vector<SCREEN_ITEM>*)dwData;
if (pVctScreen == NULL)
return FALSE;
//获取窗口信息
MONITORINFO info;
ZeroMemory(&info, sizeof(info));
info.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(hMonitor, &info);
SCREEN_ITEM item;
if (info.dwFlags == MONITORINFOF_PRIMARY)
item.bPrimaryMonitor = true;
else
item.bPrimaryMonitor = false;
item.rcScreen = info.rcMonitor;
item.rcWork = info.rcWork;
pVctScreen->push_back(item);
return TRUE;
}
上面需要注意两个点
- EnumDisplayMonitors函数的回调函数的返回值一定是TRUE 否则只能检测一个屏幕,并不会遍历
- 在放按钮的控件的窗口中使用线性布局,就不用考虑控件的位置了,直接设置控件的大小即可