七、对话框

2006年8月5日

14:25

因为笔记是用OneNote做的,上传以后为看不到图片,于是我截图放到相册上面,

相册地址为:http://photo.163.com/photos/goodmoood/61588745/

如何创建一个对话框

1.先插入一个对话框,对话框本身也是一个窗口

Insert->resouce

2.我们需要创建一个类与对话框资源相关联,实现对窗口资源的操作。

因为在VC中对资源的操作通常都是通过对与资源相对应的类来完成的。

3.创建和显示对话框

对话框的类Cdialog有两种类型:模态对话框和非模态对话框

显示一个模态对话框时,程序会暂停,必须关闭该对话框程序才能继续。

非模态对话框不会暂停程序。

模态对话框的创建:CDialog::DoModal    关闭:CDialog::EndDialog(int)

创建模态对话框 CDialog::DoModal 返回一个int值,结束这个模态窗口时候,传递这个int值给CDialog::EndDialog(int)。DoModal函数本身有显示的作用,不用show函数

非模态对话框的创建:CDialog::Create

//初始化一个CDialog对象,创建一个非模态的对话框(modeless dialog box)

//把它将一个CDialog对象关联起来

//BOOL Create( LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL);

//BOOL Create( UINT nIDTemplate, CWnd* pParentWnd = NULL);

//lpszTemplateName: 对话框模板的名字

//nIDTemplate:对话框模板的ID号

//pParentWnd:对话框父窗口的指针,如果为NULL,则对话框的父窗口将被设置为主应用程序窗口

非模态的对话框在调用Create创建完对话框之后,需要调用ShowWindow显示对话框//ShowWindow(SW_SHOW)

CAUTION:

对于模态的对话框,在模态的对话框显示时,应用程序是暂停执行的,所以模态的对话框对象可以是局部对象,不会在模态的对话框显示之前析构。

而对于非模态的对话框,应用程序不会暂停执行,所以非模态对话框的对象不能是局部对象,非模态的对话框对象有两种定义方法:

1:定义对话框成员变量

2:在堆上分配内存,在堆上分配的内存和我们整个应用程序的生命周期是一样的,可以如下定义:

CTestDlg *pDlg=new CTestDlg();

//注意内存的回收,防止memory leak

使用非模态对话框时须注意:(使用非模态对话框比较麻烦)

对于模态的对话框,当我们点击OK或者Cancel按钮时对话框窗口会被销毁

对于非模态的对话框,点击OK或者Cancel按钮时,对话框窗口并没有被销毁,只是隐藏了而已。

当我们点击OK时,由基类的虚函数OnOK()响应 CDialog::OnOK

//virtual void OnOK();

//如果你在一个非模态的对话框中实现了一个OK Button,你必须重载OnOK成员函数,在它内部调用

//销毁非模态对话框时,不要试图调用基类的成员函数,因为它实际上调用的是EndDialog,which makes the dialog box invisible but does not destroy it.所以必须调用DestroyWindow函数。

动态创建按钮

点击一个按钮时,在窗口上面动态创建一个按钮的方法,按钮的单击、列表框的选择属于通告消息。

CButton::Create   //创建Button

//BOOL Create(LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)

//按钮也是子窗口,如果dwstyle中不包含WS_VISIBLE,则在创建完Button后,需要继续调用ShowWindow()显示按钮

CWnd和任何由CWnd类派生出来的窗口类对象,内部都有一个成员变量m_hWnd保存和这个对象相关联的窗口的句柄,没有窗口和它关联时,m_hWnd的值为NULL,这样可以

让一个静态文本框响应点击消息,并将英文文本改变为中文文本。

通常一个静态文本框不是用来响应各种消息的,也不能接收通告消息的,

要使它能够响应消息先要做下面两步:

1)将其ID值 IDC_STATIC 改成其他值

2)要让它接收通告消息,需要把它的属性的style的"Notify"项选上

下面看看怎么实现改变静态文本框的内容:

1.首先要获取静态文本

静态的文本框也是一个窗口,要获取静态文本框的文本,可以使用函数 CWnd::GetWindowText,

//int GetWindowText( LPTSTR lpszStringBuf, int nMaxCount )const;

//void GetWindowText( CString& rString ) const;

注意:在对话框中直接使用CWnd::GetWindowText函数将获取对话框的文本,而不是文本框的文本;要得到对话框的文本,先得取得文本框的句柄,操作如下:

GetDlgItem(IDC_NUMBER1/*文本框控件ID*/)->GetWindowText(str);

GetDlgItem 通过控件的ID号来获取对话框上面一个控件的指针,大多数情况下是用在一个对话框类当中。

2.设置文本使用 CWnd::SetWindowText

CWnd::SetWindowText

// void SetWindowText( LPTSTR lpszString)

GetDlgItem(IDC_NUMBER1)->SetWindowText("Number1:");

实现点击"Add按钮"时将"编辑框1"加"编辑框2"的值后放到"编辑框3"中

方法一:

atoi函数

int atoi( const char *string)  //将数值字符,转化为整形数值

char* _itoa( int value, char *string, int radix);

//Convert an integer to a string

//string 指向结果

//radix 2-36数值的*进制

方法二:

用第二种访问控件的方法,即用

GetDlgItemText(IDC_EDIT1,ch1,10);

代替上面的 GetDlgItem(IDC_EDIT1)->GetWindowText(ch1,10);

GetDlgItemText(IDC_EDIT2,ch2,10);

代替上面的 GetDlgItem(IDC_EDIT2)->GetWindowText(ch2,10);

SetDlgItemText(IDC_EDIT3,ch3,10);

代替上面的 GetDlgItem(IDC_EDIT3)->SetWindowText(ch3);

方法三:

方法四:

将控件与成员变量的关联,用成员变量来操作编辑框数据。

用ClassWizard用实现把控件与成员变量关联。

添加以后效果:

在class CTestDlg :的注释宏之间会增加三个变量,并且在构造函数对其初始化:

并且在CTestDlg::DoDataExchange(CDataExchange* pDX)中将控件与变量关联

不同的控件有不同的DDX_*函数。

DoDataExchange的调用时间:

//Called by the framework to exchange an validate dialog data

//由框架调用,来交换和校验对话框的数据

//Never call this function directly.It is called by the UpdateData member function.我们从来不会直接调用这个函数,它是由UpdateData成员函数调用

//Call UpdateData to initialize a dialog box's control or retrive data from a dialog box 调用UpdateData来初始化一个对话框控件,或者从对话框获得数据

如果在Add按钮的消息响应函数直接写:m_num3 = m_num1 + m_num2;

程序运行时,并不能实现我们想要的结果。因为我们在编辑框中输入的数值,没有传递给成员变量m_num1 ,m_num2,运算后的m_num3也没有传递给编辑框3,所以看不到效果。

前面我们知道,要把编辑框与成员变量关联起来要用到DoDataExchange函数,而这个函数由UpdateData()函数调用,所以我们要行调用UpdateData 使它们关联起来:

这样就可以实现加法运算了。

控件关联的成员变量可以设置最大最小值,ClassWizard的Member Variables选项卡中

DoDataExchange函数中也会有如下变化

//DDX : Dialog Data Exchange

//DDV : Dialog Data Validate

方法五:

将控件与成员变量的关联,不过这个成员变量是控件变量:

在void CTestDlg::DoDataExchange()函数中增加了下面三个关联

这各方法的好处是,这个控件变量代表了控件本身,这样他有很多的成员函数可以利用。

在添加按钮消息响应函数当中的操作过程与第一种方法类似,只需做以下替换。

m_edit1.GetWindowText(ch1,10);

代替第一种方法的 GetDlgItem(IDC_EDIT1)->GetWindowText(ch1,10);

m_edit2.GetWindowText(ch2,10);

代替第一种方法的 GetDlgItem(IDC_EDIT2)->GetWindowText(ch2,10);

m_edit3.SetWindowText(ch3);

代替第一种方法的 GetDlgItem(IDC_EDIT3)->SetWindowText(ch3);

方法六:发送消息法

1.在添加按钮消息响应函数当中的操作过程与第一种方法类似,只需做以下替换。

::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);

代替第一种方法的 GetDlgItem(IDC_EDIT1)->GetWindowText(ch1,10);

::SendMessage(GetDlgItem(IDC_EDIT2)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch2);

代替第一种方法的 GetDlgItem(IDC_EDIT2)->GetWindowText(ch2,10);

::SendMessage(GetDlgItem(IDC_EDIT3)->m_hWnd,WM_SETTEXT,0,(LPARAM)ch3);

代替第一种方法的 GetDlgItem(IDC_EDIT3)->SetWindowText(ch3);

2.上面用的::SendMessage 是SDK平台的函数,也可以用Wnd类中的SendMessage  如:

GetDlgItem(IDC_EDIT1)->SendMessage(WM_GETTEXT,10,(LPARAM)ch1);

GetDlgItem(IDC_EDIT2)->SendMessage(WM_GETTEXT,10,(LPARAM)ch2);

GetDlgItem(IDC_EDIT3)->SendMessage(WM_SETTEXT,0,(LPARAM)ch3);

3.由于前面我们已经对编辑框关联了控件变量m_edit1,m_edit2,m_edit3,而这些控件变量代表了控件本身,所以我们可以用它们来替换GetDlgItem(IDC_EDIT1)->m_edit1.SendMessage(WM_GETTEXT,10,(LPARAM)ch1);

m_edit2.SendMessage(WM_GETTEXT,10,(LPARAM)ch2);

m_edit3.SendMessage(WM_SETTEXT,0,(LPARAM)ch3);

方法七:也是发送消息法

我们可以用CWnd::SendDlgItemMessage给子控件发送消息,

CWnd::SendDlgMessage

LRESULT SendDlgItemMessage( int nID, UINT message, WPARAM wParam=0, LPARAM lParam = 0) //等价于我们先调用GetDlgItem再调用SendMessage,它只是把这两个函数封装了一下。

上面注明红色部分,通过发送EM_SETSEL 消息来复选编辑框3的内容,

效果如下:(编辑框3内容反色)

一个消息获取编辑框上选择了的文本(即经过拖拉背景色变了的部分),

要想显示复选的部分,编辑框必须获得当前焦点,用函数 CWnd::SetFocus().

MSDN 中的EM_SETSEL 消息

创建对话框类的方法:

View->ClassWizard 或者双击对话框资源,出现

创建完对话框类之后,可以在可以在ClassView中看到增加了

创建对话框的代码

动态创建按钮的代码

访问控件的方式

1、获取对话框上控件的指针

CWnd::GetDlgItem

CWnd* GetDlgItem( int nID ) const;

void CWnd::GetDlgItem( int nID,HWND* phWnd ) const;

2、CWnd::GetDlgItemText

//int GetDlgItemText( int nID, LPTSTR lpStr, int nMaxCount ) const;

//int GetDlgItemText( int nID, CString& rString ) const;

CWnd::SetDlgItemText

//void SetDlgItemText( int nID, LPCTSTR lpszString);

3、CWnd::GetDlgItemInt

//UINT GetDlgItemInt( int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE ) const;

//可以获取控件的文本,并把它转化为无符号整型 返回

//如果遇到非数值字符,或者数值超过所能表示的最大值,将会发生错误,lpTrans接收0值

//如果没有错误 lpTrans接收一个非零的值,如果lpTrans为NULL,GetDlgItemInt不会对错误产生警告

//bSigned指示接收的数值字符是否是有符号的,如果无符号,则创建一个unsigned value

CWnd::SetDlgItemInt

//void SetDlgItemInt( int nID/*控件ID号*/, UINT nValue/*所要设置的值*/,

BOOL bSigned = TRUE /*TRUE =有符号,FALSE =设置无符号的值*/);

4、控件与成员变量的关联,在DoDataExchange函数中

void CTestDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CTestDlg)

DDX_Text(pDX, IDC_EDIT1, m_num1);//将控件IDC_EDIT1与成员变量m_num1相关联

DDX_Text(pDX, IDC_EDIT2, m_num2);

DDX_Text(pDX, IDC_EDIT3, m_num3);

//}}AFX_DATA_MAP

}

DDX_函数有很多种,关联不同的控件,需要选择不同的DDX_函数,如DDX_Scroll,DDX_Radio等

5.将控件和控件变量相关联

这各方法的好处是,这个控件变量代表了控件本身,这样他有很多的成员函数可以利用。

6.SendMessage()

可以使用SDK平台的全局函数::SendMessage(),

也可以使用 Wnd 类的 SendMessage()由于控件也是一个Wnd类,

甚至可以直接用控件自身的成员SendMessage()函数发送消息

7.SendDlgItemMessage()

我们可以用CWnd::SendDlgItemMessage给子控件发送消息,

等价于我们先调用GetDlgItem再调用SendMessage,

CWnd::UpdateData

要使关联的变量获取控件的数据,需要先UpdateData()。

UpdateData(FALSE)说明对话框正在被初始化,控件可以接受到输入的值或者将关联变量的值赋到控件上。

UpdateData(TRUE)说明正在接受数据,将控件中的数据赋给关联变量。

当一个模态对话框创建的时候,自动调用UpdateData(FALSE)。

SendMessage方法

下面再看看MSDN中

方法五的代码

整个代码如下:

常用

常用

常用

不常用

不常用

本笔记由teshorse整理补充

http://blog.csdn.net/teshorse/

对话框的收缩与扩展

效果如下:

下面先介绍一些概念:

Z-order

窗口的Z次序表明了重叠窗口堆中窗口的位置,这个窗口堆是按一个假想的轴定位的,这个轴就是从屏幕向外伸展的Z轴。Z次序最上面的窗口覆盖所有其它的窗口,Z次序最底层的窗口被所有其它的窗口覆盖。应用程序设置窗口在Z次序中的位置是通过把它放在一个给定窗口的后面,或是放在窗口堆的顶部或底部。

Windows系统管理三个独立的Z次序——一个用于顶层窗口、一个用于兄弟窗口,还有一个是用于最顶层窗口。最顶层窗口覆盖所有其它非最顶层窗口,而不管它是不是活动窗口或是前台窗口。应用程序通过设置WS_EX_TOPMOST风格创建最顶层窗口。

一般情况下,Windows系统把刚刚创建的窗口放在Z次序的顶部,用户可通过激活另外一个窗口来改变Z次序;Windows系统总是把活动的窗口放在Z次序的顶部,应用程序可用函数BringWindowToTop把一个窗口放置到Z次序的顶部。函数SetWindowPos和DeferWindowPos用来重排Z次序。

兄弟窗口: 共享同一个父窗口的多个子窗口叫兄弟窗口。

活动窗口:

活动窗口是应用程序的顶层窗口,也就是当前使用的窗口。只有一个顶层窗口可以是活动窗口,如果用户使用的是一个子窗口,Windows系统就激活与这个子窗口相应的顶层窗口。任何时候系统中只能有一个顶层窗口是活动的。用户通过单击窗口(或其中的一个子窗口)、使用ALT+TAB或ALT+ESC组合键来激活一个顶层窗口,应用程序则调用函数SetActiveWindow来激活一个顶层窗口。

前台窗口和后台窗口:

在Windows系统中,每一个进程可运行多个线程,每个线程都能创建窗口。创建正在使用窗口的线程称之为前台线程,这个窗口就称之为前台窗口。所有其它的线程都是后台线程,由后台线程所创建的窗口叫后台窗口。

用户通过单击一个窗口、使用ALT+TAB或ALT+ESC组合键来设置前台窗口,应用程序则用函数SetForegroundWindow设置前台窗口。如果新的前台窗口是一个顶层窗口,那么Windows系统就激活它,换句话说,Windows系统激活相应的顶层窗口。

要点:获得扩展后窗口大小和收缩后大小调用CWnd::SetWindowPos()。

对话框的收缩与扩展的 实现步骤

第一步:实现点击按钮时变换文本

前面已经有过类似的操作介绍,是点击静态文本的时候转换静态文本框的文本。

这里就省略不说了。

第二步:改变窗口的大小

1.先要获得收缩窗口前的窗口矩形大小,可以保存在CRect对象当中。该对象有一些成员函数比较实用,如:

CRect::IsRectEmpty //用来判断CRect对象是否为empty,当矩形的长度与宽度为0时返回真

//CRect is empty if the width and/or height are 0;

CRect::IsRectNull  //判断CRect对象的上下左右四个成员变量是否都为0,都为0返回真

//Determines whether the top, bottom, left,and right member variables are all equal to 0.

获得窗口矩形大小用 CWnd::GetWindowRect

void GetWindowRect( LPRECT lpRect) const;

//获取窗口矩形区域的大小

用GetWindowRect函数得到收缩前的窗口矩形大小以及分隔符(也是窗口类的派生类)的矩形大小,然后得出收缩后的窗口矩形大小。

2.调用 CWnd::SetWindowPos 函数,改变窗口的大小

//BOOL SetWindowPos( const CWnd* pWndInsertAfter, int x,int y, int cx, int cy, UINT nFlags);  ( 详细用法请看MSDN,右边是从MSDN摘录下来的 )

flags:

SWP_NOMOVE   Retains current position (ignores the x and y parameters)

说明保持当前窗口的位置而不移动,忽略x和y坐标。

SWP_NOZORDER   Retains current ordering (ignores pWndInsertAfter).

说明保持当前的z次序。

SetWindowPos和DeferWindowPos用来重排Z-order

//应用程序通过设置WS_EX_TOPMOST风格创建最顶层窗口。

//应用程序可用函数BringWindowToTop把一个窗口放置到Z次序的顶部。

下面是“收缩扩展按钮”的消息响应函数代码

下面实现: 响应回车,改变焦点

在一个编辑框中输入数据并按回车以后,将输入焦点转到下一个编辑框控件,从而可以继续输入下一个数据

在对话框窗口上回车,窗口会响应缺省按钮的响应函数。一般来说,“OK确定”按钮是缺省按钮,如果未改动其响应函数,它会调用基类响应函数而关闭对话框。(删除调用基类响应函数的代码,就不会关闭对话框)

我们可以在资源编辑器里更换缺省按钮。

下面改变输入焦点:

我们可以添加一个按钮响应消息,在按钮响应消息里面捕获按键消息,从而改变输入焦点。

问题是编辑框只是一个控件,我们可以对编辑框控件生成相关的类来完成相关的功能。

另一个解决办法是修改编辑框控件原先的窗口过程,自己编写一个窗口过程替换MFC提供的编辑框窗口过程

我们可以在自己写的窗口过程中判断按键消息,如果是回车,则改变焦点。

下面介绍如何在窗口生成之后,修改窗口过程:用SetWindowLong可以设置窗口的默认窗口过程winProc

知道了用SetWindowLong可以设置窗口的默认窗口过程winProc,

但是在那里调用SetWindowLong函数比较合适呢?

在WM_INITDIALOG消息响应函数中处理比较合适。

WM_INITDIALOG消息:当对话框创建完成以及其上面的子控件创建完成之后,将要显示之前发送的消息。

如果在对话框的OnCreate()函数中调用的话,窗口的子控件还没有生成,无法改变其子控件的窗口过程。

而在WM_INITDIALOG消息响应函数中,子控件创建已经完成,只是没有显示而已,

这时响应SetWindowLong改变子控件的窗口过程非常合适。

为此我们要先添加一个WM_INITDIALOG消息响应函数。

程序代码见右边:

但是运行之后,并没有达到效果,回车后焦点没有改变。

原因是:编辑框的Style如果如果没有复选Multiline属性,

则编辑框无法接受多行,当然也就无法接受回车符发送的消息

在资源编辑器中,对编辑框作如下设置:

这样设置之后,就可以转移焦点了。

响应回车,改变焦点的 另一种方法

前面的方法,必须把编辑框的Style设置为Multiline属性,当编辑框很多时,这样方法比较麻烦。前面说过了,在对话框窗口上回车,窗口会响应缺省按钮的响应函数。那么我们可以考虑在缺省按钮的响应函数上做文章。

首先

要去掉编辑框的Style设置为Multiline属性,这样编辑框控件才不会响应回车消息,而执行缺省按钮的响应函数。

然后 在缺省按钮的响应函数中,添加下面几种代码

1.GetDlgItem(IDC_EDIT1 /*是编辑框1控件标识*/)->GetNextWindow()->SetFocus();

//这种方法只能对编辑框控件1有效

2. GetFocus()->GetNextWindow()->SetFocus();

3. GetFocus()->GetWindow(CW_HWNDNEXT)->SetFocus();

上面两种方法,当焦点到了最后一个控件时,再执行下去的话,

GetFocus()->GetNextWindow()和GetFocus()->GetWindow(CW_HWNDNEXT)将得到空指针

程序执行下去就会崩溃。

4.GetNextDlgTabItem(GetFocus())->SetFocus();//会循环查找窗口,获得当前具有焦点的窗口

最后这种方法不会出现问题。

 现在有个问题:

在改变焦点的同时,复选上新得到焦点的编辑框

对第一种改变焦点的方法,我用

::SendMessage(::GetWindow(hwnd,GW_HWNDNEXT),EM_SETSEL,0,-1);//复选编辑窗口

就可以啦,但是第二种方法中,我不知道怎么办?

SendDlgItemMessage(IDC_EDIT3,EM_SETSEL,0,-1);//复选编辑框3的全部内容

上面这条代码可以对个别控件有效,

我试图  SendDlgItemMessage(GetNextDlgTabItem(GetFocus()),EM_SETSEL,0,-1);

结果报错,应该怎么办?

终于搞定了,用下面的代码可以实现,但是感觉绕了个圈子不爽!谁有没有更简单的方法?

::SendMessage(

::GetWindow(GetNextDlgTabItem(GetFocus())->m_hWnd,GW_HWNDPREV),

EM_SETSEL,0,-1);

Z-order与窗口的概念

MSDN

设置为最顶层窗口

放置到Z-order的顶部

放置到z-order的底部

窗口的X和Y坐标

窗口的宽度与高度

保留当前位置

保留当前z-order

保留当前窗口大小,这样就不能修改窗口大小了

函数可以改变指定窗口的属性

要设置的值的偏移量

如果运行成功,则返回先前的32位integer值,如果第二个变量为GEL_WNDPROC,则返回先前的窗口过程。

响应回车,改变焦点 代码

注:

1.全局的SetFocus函数

HWND SetFocus(

HWND  hwnd  //handle to window

);

2.全局的GetNextWindow函数:

HWND GetNextWindow(

HWND hWnd,//handle to current window

UINT uCmd // direction

);//当 uCmd=GW_HWNDNEXT  当前窗口的下一个窗口

//当 uCmd=GW_HWNDPREV  当前窗口的上一个窗口

3.画红线的地方,可以用更强功能的函数替代:

SetFocus(::GetWindow(hwnd,GW_HWNDNEXT));

4.画红线的地方,也可以用GetNextDlgTabItem函数替代

::SetFocus(::GetNextDlgTabItem(::GetParent(hwnd),hwnd,FALSE));

//The GetNextDlgTabItem function retrieves a handle to the first control that has the

//WS_TABSTOP style that precedes(前面)( or follows)the specified control.

HWND GetNextDlgTabItem(

HWND hDlg,   //handle to dialog box

HWND hCtrl,  //handle to known control 已知控件的句柄

bool bPrevious   //direction flag 方向。If this parameter is TRUE,

//the function searches for the previous control in the dialog box.

//If this parameter is FALSE,the function searches for

//the next control in the dialog box

);

总之:

::GetNextWindow(hwnd,GW_HWNDNEXT)

::GetWindow(hwnd,GW_HWNDNEXT)

::GetNextDlgTabItem(::GetParent(hwnd),hwnd,FALSE)

都可以获得当前控件hwnd的下一个控件的句柄。

CWnd::GetNextWindow

CWnd* GetNextWindow( UINT nFlag = GW_HWNDNEXT )const;//具有缺省的方向GW_HWNDNEXT

 足足花了我两天的时间才把这一讲听完并且做完笔记,搞得失眠一宿,真是痛苦并痛快啊!终于可以睡一好觉,只希望这些努力没有白费,但愿它能对一些初学者有些帮助,对自己也有些帮忙!有空来我家玩玩:

 http://blog.csdn.net/teshorse/

http://hi.baidu.com/teshorse/

http://hexun.com/teshorse/

菜单项 Layout->TabOrder显示TAB顺序

孙鑫VC学习笔记:第七讲相关推荐

  1. 孙鑫VC++学习笔记(转载至程序员之家--虎非龙)[11--15] .

    第11课 1.创建4个菜单,为其添加消息响应,用成员变量保存绘画类型.添加LButtonDown和Up消息. 2.当窗口重绘时,如果想再显示原先画的数据,则需要保存数据.为此创建一个新类来记录绘画类型 ...

  2. 孙鑫VC++学习笔记(转载至程序员之家--虎非龙)[11--15]

    第11课 1.创建4个菜单,为其添加消息响应,用成员变量保存绘画类型.添加LButtonDown和Up消息. 2.当窗口重绘时,如果想再显示原先画的数据,则需要保存数据.为此创建一个新类来记录绘画类型 ...

  3. 视觉SLAM十四讲学习笔记-第七讲-视觉里程计-三角测量和实践

     专栏汇总 视觉SLAM十四讲学习笔记-第一讲_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习笔记-第二讲-初识SLAM_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习笔记-第 ...

  4. 视觉SLAM十四讲学习笔记-第七讲-视觉里程计-对极几何和对极约束、本质矩阵、基础矩阵

    专栏系列文章如下:  专栏汇总 视觉SLAM十四讲学习笔记-第一讲_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习笔记-第二讲-初识SLAM_goldqiu的博客-CSDN博客 视觉SLA ...

  5. 视觉SLAM十四讲学习笔记-第七讲-视觉里程计-PnP和实践

      专栏汇总 视觉SLAM十四讲学习笔记-第一讲_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习笔记-第二讲-初识SLAM_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习笔记- ...

  6. 视觉SLAM十四讲学习笔记-第七讲-视觉里程计-特征点法和特征提取和匹配实践

    专栏系列文章如下: 视觉SLAM十四讲学习笔记-第一讲_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习笔记-第二讲-初识SLAM_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习 ...

  7. 孙鑫VC学习系列教程

    教程简介 1.循序渐进 从Win32SDK编程开始讲解,帮助大家理解掌握Windows编程的核心 -- 消息循环机制. 2.通俗易懂 编程语言枯燥难懂,然而通过孙鑫老师形象化的讲解,Windows和M ...

  8. 视觉SALM十四讲学习笔记——第七讲 视觉里程计(1)

    视觉里程计这一部分的第一个主要内容是ORB特征点的提取与匹配.这里主要关注两个内容: (1)特征点的匹配方法及代码实现 (2)ORB特征点的BRIEF描述子如何实现旋转不变性及在示例代码中的体现 1. ...

  9. Apollo星火计划学习笔记——第七讲自动驾驶规划技术原理1

    文章目录 前言 1. 规划技术功能概述 1.1 自动驾驶系统 1.2 规划的作用 1.3 规划主要功能 1.3.1 路由寻径(Routing) 1.3.2 行为决策 1.3.3 轨迹规划 2. Apo ...

最新文章

  1. vim 编辑器安装 使用
  2. [译]5.1. System Initialization Overview 系统初始化简介
  3. 输入一组整数,0结束输入,之后输出输入的最大的和最小的整数.【思路】
  4. c语言节点有指针域数据域,学习心得:链表的操作(C语言实现)
  5. 【UGV】32版UGV原理图
  6. ubuntu下配置bind9为局域网的DNS服务器
  7. 设计模式--6大原则--单一职责原则
  8. 你必须要知道的架构知识~第二章 代码是否面向对象,要看你的继承怎么用
  9. 如何用 Redis 做实时订阅推送的?
  10. pyqt5获取显示器的分辨率
  11. 【MySQL部署与安装】
  12. [dfs] 洛谷 P2535 收集资源
  13. 很酷的CSS3仿Facebook登录表单
  14. 如何查看硬盘对应的主板接口属性
  15. android小米开源代码
  16. 《Objective-C基础教程》学习笔记第九-十章
  17. 随心测试_Python Se_003操作浏览器对象
  18. 帕斯卡算术机——数学天才的十余年匠心
  19. 塞拉菲娜创始人 - 木子
  20. 华为OD机试 - 预订酒店(Java JS Python)

热门文章

  1. ug10许可证错误一8_UG10.0制图模板无法打开内部错误,UG软件要多次才能打开延迟启动...
  2. 杰理之AUX 模式使用 AUX1 或者 AUX2 通道时,程序会复位问题【篇】
  3. 家庭条件不好的90后,刚刚毕业,该如何存钱买房?
  4. Qt中文翻译(官方文档,界面,工具等)集锦
  5. 关于HC-05蓝牙模块部分命令不可用的问题
  6. RAD Studio 10.3.x RIO 常规快捷键操作
  7. 替代AG9300|替代NCS8823|CS5260 Type-C转VGA视频转换方案
  8. phpmyadmin更新php,phpmyadmin 修改记录(不断更新)_PHP教程
  9. java填充excel表格中_填充导出Java导出excel表格
  10. sopc设计一个液晶模块