转自http://www.cn-doc.com/_soft_visual_c_tech_doc/2005_08_18_23/20050818230400236_5.htm
类的继承图表
cobject
ccmdtarget
cwnd //由cwnd派生,是一个窗口类
cdialog
对话框分为模态对话框和非模态的对话框
cdialog::domodal
//virtual int domodal()
调用domodal()创建一个模态的对话框
它的返回值是做为cdialog::enddailog成员函数的参数,这个参数用来关闭对话框
cdialog::enddailog
//用来关闭模态的对话框
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,则对话框的父窗口将被设置为主应用程序窗口
模态对话框的显示不用调用showwindow
而非模态的对话框在调用create创建完对话框之后,需要调用showwindow显示对话框//showwindow(sw_show)
caution:
对于模态的对话框,在模态的对话框显示时,应用程序是暂停执行的,所以模态的对话框对象可以
是局部对象,不会在模态的对话框显示之前析构。
而对于非模态的对话框,应用程序不会暂停执行,所以非模态对话框的对象不能是局部对象,非模态的
对话框对象有两种定义方法:
1:定义对话框成员变量
2:在堆上分配内存,在堆上分配的内存和我们整个应用程序的生命周期是一样的,可以如下定义:
ctestdlg *pdlg=new ctestdlg(); //注意内存看见的回收,防止memory leak
caution:
对于模态的对话框,当我们点击ok或者cancel按钮时这个对话框窗口是被销毁了的
对于非模态的对话框,这个对话框窗口并没有被销毁,只不过是隐藏了,当我们点击ok时,由基类的
虚函数onok()响应
cdialog::onok
//virtual void onok();
//如果你在一个非模态的对话框中实现了一个ok button,你必须重载onok成员函数,在它内部调用
//destroywindow,不要调用基类的成员函数,因为它调用的是enddialog,which makes the dialog
//box invisible but does not destroy it.
cbutton::create
// BOOL Create( LPCTSTR lpszCaption, DWORD
dwStyle, const RECT& rect, CWnd*
pParentWnd, UINT nID );
//创建button
//按钮也是子窗口,如果dwstyle中不包含ws_visible,则在创建完button后,继续调用showwindow()显示
//按钮
cwnd和任何由cwnd类派生出来的窗口类对象,内部都有一个成员变量m_hwnd保存和这个对象相关联的窗口的
句柄,没有窗口和它关联时,m_hwnd的值为null
静态的文本框也是一个窗口,要获取静态文本框的文本,可以使用函数
cwnd::getwindowtext
设置文本使用
cwnd::setwindowtext
cwnd::getwindowtext
//int getwindowtext( lptstr lpszstringbuf, int nmaxcount )const;
//void getwindowtext( cstring& rstring ) const;
cwnd::setwindowtext
// void setwindowtext( lptstr lpszstring)
对于静态的文本框是不能接收通告消息的,如果让它接收通告消息,需要把它的属性的style的"notify"项选上
atoi函数
int atoi( const char *string) //将数值字符,转化为整形数值
char* _itoa( int value, char *string, int radix); //convert an
integer to a string
//string 指向结果
//radix 2-36数值的*进制
访问控件的方式
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指示接收的数值字符是否是有符号的
cwnd::setdlgitemint
//void setdlgitemint( int nid, uint nvalue, bool bsigned = true );
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等
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来初始化一个对话框控件,或者从对话框获得数据
cwnd::updatedata
//bool updatdata( bool bsaveandvalidate = true )
//call the member function to initialize data in a dialog box, or to
retrieve and validate
//dialog data
//flag that indicates whether dialog box is being initialized (false) or
data is being retrieve
//(true)
//the framework automatically calls updatedata with bsaveandvalidate set
to false when a modal
//dialog box is created in the default implementation of
cdialog::oninitdialog
在控件关联的成员变量设置最大最小值后,dodataexchange函数中会增加如下几条语句
void
ctestdlg::dodataexchange(cdataexchange* pdx)
{
cdialog::dodataexchange(pdx);
//{{afx_data_map(ctestdlg)
ddx_text(pdx, idc_edit1,
m_num1); //ddx :
dialog data exchange
1 ddv_minmaxint(pdx, m_num1, 0,
100); //ddv : dialog data
validate
ddx_text(pdx, idc_edit2, m_num2);
2 ddv_minmaxint(pdx, m_num2, 0,
100); //ddv_函数也有很多,同ddx_函数一样
ddx_text(pdx, idc_edit3, m_num3);
//}}afx_data_map
}
获取文本的消息:wm_gettext
an application sends a wm_gettext message to copy the text that
corresponds to a window into a
buffer provided by the caller.
to send this message,call the sendmessage function with the
following parameters.
sendmessage{
(hwnd)
hwnd,
//handle to destination window
wm_gettext,
//message to send
(wparam)
wparam, //number of the
character to copy
(lparam)
lparam //text
buffer
}
设置文本的时候使用消息
wm_settext
sendmessage{
(hwnd)
hwnd,
//handle to destination window
wm_settext,
//message to send
(wparam)
wparam, //not used;must
be zero
(lparam)
lparam
//window-text string (lpctstr)
}
给对话框的子控件发送消息
cwnd::senddlgmessage
lresult senddlgitemmessage( int nid, uint message, wparam wparam=0,
lparam lparam = 0)
//等价于我们现调用getdlgitem再调用sendmessage
编辑框消息 em_getsel
//the em_getsel message retrieves the starting and ending character
positions of the current
//selection in an edit control. you can send this message to either an
edit control or a rich
//edit control
sendmessage{
(hwnd)
hwnd,
//handle to destination window
wm_gettext,
//message to
send
(wparam) wparam,
//starting position (lpdword)
(lparam)
lparam
//ending position
(lpdword)
}
em_setsel设置复选的开始位置和结束位置
sendmessage{
(hwnd)
hwnd,
//handle to destination window
wm_settext,
//message to
send
(wparam)
wparam, //starting
position
(lparam)
lparam
//ending position
}
//if the start is 0 and the end is -1, all the text in the edit control
is selected.
//if the start is -1,any current selection is deselected
设置窗口的焦点 cwnd::setfocus
cwnd* setfocus();
总结:
对话框控件访问七种方式
1、getdlgitem()->get(set)windowtext()
//常用
2、getdlgitemtext()/setdlgitemtext()
3、getdlgitemint()/setdlgitemint()
4、将控件和整型变量相关联
//常用
5、将控件和控件变量相关联
//常用
6、sendmessage()
//不常用
7、senddlgitemmessage()
//不常用
对话框的收缩与扩展
crect::isrectempty
//determines whether crect is empty.crect is empty if the width
and/or height are 0;
crect::isrectnull
//determines whether the top, bottom, left,and right member
variables are all equal to 0.
cwnd::getwindowrect
void getwindowrect( lprect lprect) const;
//获取窗口矩形区域的大小
cwnd::setwindowpos
//bool setwindowpos( const cwnd* pwndinsertafter, int x,int y, int
cx, int cy, uint nflags);
setwindowpos和deferwindowpos用来重排z-order
//应用程序通过设置ws_ex_topmost风格创建最顶层窗口。
//应用程序可用函数bringwindowtotop把一个窗口放置到z次序的顶部。
兄弟窗口
共享同一个父窗口的多个子窗口叫兄弟窗口。
活动窗口
活动窗口是应用程序的顶层窗口
应用程序则调用函数setactivewindow来激活一个顶层窗口
前台窗口和后台窗口
在windows系统中,每一个进程可运行多个线程,每个线程都能创建窗口。创建正在使用窗口的线程
称之为前台线程,这个窗口就称之为前台窗口。所有其它的线程都是后台线程,由后台线程所创建的
窗口叫后台窗口。
用户通过单击一个窗口、使用alt+tab或alt+esc组合键来设置前台窗口,应用程序则用函数
setforegroundwindow设置前台窗口。如果新的前台窗口是一个顶层窗口,那么windows系统就激活它,
换句话说,windows系统激活相应的顶层窗口。
setwindowpos???
setwindowlong函数
//the setwindowlong function changes an attribute of the specified
window
//setwindowlong函数可以改变指定窗口的属性
long setwindowlong
{
hwnd
hwnd,
// handle to window
int
nindex, //
offset of value to set
long dwnewlong //
new value
}
当
nindex=gwl_wndproc 可以sets a new
address for the window procedure
此时可以把dwnewlong设置成新的窗口过程的地址。
函数的返回值:
if the function succeeds, the return value is the previous
value of the specified 32-bit integer
if the function fails , the return value is zero
当
nindex=gwl_wndproc ,它的返回值就是以前的窗口过程的地址
当对话框上的子控件全部创建完毕,对话框将要显示时发送消息:wm_initdialog
//sent to a dialog box before the dialog box is displayed
子控件的创建时间在对话框创建之后,对话框将要显示之前
窗口过程函数的写法:
lresult callback windowproc{
hwnd hwnd,
//handle to window
uint umsg,
//message identifier
wparam wparam, //first message
parameter
lparam lparam //second message
parameter
}
当处理的是wm_char消息时,wparam表示字符的ascii码
caution!
窗口过程函数是一个全局函数
全局的setfocus函数
hwnd setfocus(
hwnd
hwnd //handle to window
);
全局的getnextwindow函数:
hwnd getnextwindow(
hwnd
hwnd, //handle to current window
uint
ucmd // direction
);
//当
ucmd=gw_hwndnext 当前窗口的下一个窗口
//当
ucmd=gw_hwndprev 当前窗口的上一个窗口
编辑框的style如果如果没有复选multiline属性,则编辑框无法接受回车符发送的消息
取消multiline属性是在 02:29:10 写onok函数时
获取窗口句柄的getwindow全局函数
hwnd getwindow(
hwnd hwnd, // handle to
original window
uint ucmd //
relationship
getnextdlgtabitem函数
//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
);
cwnd::getnextwindow
cwnd* getnextwindow( uint nflag = gw_hwndnext )const;//具有缺省的方向gw_hwndnext
获取当前具有输入焦点的窗口的指针的函数:
cwnd::getfocus
cwnd::getwindow
cwnd* getwindow( uint ncmd) const;
cwnd::getnextdlgtabitem
cwnd* getnextdlgtabitem( cwnd* pwndctrl, bool bprevious = false) const;
//函数寻找具有ws_tabstop style的control,循环依次调用
菜单项
layout->taborder显示顺序
一、 简单的逃跑按钮
//注意下列方法,定义一个类为了捕获鼠标移动点的方便
1,创建一个基于对话框的MFC
AppWizard工程
2,在View窗口点右键,添加一个自定义的类(或者用Classwizard工具添加),基类为CButton
class CWeiXinBtn :
public CButton
3,给CWeiXinBtn类添加成员变量CWeiXinBtn* m_pBtn;
4,给对话框添加俩按钮,每个按钮都关联一个CWeiXinBtn的变量
5,在OnInitDialog添加