POCO c++ 库 使用

背景

c++ 标准库基本没有考虑业务开发,偏离业务太远,对于开发者太不友好,我之前想在使用websocket ,但标准库没有,找了第三方库好久,发现不知道选什么好,c++库引用又不方便,必须编译成自己使用版本,对于我这个老手嫌麻烦,对新手不知道怎么办了.

poco库

这个库已经有10几年了,而且代码开发都是现代c++,代码可读性非常好,开发时候可以学习一下,我都不知道标准库代码为什么写成那样子,基本没有可读性,感觉自带混淆。。POCO 基本涵盖所有方面,加密,压缩,网络,转码 ,json,等等基本想到都有。

POCO 编译

https://github.com/pocoproject/poco

里面写了

自己必须自己安装cmake,我自己用cmake编译的,因为我直接点击sin工程编译总是编译失败,所以建议cmake,这里默认编译64位,windows开发大多数32位,目前我感觉不到64位程序的优势。

  1. 下载,我直接点击下载,我不用git
  2. 收到创建一个cmake-build目录
  3. 在当前目录启动cmd,要切换到当前目录,win11默认启动就当前目录
  4. cmake .. -A Win32 //生成工程,vs 版本必须要支持c++ 14 ,我开始用vs2012编译是不行,我后面用的vs2019, 默认会最高的版本编译,我这里编译32 ,如果你想64 就cmake ..
  5. cmake --build . --config Debug //编译debug版本,不然你开发debug时候,找不到对应库,因为POCO在头文件写lib引入,不同版本引入不一样。
  6. 找到bin debug dll复制到自己要工程即可。

总结

对于c++ windows 开发人来说,不怎么喜欢写命令编译,POCO 貌似有商业版本了,不过我们免费版本就可以了,基本涉及大部分业务。不得不佩服老外毅力,这个东西能写10几年维护,不得不说我们太多缺少这些精神,我们大部分一切只是为了利益。。。

duilib 消息自己简单总结

背景

最近由于各种原因又学习了duilib c/c++界面库

总结

  1. CWindowWnd::__WndPro
  2. pThis->HandleMessage
  3. m_PaintManager.MessageHandler(uMsg, wParam, lParam, lRes)[这个是最重要的]

前2步

调用虚函数 HandleMessage, 我们做界面开发时候会继承CWindowWnd其实前面2步,只是把窗口HWND 与 我们代码对象绑定起来,建立关系,duilib 提供 WindowImplBase 方便我们开发界面而已,我们也可以不继承这个类,自己写事件和一些事件处理。

m_PaintManager.MessageHandle

进入界面库核心逻辑,前面都是只是传统界面逻辑,这里根据windwos 系统消息[WM_PAINT, WM_LBUTTONDOWN] 等等事件。

  1. 属性【画图】
  2. 行为

画图

根据我们的节点,一个一个画出来,这个类似html技术,目前所有主流界面开发都有点类似html 界面开发思路。

行为

根据鼠标和按键触发对应行为,dulib的行为基本都是通过notify 时间投递,这个投递在当前HWND里面。

这个类似win32 界面开发, 传统win32开发增加一个按钮事件 ,那么就投递 BM_CLICK给父窗口,父窗口在消息处理函数中处理这个消息。

例子

Button 点击例子代码分析

    case WM_LBUTTONUP:
        {
            POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
            m_ptLastMousePos = pt;
            if( m_pEventClick == NULL ) break;
            ReleaseCapture();
            TEventUI event = { 0 };
            event.Type = UIEVENT_BUTTONUP;
            event.pSender = m_pEventClick;
            event.wParam = wParam;
            event.lParam = lParam;
            event.ptMouse = pt;
            event.wKeyState = (WORD)wParam;
            event.dwTimestamp = ::GetTickCount();
            // By daviyang35 at 2015-6-5 16:10:13
            // 在Click事件中弹出了模态对话框,退出阶段窗口实例可能已经删除
            // this成员属性赋值将会导致heap错误
            // this成员函数调用将会导致野指针异常
            // 使用栈上的成员来调用响应,提前清空成员
            // 当阻塞的模态窗口返回时,回栈阶段不访问任何类实例方法或属性
            // 将不会触发异常
            CControlUI* pClick = m_pEventClick;
            m_pEventClick = NULL;
            pClick->Event(event);
        }
        break;

在CPaintManagerUI::MessageHandler中处理windows 窗口消息,这里贴出来处理鼠标点击松开事件,基本都是这种写法来处理自绘的界面,记得很久很久之前自己写自绘的按钮就是在WM_PAINT 进行贴图,然后点击处理点击事件,就可以实现图片的按钮,比自己修改win32 button还方便一些,因为整个自绘逻辑都是自己开发的,用系统Button,很多逻辑都是系统,这样子导致很多限制,要打补丁的地方太多了。

            TEventUI event = { 0 };
            event.Type = UIEVENT_BUTTONUP;
            event.pSender = m_pEventClick;
            event.wParam = wParam;
            event.lParam = lParam;
            event.ptMouse = pt;
            event.wKeyState = (WORD)wParam;
            event.dwTimestamp = ::GetTickCount();
            // By daviyang35 at 2015-6-5 16:10:13
            // 在Click事件中弹出了模态对话框,退出阶段窗口实例可能已经删除
            // this成员属性赋值将会导致heap错误
            // this成员函数调用将会导致野指针异常
            // 使用栈上的成员来调用响应,提前清空成员
            // 当阻塞的模态窗口返回时,回栈阶段不访问任何类实例方法或属性
            // 将不会触发异常
            CControlUI* pClick = m_pEventClick;
            m_pEventClick = NULL;
            pClick->Event(event);

这里获取到点击控件,通过坐标计算找到合适控件【通过计算】,然后触发事件,这里事件就是UIEVENT_BUTTONUP,然后控件开始处理该事件。这个是虚函数,基本不会重载该虚函数,

button 控件处理函数

void CControlUI::Event(TEventUI& event)
{
    if( OnEvent(&event) ) DoEvent(event);
}

所有控件的基类,OnEvent 是委托事件,用户代码基本不会委托这个函数,除了一些复杂的控件。
DoEvent是虚函数,所有控件基本都会重载这个函数,用来专门事件处理的。

butto调用 DoEvent

        if( event.Type == UIEVENT_BUTTONUP )
        {
            if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
                if( ::PtInRect(&m_rcItem, event.ptMouse) && IsEnabled()) Activate();
                m_uButtonState &= ~(UISTATE_PUSHED | UISTATE_CAPTURED);
                Invalidate();
            }
            return;
        }

Activate 激活按钮触发点击事件,Button还有其他事件要处理,来显示不同点击事件

    bool CButtonUI::Activate()
    {
        if( !CControlUI::Activate() ) return false;
        if( m_pManager != NULL ) m_pManager->SendNotify(this, DUI_MSGTYPE_CLICK);
        return true;
    }

触发通知,这个等同win32变成的发送 BN_CLICKED事件,m_pManager里面有一个list 包含notify listener,遍历进行通知。
duilib窗口对象都会绑定一个CPaintManagerUI,窗口创建后就添加事件监听。
我们开发代码都会实现INotifyUI或者直接继承WindowImplBase,我们业务代码基本都在notify实现的。
总结
这里这么多代码,无法就是子控件与窗口建立联系,方便回调。
duiib这个界面库,基本在各大厂商进行验证,可以算是windows pc上面一个标准了,官方开源版本太老,可以用其他大厂的开源duilib直接开发,不过自己继续在官方版本也可以。
如果跨平台基本就是electron,但这种内存比较大,几百M跑不掉,对内容类型的界面用这个比较方便,对于性能要求比较高还是用duilib比较好。
QT也是不错的选择,不过我自己没有用过,wps yy貌似都是qt开发的。
选择哪个开发主要看自己业务,没有完美的东西