当前位置: 首页 > news >正文

MFC 对话框

目录

一、对话款基本认识

二、对话框项目创建

三、控件操作

四、对话框创建和显示 

模态对话框

非模态对话框

五、动态创建按钮

六、访问控件

控件添加控制变量

访问对话框

操作对话框

SendMessage()

七、对话框伸缩功能实现

八、对话框小项目-逃跑按钮

九、小项目


一、对话款基本认识

对话框是与用户进行交互的控件,如文件对话框,字体对话框,颜色对话框等,一般用于告示,提醒等。对话框就是一个窗口,它不仅可以接收消息,而且还可以被移动和关闭,甚至可以在它的客户区中进行绘图。相当于一个窗口,在它上面能够旋转各种标准控件和扩展控件。都是由CWnd类派生来。

Windows应用程序(win桌面应用程序)工作的基本流程是从用户那里得到数据,经过相应的处理之后,先把处理结果输出到屏幕,打印机或者其他输出设备。这就需要用到Windows应用程序的用户接口对话框。

常用对话框

这些控件也是对话框

二、对话框项目创建

创建MFC应用项目,创建基于对话框的程序类型

用户界面,按需选择

高级功能按需选择

生成的类:一个APP类,一个Dialog类

三、控件操作

WM系列消息是对话框接收处理,子控件的消息处理需要在消息映射中指明ID和控件事件

给对话框的控件添加消息处理的3种方式

  1. 双击对话框里面的控件就会在Dlg类消息映射表中添加消息映射
  2. 右击控件,选择类向导,命令一栏中,在里面选择控件的ID值,在选择对应的控件事件
  3. 右击对话框,选择属性,选择控件事件,选择要处理的消息

如何给对话框添加控件?VS中打开工具箱,直接选中拖曳即可

当控件的消息处理无法满足需求时,可以控件也是对话框,可以给控件,对话框添加类,指定ID,父窗口即可

资源添加一个新的对话框,在对话框中右击选择 添加类,会生成一个      .h       .cpp文件

继承的基类选择,可以选CDialog,或者CDialogEx(继承自前者,提供了更加丰富的控件支持)

这个创建后,其构造函数如下:

  1. ButtonText::ButtonText(CWnd* pParent /*=nullptr*/): 这是构造函数的定义,它属于名为ButtonText的类。构造函数的作用是在创建类的对象时进行初始化操作。
  2. :CDialogEx(IDD_DIALOG1, pParent): 这是构造函数的初始化列表(initializer list)。在这里,我们调用了基类(CDialogEx)的构造函数,并传入两个参数:对话框模板资源的ID(IDD_DIALOG1)和父窗口指针(pParent)。通过调用基类的构造函数,确保了从基类继承的成员变量得到了正确的初始化。

在这个构造函数中,传入的 pParent 参数指定了对话框的父窗口。父窗口是指对话框所属的上层窗口,通常用于确定对话框的显示位置和处理窗口间的关系。在这里,pParent 参数指定了对话框的父窗口,可以根据调用这个构造函数时传入的具体参数值来确定。在实际使用中,根据具体的情景,可以传入不同的父窗口指针,以确立对话框与哪个窗口有关联关系。

AddDialogText::AddDialogText(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_DIALOG1, pParent)
{}

控件的类不想要了,怎么办?项目中删除即可,即可把类的引用修改回来,否则会造成程序连接时候报错。


 

四、对话框创建和显示 

一个控件(对话框),使用消息映射来处理控件事件;一个控件(对话框),添加类,创建类并且show是不一样的。或者提供了更加丰富的功能,更重要的是可以绘制出来,与用户交互,而且拥有自己的消息循环。

创建一个对话框,并设置ID值,在属性一栏中,可以控制外观,位置,行为等,给该对话框添加类。

当点击第一个对话框确定按钮后,就会弹出一个新的对话框。

所以需要在第一个对话框的 .cpp 文件包含新对话框的类。

需要在第一个消息对话框中为Button(确定按钮)使用消息映射机制,

模态对话框

对话框,控件的本质都是对话框,创建他们需要先Create后Show

模态(Model)对话框:指当其显示时,程序会暂停执行,直到关闭这个模态对话框后,才能继续执行程序中其它任务。当一个模态对话框打开时,用户只能与该对话框进行交互,而其它用户界面对象接收不到输入信息。在其显示时,整个程序会暂停,直到关闭该对话框。

void CMFCApplication1Dlg::OnBnClickedOk()
{// 1.模态对话框使用CBingoDialog dlg;dlg.DoModal();    // 模态对话框,只能操作当前窗口,会阻塞消息循环
}

一但使用后该进程只能先等该对话框处理完后才能继续处理消息。

非模态对话框

对话框,控件的本质都是对话框,创建他们需要先Create后Show

非模态(Modeless)对话框:当其显示时,允许执行程序中其它任务,而不用关闭这个对话框。在MFC中,对资源的操作通常都是通过一个与资源相关的类来完成。对话框资源对应CDialog基类。

需要考虑一个问题,如果在函数内部实例化对话框,创建,绘制对话框,函数执行结束,对话框就会销毁。最好的处理办法就是:在第一个对话框类中,实例化对象,并在调用初始化函数时创建出来,在消息函数中绘制。

void CMFCApplication1Dlg::OnBnClickedOk()
{// 2.非模态对话框//需要作为MFCApplication1Dlg类的成员变量//原因:非模态对话框不会阻塞消息循环,一旦函数结束就会析构掉对象,造成程序崩溃// 窗口绘制之前还需要先创建,在这个类初始化时进行操作if (dlg.m_hWnd == NULL){dlg.Create(IDD_DLG_EDAOYUN, this);}dlg.ShowWindow(SW_SHOW);
}

五、动态创建按钮

动态的需求,需要多少个按钮在程序开始时时不确定的,只能在程序运行时创建

void CBingoDialog::OnBnClickedButton1()
{// TODO: 在此添加控件通知处理程序代码TRACE("%s(%d):%s\n", __FILE__, __LINE__, __FUNCTION__);if (m_button.m_hWnd == NULL){m_button.Create(_T("动态"), BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,CRect(100, 100, 200, 150), this, 9999);}TCHAR buf[20] = _T("");::SendMessage(m_edit1.m_hWnd, WM_GETTEXT, 20, (LPARAM)buf);m_edit1.SendMessage(WM_SETTEXT, sizeof(buf), (LPARAM)buf);this->SendMessage(WM_GETTEXT, 20, (LPARAM)buf);
}

相关必要的解释:

  • CButton类是继承自CWND类,m_hWnd就是该类的一个成员变量,记录了Windows系统创建该窗口后,这个窗口的句柄由 m_hWnd 来保存。说明控件(对话框)的本质就是窗口
  • BS_DEFPUSHBUTTON:这是按钮的样式,表示默认的按钮外观。
  • WS_VISIBLE | WS_CHILD:这是窗口样式,表示按钮是可见的并且作为父窗口的子窗口存在。
  • CRect(100, 100, 200, 150):这是按钮控件的位置和大小,使用矩形区域来表示,左上角坐标为 (100, 100),右下角坐标为 (200, 150)。
  • this:这个参数表示按钮控件的父窗口,也就是按钮所在的对话框
  • 9999:这是按钮控件的标识符,用于在程序中唯一标识这个按钮控件。

父窗口,子窗口:当我们在对话框中创建一个按钮时,按钮控件会成为对话框的子窗口,并且对话框将成为该按钮的父窗口。这意味着按钮的显示、布局、事件处理等都是相对于对话框来进行的。同时,对话框也负责管理和维护这些子窗口,比如控制它们的显示和隐藏,处理它们的消息等。

  1. 父窗口

    • 父窗口通常是一个容器窗口,它可以包含其他窗口作为它的子窗口。
    • 父窗口负责管理和布局它的子窗口,包括显示、隐藏、移动、调整大小等操作。
    • 一个窗口可以同时是另一个窗口的子窗口和父窗口,这种多层次的父子关系可以形成窗口的层次结构。
  2. 子窗口

    • 子窗口是被包含在父窗口内的窗口,它的位置和尺寸相对于父窗口来确定。
    • 子窗口可以是各种控件,比如按钮、文本框、列表框等,也可以是其它窗口。
    • 子窗口的行为通常由其父窗口来管理和控制,父窗口处理子窗口的消息并进行相应的响应。

在 MFC 编程中,对话框类通常是一个典型的父窗口,它可以包含各种控件作为其子窗口,比如按钮、编辑框、组合框等。当你在对话框资源编辑器中放置控件时,这些控件就成为了对话框的子窗口。在对话框类的代码中,你可以通过控件的成员变量或者控件 ID 来操作和管理这些子窗口。

上述在按钮消息处理函数中,this指针指向的就是父窗口

六、访问控件

控件都提供一些方法用于访问,比如编辑框,提供了设置默认内容,获取编辑框输入内容给的方法

用编辑框为例,学习相关使用。

控件添加控制变量

右击控件,添加变量

在父类中,会增加以下内容:

int m_value1;
int m_value2;
int m_value3;

父类构造函数

CBingoDialog::CBingoDialog(CWnd* pParent /*=nullptr*/): CDialog(IDD_DLG_EDAOYUN, pParent), m_value1(0), m_value2(0), m_value3(0)
{}

CEdit m_edit1;
CEdit m_edit2;
CEdit m_edit3;

添加变量 值,控件都会在 DoDataExchange 中指定对话框类成员变量与控件之间的数据交换规则,以及进行数据验证。

void CBingoDialog::DoDataExchange(CDataExchange* pDX)
{CDialog::DoDataExchange(pDX);DDX_Text(pDX, IDC_EDIT1, m_value1);DDV_MinMaxInt(pDX, m_value1, -9999, 9999);DDX_Text(pDX, IDC_EDIT2, m_value2);DDV_MinMaxInt(pDX, m_value2, -9999, 9999);DDX_Text(pDX, IDC_EDIT3, m_value3);DDV_MinMaxInt(pDX, m_value3, -9999, 9999);DDX_Control(pDX, IDC_EDIT1, m_edit1);DDX_Control(pDX, IDC_EDIT2, m_edit2);DDX_Control(pDX, IDC_EDIT3, m_edit3);
}

DoDataExchange 是 MFC 对话框类中的一个重要成员函数,用于实现对话框和控件之间的数据交换。在该函数中,可以通过调用 DDX_DDV_ 系列的宏来指定对话框类成员变量与控件之间的数据交换规则,以及进行数据验证。

具体来说,DoDataExchange 函数通常被用来执行两个方面的工作:

  1. 数据传递(DataExchange):将对话框类中的成员变量的值与与之关联的控件进行双向的数据交换。这包括从控件更新数据到成员变量(如 DDX_ControlDDX_Text 等),以及将成员变量的值反向填充到相关联的控件(如 DDX_ControlDDX_Text 等)。

  2. 数据验证(DataValidation):在数据交换过程中,执行数据验证操作,确保用户输入的数据符合预期的格式和范围。这包括使用 DDV_ 系列的宏来对用户输入的数据进行验证,例如格式、范围等。

在你提供的代码中,DoDataExchange 函数拥有一个名为 pDX 的参数,这是数据交换指针,它在数据传递和数据验证过程中扮演着重要的角色。通过在 DoDataExchange 函数中处理 pDX 参数,可以实现对话框和控件之间的数据交换和验证。

在 MFC(Microsoft Foundation Classes)中,DDX_Text 是一个用于数据交换的宏,用于在对话框和控件之间进行文本数据的交换。

具体地说,DDX_Text 宏用于将文本控件(如编辑框)中的数据与对话框类中的成员变量相关联,或者将对话框类中的成员变量的值与文本控件相关联。

DDX_Text(pDX, nIDC, memberName);

其中:

  • pDX 是数据交换指针,负责在对话框和控件之间进行数据交换。
  • nIDC 是控件的 ID,即要进行数据交换的控件的标识符。
  • memberName 是对话框类中的成员变量,用于存储或显示控件中的数据。

在你提供的代码中,DDX_Text(pDX, IDC_EDIT1, m_value1) 的作用是将 ID 为 IDC_EDIT1 的编辑框中的文本与对话框类中名为 m_value1 的成员变量进行关联。这样,在对话框中修改编辑框的内容时,相关联的成员变量 m_value1 也会相应地更新,反之亦然。

通过使用 DDX_Text 宏,可以很方便地实现对话框中控件和对话框类成员变量之间的双向数据交换,这在 MFC 编程中是非常常见和有用的操作。

在 MFC(Microsoft Foundation Classes)中,DDV_MinMaxInt 是一个用于数据验证的宏,用于验证整数类型的数据是否在指定的最小值和最大值范围内。

具体地说,DDV_MinMaxInt 宏用于在对话框数据验证期间检查整数类型的数据,确保其值在指定的最小值和最大值之间。其语法如下:

DDV_MinMaxInt(pDX, value, minVal, maxVal);

其中:

  • pDX 是数据交换指针,负责数据验证。
  • value 是要进行验证的整数值,通常是对话框类中的成员变量。
  • minVal 是允许的最小值。
  • maxVal 是允许的最大值。

在你提供的代码中,DDV_MinMaxInt(pDX, m_value1, -9999, 9999) 的作用是验证对话框类中名为 m_value1 的整数成员变量,确保其值在 -9999 到 9999 的范围内。如果用户输入的值不在这个范围内,MFC 将会显示相应的验证错误消息,并阻止用户继续进行操作,直到输入的值符合要求为止。

通过使用 DDV_MinMaxInt 宏,可以方便地实现对话框中整数类型数据的范围验证,确保用户输入的数据符合预期的范围要求。

DDX_Control 宏用于将对话框中的控件与对话框类中的成员变量进行关联,其作用是将控件的句柄(handle)与对话框类中的成员变量相关联,从而可以通过成员变量来操作控件。

具体来说,DDX_Control 宏的语法如下:

DDX_Control(pDX, nIDC, m_memberName);

其中:

  • pDX 是数据交换指针,负责在对话框和控件之间进行数据交换。
  • nIDC 是控件的 ID,即要进行数据交换的控件的标识符。
  • m_memberName 是对话框类中的成员变量,用于存储控件的句柄。

在你提供的代码中,DDX_Control(pDX, IDC_EDIT1, m_edit1) 的作用是将 ID 为 IDC_EDIT1 的编辑框控件与对话框类中名为 m_edit1 的成员变量进行关联。这样一来,通过 m_edit1 成员变量可以直接操作对应的编辑框控件,例如获取或设置文本内容、启用或禁用控件等操作。

通过使用 DDX_Control 宏,可以方便地实现对话框类成员变量与控件之间的关联,简化了对控件的操作和管理。

访问对话框

GetDlgItem 根据控件的 ID 来获取对应的编辑框控件对象的指针。

SetWindowText:为编辑框设置初始值

GetWindowText:获取编辑框内的值

SetDlgItemText,GetDlgItemText 上面两个功能的综合体

BOOL CBingoDialog::OnInitDialog()
{CDialog::OnInitDialog();// TODO:  在此添加额外的初始化CWnd* pEdit01 = GetDlgItem(IDC_EDIT1);CWnd* pEdit02 = GetDlgItem(IDC_EDIT2);//CWnd* pEdit03 = GetDlgItem(IDC_EDIT3);CString strText;if (pEdit01 != NULL){pEdit01->SetWindowText(_T("100"));pEdit01->GetWindowText(strText);}if (pEdit02 != NULL){SetDlgItemText(IDC_EDIT2, _T("200"));GetDlgItemText(IDC_EDIT2, strText);}//if (pEdit03 != NULL) pEdit03->SetWinodwText(_T("300"));SetDlgItemInt(IDC_EDIT3, 100);return TRUE;  // return TRUE unless you set the focus to a control// 异常: OCX 属性页应返回 FALSE
}

操作对话框

在对话框中输入三个值,点击确定按钮后,会把前两个值相加放到第三个中

UpdateData() 是 MFC 中用于进行对话框和控件之间数据交换的函数。通过调用 UpdateData(TRUE),可以将对话框中的控件的当前值更新到关联的成员变量中;而通过调用 UpdateData(FALSE),可以将成员变量的值更新到关联的控件中。

void CBingoDialog::OnBnClickedOk()
{// TODO: 在此添加控件通知处理程序代码//CDialog::OnOK();//UpdateData();//m_value3 = m_value2 + m_value1;//UpdateData(FALSE);CString str1, str2, str3;m_edit1.GetWindowText(str1);m_edit2.GetWindowText(str2);int t = _wtoi(str1) + _wtoi(str2);TCHAR buf[32] = _T("");str3 = buf;m_edit3.SetWindowTextW(str3);
}

SendMessage()

一个是调用全局的方法,一个是调用编辑框类的方法

::SendMessage(m_edit1.m_hWnd, WM_GETTEXT, 20, (LPARAM)buf);
m_edit1.SendMessage(WM_SETTEXT, sizeof(buf), (LPARAM)buf);

SendMessage() 是 Windows API 中用于发送消息的函数之一,在 MFC 中也可以使用。通过 SendMessage() 函数,可以向窗口或控件发送特定的消息,以实现各种操作,如获取或设置控件的状态、通知控件发生了特定的事件等。

具体来说,SendMessage() 函数的原型为:

LRESULT SendMessage(HWND   hWnd,UINT   Msg,WPARAM wParam,LPARAM lParam
);
  • hWnd:指定要接收消息的窗口或控件的句柄。
  • Msg:指定要发送的消息类型,是一个表示消息的整数值。
  • wParam 和 lParam:作为消息参数传递的额外信息,具体意义取决于不同的消息类型。

在 MFC 中,你可以使用 SendMessage() 函数来与窗口控件进行交互,例如设置控件的状态、获取控件的信息、自定义处理消息等。常见的用法包括发送 WM_SETTEXT 消息来设置控件的文本内容,发送 BM_CLICK 消息来模拟按钮的点击操作,以及发送自定义消息来实现特定的功能。

七、对话框伸缩功能实现

思路:初始化对话框函数中,获取窗口大小,计算得到缩小后的窗口大小

GetWindowRect获取对话框大小

判断一个矩形是否为空:IsRectEmpty(),IsRectNull()。前者是判断矩形面积是否为空,后者是判断矩形的四个坐标值是否为0,不关心是否能做为一个矩形。

SetWindowPos()改变窗口的大小。

BOOL CBingoDialog::OnInitDialog()
{CDialog::OnInitDialog();// 获取窗口范围GetWindowRect(m_large);m_small = m_large;// 计算得到缩小后的范围m_small.right = m_small.left + m_small.Width() / 2;m_small.bottom = m_small.top + m_small.Height() / 2;return TRUE;  // return TRUE unless you set the focus to a control// 异常: OCX 属性页应返回 FALSE
}

在缩小按钮按钮事件中完成对窗口的缩放处理

void CBingoDialog::OnBnClickedBtnLarge()
{// TODO: 在此添加控件通知处理程序代码CRect curRect;GetWindowRect(curRect);CWnd* pButton = GetDlgItem(IDC_BTN_LARGE);CString strTitle;if (pButton){pButton->GetWindowText(strTitle);if (strTitle == _T("放大") && m_large.IsRectEmpty() == FALSE){pButton->SetWindowTextW(_T("缩小"));SetWindowPos(NULL, curRect.left, curRect.top, m_large.Width(), m_large.Height(), SWP_NOMOVE | SWP_NOZORDER);// 窗口Z轴控制//SetWindowPos(&wndTopMost, curRect.left, curRect.top, m_large.Width(), m_large.Height(), SWP_NOMOVE);}else if (m_small.IsRectEmpty() == FALSE){pButton->SetWindowTextW(_T("放大"));SetWindowPos(NULL, curRect.left, curRect.top, m_small.Width(), m_small.Height(), SWP_NOMOVE | SWP_NOZORDER);//SetWindowPos(&wndTopMost, curRect.left, curRect.top, m_small.Width(), m_small.Height(), SWP_NOMOVE);}}
}

八、小项目-逃跑按钮

创建一个基于对话框的项目,为两个按钮添加变量-控件

给这个项目,类向导,添加MFC类

这是,两个按钮添加变量-控件,是属于CBUTTON类;CMyButton类是属于CButton的子类。

鼠标移动到按钮控件上的消息会被控件捕获,而不会给对话框

不信的话,可以在对话框中设置一个鼠标移动消息验证一下

TRACE("%s(%d):%s %d %d\n", __FILE__, __LINE__, __FUNCTION__, point x, point y);

项目思路:为两个按钮对象给出MouseMove方法,响应消息

两个按钮创建变量-控件后,控件就会被类关联;使用CMyButton 指向这两个控件变量

	CMyButton m_btn_light;CMyButton m_btn_left;

CMyButton中设置一个类指针

CMyButton* m_pButton;

在对话框初始化时关联起来

	m_btn_left.m_pButton = &m_btn_light;m_btn_light.m_pButton = &m_btn_left;

处理逻辑

void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值ShowWindow(SW_HIDE);if (m_pButton != NULL){m_pButton->ShowWindow(SW_SHOW);}CButton::OnMouseMove(nFlags, point);
}

点击成功提示

void CRunningButtonDlg::OnBnClickedButton2()
{// TODO: 在此添加控件通知处理程序代码MessageBox(_T("恭喜你,点到我了"), _T("成功!"));
}

九、小项目-属性页添加

在八的基础上,给对话框添加一个新的按钮,点击后,会给出一个新的对话框

添加对话框资源

给新的对话框控件:Group Box,单选框,静态文本,列表

给这个对话框添加类,类向导,添加MFC类

给单选框添加控制变量-值,不必设置范围

这样做的意义就是有了对话框类,成员变量是控件的值,就可以拿到这些值了。

但是设置三个值记录太麻烦了,不如再次基础上魔改以下

修改为BOOL数组记录值

 修改初始化函数,和关联函数

为新对话框类重写初始化函数,选择这个类,属性,重写,选择要重写的类,要在初始化时为列表进行初始化,单选框不用,因为我们只需要获得它的状态。

BOOL PROP_01::OnInitDialog()
{CPropertyPage::OnInitDialog();// TODO:  在此添加额外的初始化// 因为GetDlgItem拿到根据ID拿控件的对象地址,默认类型时CWND,需要强制转换// 就可以通过地址来操作类的成员属性CListBox* pListBox = (CListBox*)GetDlgItem(IDC_LIST_COMPANY);if (pListBox){pListBox->AddString(_T("阿里巴巴"));pListBox->AddString(_T("华为"));pListBox->AddString(_T("腾讯"));pListBox->AddString(_T("京东"));pListBox->AddString(_T("百度"));}return TRUE;  // return TRUE unless you set the focus to a control// 异常: OCX 属性页应返回 FALSE
}

按照上面方法再创建一个对话框,添加控件

为对话框添加MFC类,右击对话框,类向导,添加MFC类

为多选框添加控制变量-值,和上面一样

按照上面再添加一个,最后一个了

类向到,添加MFC类

添加控制变量-值

十、属性页处理

再追加一个MFC类,类向导,MFC类

将三个对话框作为成员变量添加给类 CMyProSheet

两个构造函数都要处理

父对话框触发点击事件

运行程序试试看

程序崩溃,尝试Debug,点击重试,程序就可以定位到崩溃处

问题出在这里

可能时对话框实例失败,验证以下,问题不在这里

查看调用堆栈,貌似也没啥问题,嗯?发现问题

查看路径下源码行处,发现对于处理单选框需要指定Group属性

单选框只能选一个,CTRL+D,可见Tab顺序

需要3,4,5是一个tab中,只需要再第一个单选框选中即可 GROUP=TRUE

那么单选框也就不需要数组了,Int 即可

接下来,优化对话框的上一步,下一步,去掉帮助按钮,未优化

优化:重写三个对话框类的激活方法(不是消息,是类的一个方法)

给公司添加控制变量

优化:重写OnwizardNext(),必须选择才能执行到下一步

十一、一些开发经验

需要初始化的控件可以在父窗口类初始化时进行。

添加控制变量(控件):值,可以拿到控件的值(编辑框的内容等等);控件,可以拿到控件的句柄保存到一个对象中。

将控制变量放到父窗口类中,我们可以自由拿到,通过父窗口对象操作控件

当需要处理控件的消息时,需要为控件添加控制变量到父窗口类中;如果想要处理该控件的消息,就需要实例化这个控件(所有控件都是继承自CWIND,都是窗口)。就需要创建出来一个类,利用多态,新类指向控制变量-控件,在新类中设置处理消息的函数,就可以了。参考八

获取窗口大小的操作都是放到初始化时完成的

在函数中不可实例化对象,因为函数结束对象销毁,不妨把要实例化的类放在类中,在函数中创建重绘。

添加MFC类,其实道理和八一样,对话框(控件)有了自己的类,就可以有更多操作的控件;再框架中要通过消息映射机制,操作空间有限

相关文章:

MFC 对话框

目录 一、对话款基本认识 二、对话框项目创建 三、控件操作 四、对话框创建和显示 模态对话框 非模态对话框 五、动态创建按钮 六、访问控件 控件添加控制变量 访问对话框 操作对话框 SendMessage() 七、对话框伸缩功能实现 八、对话框小项目-逃跑按钮 九、小项…...

关于node安装和nvm安装的问题

node 1.已经自定义路径安装了node,但是在cmd输入node -v显示不是内部命令 路径问题:确保 Node.js 已经被添加到了系统的环境变量 PATH 中。PATH 环境变量包含了操作系统用来查找命令的位置。你可以通过以下步骤检查 Node.js 是否已被添加到 PATH&#x…...

react 手机端 rc-table列隐藏(根据相关条件是否隐藏)、实现图片上传操作

最近公司某一项目的手机端,新增需求:table中的附件要可以编辑,并且是在特定条件下可编辑,其他仅做展示效果。 查阅官方文档,没有发现是否隐藏这一属性,通过css控制样式感觉也比较麻烦,后面发现可…...

目标检测YOLO系列从入门到精通技术详解100篇-【目标检测】三维重建

目录 前言 几个高频面试题目 “基于RGB-D相机的三维重建"和传统的SFM和SLAM算法有什么区别?...

H110主板搭配魔改QNCW升级小记

最近搬家完毕,翻出来一块闲置已久的qncw,隐约记得是买的主板套装,现在主板早已不知踪影,剩下孤零零一个CPU,一起翻出来一个G3900T亮机CPU,应该是同时代的产物。 qncw百度上一搜,发现参数还行&am…...

Rust8.2 Fearless Concurrency

Rust学习笔记 Rust编程语言入门教程课程笔记 参考教材: The Rust Programming Language (by Steve Klabnik and Carol Nichols, with contributions from the Rust Community) Lecture 16: Fearless Concurrency 无畏并发 src/main.rs use std::thread; use std::time::Du…...

合并两个有序链表(冒泡排序实现)

实例要求:将两个升序链表合并为一个新的 升序 链表并返回;新链表是通过拼接给定的两个链表的所有节点组成的;实例分析:先拼接两个链表,在使用冒泡排序即可;示例代码: struct ListNode* mergeTwo…...

【iOS】——知乎日报第五周总结

文章目录 一、评论区展开与收缩二、FMDB库实现本地持久化FMDB常用类:FMDB的简单使用: 三、点赞和收藏的持久化 一、评论区展开与收缩 有的评论没有被回复评论或者被回复评论过短,这时就不需要展开全文的按钮,所以首先计算被回复评…...

gRPC 四模式之 双向流RPC模式

双向流RPC模式 在双向流 RPC 模式中,客户端以消息流的形式发送请求到服务器端,服务器端也以消息流的形式进行响应。调用必须由客户端发起,但在此之后,通信完全基于 gRPC 客户端和服务器端的应用程序逻辑。 为什么有了双向流模式…...

五分钟,Docker安装kafka 3.5,kafka-map图形化管理工具

首先确保已经安装docker,如果是windows安装docker,可参考 wsl2安装docker 1、安装zk docker run -d --restartalways -e ALLOW_ANONYMOUS_LOGINyes --log-driver json-file --log-opt max-size100m --log-opt max-file2 --name zookeeper -p 2181:218…...

2023.11.18html中如何使用input/button进行网页跳转

2023.11.18html中如何使用input/button进行网页跳转 在做网页时有时会用元素,有时会用元素进行form表单操作或者网页跳转,但是用bootstrap时两种元素会出现不同的样式,为了样式一致,有时需要使用这两种元素相互实现其常用功能。 …...

java文件压缩加密,使用流的方式

使用net.lingala.zip4j来进行文件加密压缩。 添加依赖net.lingala.zip4j包依赖&#xff0c;这里使用的是最新的包2.11.5版本。 <dependency><groupId>net.lingala.zip4j</groupId><artifactId>zip4j</artifactId><version>${zip4j.versi…...

月子会所信息展示服务预约小程序的作用是什么

传统线下门店经营只依赖自然流量咨询或简单的线上付费推广是比较低效的&#xff0c;属于靠“天”吃饭&#xff0c;如今的年轻人学历水平相对较高&#xff0c;接触的事物或接受的思想也更多更广&#xff0c;加之生活水平提升及互联网带来的长期知识赋能&#xff0c;因此在寻找/咨…...

Windows核心编程 静态库与动态库

资源文件 .rc 文件 会被 rc.exe 变成 .res 文件(二进制文件) 在链接时链接进入 .exe 文件 一、如何保护源码 程序编译链接过程 不想让别人拿到源代码&#xff0c;但是想让其使用功能&#xff0c;根据上图观察&#xff0c;把自己生成的obj给对方&#xff0c;对方拿到obj后&…...

【Spring Boot】如何自定义序列化以及反序列器

在我们使用默认的消息转换器&#xff0c;将java的Long类型通过json数据传输到前端JS时&#xff0c;会导致Long类型的精度丢失&#xff0c;这是因为JS处理Long类型数字只能精确到前16位&#xff0c;所以我们可以采用自定义序列化方式将Long类型数据统一转为String字符串&#xf…...

6 Redis的慢查询配置原理

1、redis的命令执行流程 redis的慢查询只针对步骤3 默认情况下&#xff0c;慢查询的阈值是10ms...

JAVA小游戏 “拼图”

第一步是创建项目 项目名自拟 第二部创建个包名 来规范class 然后是创建类 创建一个代码类 和一个运行类 代码如下&#xff1a; package heima; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import …...

Spring 配置

配置文件最主要的目的 : 解决硬编码的问题(代码写死) SpringBoot 的配置文件,有三种格式 1.properties 2.yaml 3.yml(是 yaml 的简写) SpringBoot 只支持三个文件 1.application.properties 2.application.yaml 3.application.yml yaml 和 yml 是一样的,学会一个就行…...

全新酷盒9.0源码:多功能工具箱软件的最新iapp解决方案

全能工具箱软件酷盒&#xff1a;源码提供iapp解决方案&#xff0c;自定义打造个性化体验 酷盒是一款功能丰富的工具箱软件&#xff0c;内置众多实用功能&#xff0c;并实时更新热门功能。该软件还拥有丰富的资源库&#xff0c;用户可以在线畅玩游戏、免费下载音乐等。 我们提…...

aspose.cells java合并多个excel

背景 有需求需要把多个excel合并到一个excel文件里面&#xff0c;之前一直都是用python来处理办公自动化的东西&#xff0c;但是这个需求用python的openxyl库处理基本只能合并数据&#xff0c;样式没办法一比一合并过去&#xff0c;找了很多解决方案都没法实现&#xff0c;所以…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

C++ 设计模式 《小明的奶茶加料风波》

&#x1f468;‍&#x1f393; 模式名称&#xff1a;装饰器模式&#xff08;Decorator Pattern&#xff09; &#x1f466; 小明最近上线了校园奶茶配送功能&#xff0c;业务火爆&#xff0c;大家都在加料&#xff1a; 有的同学要加波霸 &#x1f7e4;&#xff0c;有的要加椰果…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...