找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 14|回复: 0

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

[复制链接]
  • TA的每日心情
    开心
    2026-4-12 21:41
  • 签到天数: 78 天

    [LV.6]常住居民II

    119

    主题

    17

    回帖

    2439

    积分

    管理员

    积分
    2439
    发表于 2026-4-6 11:04:21 | 显示全部楼层 |阅读模式
    涉及知识点:

    获取可用的屏幕个数以及分辨率
    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;
    }
    AI写代码
    cpp
    运行

    上面需要注意两个点

    EnumDisplayMonitors函数的回调函数的返回值一定是TRUE 否则只能检测一个屏幕,并不会遍历
    在放按钮的控件的窗口中使用线性布局,就不用考虑控件的位置了,直接设置控件的大小即可
    ————————————————
    版权声明:本文为CSDN博主「JamesWu9527」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/Wuzm_/article/details/107544852

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    Archiver|手机版|小黑屋|SOUI官方论坛

    GMT+8, 2026-4-21 19:31 , Processed in 0.092040 second(s), 21 queries .

    Powered by Discuz! X3.5

    © 2001-2025 Discuz! Team.

    快速回复 返回顶部 返回列表