首页 > 其他分享 >duilib 自定义控件

duilib 自定义控件

时间:2024-05-22 14:21:09浏览次数:25  
标签:控件 endPoint return 自定义 duilib FramWnd mycontrol hDC startPoint

1.主窗口

自定义FramWnd继承WindowImplBase,

重写CreateControl,HandleMessage.

组合CPaintManagerUI.

2.自定义控件

自定义mycontrol 继承CControlUI

重写DoEvent,DoPaint,SetPos.

main.cpp

#include "FramWnd.h"

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow)
{
    CPaintManagerUI::SetInstance(hInstance);
    CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());

    FramWnd* pFrame = new FramWnd();
    if (pFrame == NULL) return 0;
    pFrame->Create(NULL, _T("测试"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);
    pFrame->ShowWindow(true);
    CPaintManagerUI::MessageLoop();
    return 0;
}

 

FramWnd.h

#pragma once

#include "UIlib.h"
using namespace DuiLib;
class FramWnd :public WindowImplBase
{
public:
  FramWnd();
  virtual ~FramWnd() {}

  // 通过 CWindowWnd 继承
  virtual LPCTSTR GetWindowClassName() const override;
  UINT GetClassStyle() const override;

  LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override;

  CPaintManagerUI m_pm;

  // 通过 WindowImplBase 继承
  virtual CDuiString GetSkinFolder() override;
  virtual CDuiString GetSkinFile() override;
  virtual CControlUI* CreateControl(LPCTSTR pstrClass);
};

 

FramWnd.cpp

#include "FramWnd.h"
#include "mycontrol.h"

LPCTSTR FramWnd::GetWindowClassName() const
{
  return _T("FramWnd");
}


UINT FramWnd::GetClassStyle() const
{
  return UI_CLASSSTYLE_FRAME | CS_DBLCLKS; ;
}

LRESULT FramWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  if (uMsg == WM_CREATE) {
    m_pm.Init(m_hWnd);
    CDialogBuilder builder;
    CControlUI* pRoot = builder.Create(_T("WindowsProject1.xml"), 0, this, &m_pm);
    m_pm.AttachDialog(pRoot);
    m_pm.AddNotifier(this);
    return 0;
  }
  else if (uMsg == WM_DESTROY) {
    ::PostQuitMessage(0);
  }
  LRESULT lRes = 0;
  if (m_pm.MessageHandler(uMsg, wParam, lParam,lRes)) return lRes;
  return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
}


CDuiString FramWnd::GetSkinFolder()
{
  return CDuiString();
}

CDuiString FramWnd::GetSkinFile()
{
  return CDuiString();
}

CControlUI* FramWnd::CreateControl(LPCTSTR pstrClass)
{
  if (_tcsicmp(pstrClass, _T("mycontrol")) == 0)
  {
    return  new mycontrol;
  }
  return NULL;
}

FramWnd::FramWnd()
{
}

 

mycontrol.h

#pragma once
#include "UIlib.h"
typedef struct {
  POINT startPoint; // 鼠标按下时的坐标点,
  POINT endPoint; // 鼠标释放时的坐标点,
}line;

namespace DuiLib
{
  class mycontrol :
    public CControlUI 
  {
  public:
    mycontrol(void);
    ~mycontrol(void);
    virtual void SetPos(RECT rc, bool bNeedInvalidate = true);
    bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl);
    virtual void DoEvent(TEventUI& event);

  private:
    POINT _startPoint; // 鼠标按下时的坐标点,
    POINT _endPoint; // 鼠标释放时的坐标点
    bool _lbtnDown; // 鼠标左键是否按下。
    std::vector<line> _lines; // 存储所有绘制的线段。
  };
}

 

mycontrol.cpp

 

#include "mycontrol.h"
#include "UILib.h"

namespace DuiLib
{
  mycontrol::mycontrol(void){}
  mycontrol::~mycontrol(void) {}
  void mycontrol::SetPos(RECT rc, bool bNeedInvalidate)
  {
    CControlUI::SetPos(rc, bNeedInvalidate);
  }

  bool mycontrol::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
  {
    RECT rc = GetPos() ;
    if (IsRectEmpty(&rc)) {
      return false;
    }
    COLORREF bgColor = RGB(255, 255, 255); // 默认白色  
    HBRUSH hBrush = CreateSolidBrush(bgColor);
    if (hBrush) {
      HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
      FillRect(hDC, &rc, hBrush);
      DrawText(hDC, _T("Hello, World!"), -1, (LPRECT)&rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
      HPEN hPen2 = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
      SetPixel(hDC, 30, 10, RGB(255, 0, 0));
      SetPixel(hDC, _startPoint.x, _startPoint.y-3, RGB(255, 0, 0));
      SelectObject(hDC, hPen2);
      MoveToEx(hDC, 0, 0, NULL);
      LineTo(hDC, rc.right, rc.bottom);
      MoveToEx(hDC, _startPoint.x, _startPoint.y, NULL);
      LineTo(hDC, _endPoint.x, _endPoint.y);
      for (auto line:_lines)
      {
        MoveToEx(hDC, line.startPoint.x, line.startPoint.y, NULL);
        LineTo(hDC, line.endPoint.x, line.endPoint.y);
      }
      DeleteObject(hPen2);
      SelectObject(hDC, hOldBrush);
      DeleteObject(hBrush);
    }
    return false;
  }
  void mycontrol::DoEvent(TEventUI& event)
  {
    
    switch (event.Type)
    {
      case UIEVENT_MOUSEMOVE:
        if (_lbtnDown)
        {
          _endPoint = event.ptMouse;
          Invalidate();
        }
        return;
      case UIEVENT_BUTTONUP:
        _lbtnDown = false;
        line l;
        l.startPoint = _startPoint;
        l.endPoint = _endPoint;
        _lines.push_back(l);
        return;
      case UIEVENT_BUTTONDOWN:
        _lbtnDown = true;
        _startPoint = event.ptMouse;
        return;
    default:
      break;
    }

    CControlUI::DoEvent(event);
  }
}
WindowsProject1.xml
<?xml version="1.0"?>
<Window mininfo="200,360" size=" 480,320 ">
    <VerticalLayout bkcolor="#FFFF00FF">

        <mycontrol  />
    </VerticalLayout>
</Window>

 

效果

 

标签:控件,endPoint,return,自定义,duilib,FramWnd,mycontrol,hDC,startPoint
From: https://www.cnblogs.com/liuguoyao514257665/p/18206103

相关文章

  • Python:自定义类或模块时的注意事项
     Python进阶版:定义类时应用的9种最佳做法1.好的命名2.显式实例属性3.使用属性——但要精简4.定义有意义的字符串表示法5.实例方法,类方法和静态方法6.使用私有属性进行封装7.分离关注点和解耦8.考虑使用__slots__进行优化9.文件 1.好的命名定义自己的类,就......
  • Serilog日志输出到WPF UI控件
    使用到日志接收器的接口 ILogEventSinkWPF+Prsim+Serilog详细介绍链接 https://github.com/serilog/serilog/wiki/Developing-a-sink   publicinterfaceILogEventSinkWrite:ILogEventSink{LogEventGetLogMessage();}publicclassLogEventSink:I......
  • keycloak~自定义认证流设置固定redirect_uri
    redirect_uri在keycloak进行认证成功之后,会重定向到这个目标页面,一般为用户的来源页,即你在登录之前访问的页面;自定义认证流是指对keycloak中的brower和directgrant两个认证方式的过程添加自定义策略,如在用户登录成功时,检查它的密码强度,如果不符合要求,就跳到一个说明页面,告诉用户,......
  • 自定义分页控件
    自定义分页控件tip:该控件的样式用的是materialDesign库,需要下载Nuget包CodeXaml<UserControlx:Class="TestTool.CustomControls.PagingControl"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.mic......
  • 自定义可移动点二维坐标轴控件
    自定义可移动点二维坐标轴控件目录路由参数坐标轴控件定义Demo路由参数X_YResultCollection为当前X轴对应Y轴值存储字典publicclassResultCollectionChangedEventArgs(RoutedEventroutedEvent,objectsource,IDictionary<double,double>resultCollection):Route......
  • GridLayout 等控件来完成多行按钮操作
     第一步,在布局文件中添加一个GridLayout控件,设置它的行列数和间距等属性,例如:<GridLayoutandroid:id="@+id/grid_layout"android:layout_width="match_parent"android:layout_height="wrap_content"android:columnCount="4"andr......
  • form-create-designer中怎么扩展自定义组件
    form-create-designer中怎么扩展自定义组件form-create-designer是基于 @form-create/element-ui实现的表单设计器组件。可以通过拖拽的方式快速创建表单,提高开发者对表单的开发效率,节省开发者的时间。FormCreate官网:https://www.form-create.com帮助文档:https://pro.form-cr......
  • 高并发系统-使用自定义日志埋点快速排查问题
    背景在高并发的系统中,通常不会打印除参数校验失败或捕获异常之外的日志,防止对接口的性能产生影响。那对于请求不符合预期的情况,我们如何快速找到是哪块逻辑影响的至关重要。Pfinder提供的链路监控,更多的是性能层面的监控,无法满足我们上述的诉求。下面我将通过自定义通用上下......
  • spring boot如何自定义注解
    总共分三步:1、创建一个注解importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Target(ElementType.METHOD)//注解的目标为方法@Retention(Retention......
  • QT基础语法与控件
    1.基础使用纯正的开源版本QT使用C++来实现QT使用QT可以使C++项目可视化本身也是C++的一个库允许跨平台QT特征面向对象,模块化设计调用,所有QT控件可继承控件之间的通信,signalslot友好的联机帮助,函数参数手册自定义控件设计QTCreator编译器集成开发环境IDE直接下载QT......