SOUI自定义控件(3)

上一节内容已经搭好了主框架,本章就在这个框架下添砖加瓦了。这一节主要讲SOUI的消息映射,在SOUI里使用了WTL的消息映射方式,当主窗口收到消息后会根据情况转发消息给SOUI的控件,在控件里我们使用本

//消息映射列表
    SOUI_MSG_MAP_BEGIN()
    SOUI_MSG_MAP_END()

来处理消息。在这之前添加关心的消息即可,所有可用消息查看msgcrack.h即可查看。对于一大多数消息直接 MSG_WM_XXXX(XXXX代表消息名比如MSG_WM_SIZE即可处理WM_SIZE消息)。而且这个消息信息已经被crack了,可以直接使用。

// void OnSize(UINT nType, CSize size)
#define MSG_WM_SIZE(func) \
    if (uMsg == WM_SIZE) \
    { \
        SetMsgHandled(TRUE); \
        func((UINT)wParam, _WTYPES_NS::CSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
        lResult = 0; \
        if(IsMsgHandled()) \
            return TRUE; \
    }

如上MSG_WM_SIZE的定义,上面注释的函数即是你需要用来处理这个消息的函数原型。这样就可以方便的处理各种消息。当然还提供了消息区间等其它方便处理的宏。

这里我们要自绘控件当然少不了处理绘制消息WM_PAINT。但是因为WM_PAINT默认情况下传入的是DC,但是SOUI是DUI,它定义了自己的绘制对像,所以它重定义了一个MSG_WM_PAINT_EX宏来处理绘制消息。代码如下:

#pragma once
#include <core\SWnd.h>

SNSBEGIN

class SCharts :
    public SWindow
{
    DEF_SOBJECT(SWindow, L"scharts")

public:


protected:
    void OnPaint(IRenderTarget* pRT);

    //属性列表
    SOUI_ATTRS_BEGIN()

    SOUI_ATTRS_END()

    //消息映射列表
    SOUI_MSG_MAP_BEGIN()
        MSG_WM_PAINT_EX(OnPaint)
    SOUI_MSG_MAP_END()
};

SNSEND

这样我们实现OnPaint即可实现自定义绘制。

下面绘制一个拆线图:

最后效果如下:

 SCharts.h

#pragma once
#include <core\SWnd.h>
#include <vector>

SNSBEGIN

class SCharts :
    public SWindow
{
    DEF_SOBJECT(SWindow, L"scharts")

public:


protected:
    void OnPaint(IRenderTarget* pRT);

    void CalcPoint(std::vector<POINT>& ptList);

    //属性列表
    SOUI_ATTRS_BEGIN()

    SOUI_ATTRS_END()

    //消息映射列表
    SOUI_MSG_MAP_BEGIN()
        MSG_WM_PAINT_EX(OnPaint)
    SOUI_MSG_MAP_END()
};

SNSEND

SCharts.cpp

#include "stdafx.h"
#include "SCharts.h"
#include <random>

void SCharts::OnPaint(IRenderTarget* pRT)
{
	SPainter painter;
	BeforePaint(pRT, painter);

	std::vector<POINT> ptList;
	std::default_random_engine random(time(NULL));
	CRect rcClient;
	GetClientRect(&rcClient);
	std::uniform_int_distribution<int> dis1(0, rcClient.Height());
	for (int i = 0; i < 500;i++) {
		ptList.push_back({ i * 10,dis1(random)});
	}

	CalcPoint(ptList);
	pRT->DrawLines(ptList.data(), ptList.size());

	AfterPaint(pRT, painter);
}

void SCharts::CalcPoint(std::vector<POINT>& ptList)
{
	CRect rcClient;
	GetClientRect(&rcClient);

	for (auto& pt : ptList)
	{
		pt.x +=rcClient.left ;
		pt.y = rcClient.bottom - pt.y;
	}
}

XML仅仅是简单的去掉了前面的背景色。

上面的绘制代码主要调用DrawLines来绘制多线条。

PS:BeforePaint和AfterPaint用于保存和恢复IRenderTarget的绘制对象。因为SOUI的调用是一层一层绘制的,如果你不恢复绘制对象将会影响后面的绘制。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值