SOUI的一个动态创建控件的小例子

涉及知识点:

  1. 获取可用的屏幕个数以及分辨率
  2. SOUI中的线性布局的使用
  3. SOUI中的动态插入xml的方法(也就是动态的创建控件)
  4. 对动态创建出来的控件,进行一个点击事件的注册

目的:获取屏幕个数,生成对应的按钮,点击对应的按钮,设置窗体到对应的屏幕上;

和上一个例子的基础代码一致 这边直接上代码

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;
}

上面需要注意两个点

  1. EnumDisplayMonitors函数的回调函数的返回值一定是TRUE 否则只能检测一个屏幕,并不会遍历
  2. 在放按钮的控件的窗口中使用线性布局,就不用考虑控件的位置了,直接设置控件的大小即可

猜你喜欢

转载自blog.csdn.net/Wuzm_/article/details/107544852
今日推荐