1 创建对话框
①模式对话框
CTestDialog dlg;
dlg.DoModal();
②非模式对话框
CTestDialog dlg;
dlg.Create(IDD_XXX, this);
dlg.ShowWindow(SM_SHOW);
NOTE: 如果按以上写法创建非模式对话框,那么不会出现,因为dlg对象是局部变量,超出所在函数作用域后会发现析构,解决办法1° 把dlg写成类的成员函数 2°如下所示
CTestDialog *pDlg = new CTestDialog(); //在堆上分配内存
pDlg->Create(IDD_XXX, this);
pDlg->ShowWindow(SM_SHOW);
这样写能解决问题,但是在堆上分配的内存由于没有delete,所以该内存在程序运行的整个阶段都不能释放。
补充: 内存分配的一点知识
内存分配方式有三种: (1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。 (2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 (3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
2 关于静态文本
也就是起显示作用的标签,ID号都为IDC_STATIC,而且属性里默认是不能接收鼠标点击(通告事件)的,如果要使点击可用,则先改ID 再勾选 通知 或 NOTIFY。
3 访问控件
① CWnd::GetDlgItem
CWnd*GetDlgItem(intnID)const;
void CWnd::GetDlgItem( intnID, HWND*phWnd) const;
②CWnd::GetWindowText
int GetWindowText(LPTSTR lpszStringBuf, int nMaxCount)const;
void GetWindowText(CString& rString)const;
③CWnd::GetDlgItemText
int GetDlgItemText(int nID,LPTSTR lpStr,int nMaxCount)const;
int GetDlgItemText( int nID, CString & rString) const;
NOTE: ③ == ① + ②
eg. GetDlgItemText(IDD_XXX, str) == GetDlgItem(IDD_XXX)->GetWindowText(str);
④给控件添加一个相关联的成员变量(类向导)
UpdateData(TRUE);// 控件值-->变量
m_nNumber1 = m_nNumber2 + m_nNumber3;
UpdateData(FALSE);//变量-->控件
⑤CWnd::GetDlgItemInt
UINT GetDlgItemInt(int nID, BOOL*lpTrans=NULL,BOOL bSigned=TRUE)const;
para: bSigned == TRUE 时,可以进行取有符号整数
4 关于对话框收缩效果
void CTest::OnTest()
{
// TODO: Add your control notification handler code here
CString str;
static CRect rectLarge;
static CRect rectSmall;
static CRect rectNew;
if (rectLarge.IsRectNull())
{
GetWindowRect(&rectLarge);
GetDlgItem(IDC_SEPRATOR)->GetWindowRect(&rectSmall);
rectNew.left = rectLarge.left;
rectNew.top = rectLarge.top;
rectNew.right = rectSmall.right;
rectNew.bottom = rectSmall.bottom;
}
if (GetDlgItemText(IDC_TEST, str), str == "收缩<<")
{
SetDlgItemText(IDC_TEST, "扩展>>");
SetWindowPos(NULL, 0, 0, rectNew.Width(), rectNew.Height() , SWP_NOMOVE | SWP_NOZORDER);
}
else
{
SetDlgItemText(IDC_TEST, "收缩<<");
SetWindowPos(NULL, 0, 0, rectLarge.Width(), rectLarge.Height() , SWP_NOMOVE | SWP_NOZORDER);
}
}
①CRect::IsRectNull
BOOL IsRectNull() const;
返回值:
如果CRect的上、左、下和右边的值都等于0,则返回非零值;否则返回0。
说明:
此函数用来确定CRect的上、左、下和右边的值是否都等于0。与IsRectEmpty不同,IsRectEmpty用来确定矩形是否为空。
②
CRect::IsRectEmpty
BOOL IsRectEmpty() const;
返回值:
如果CRect是空的则返回非零值;否则,如果CRect不是空的则返回0。
说明:
此函数用来确定CRect是否是空的。如果一个矩形的宽度和/或高度是0或负值,则称这个矩形为空的。与IsRectNull不同,IsRectNull用来确定是否矩形的所有坐标都是零。
注意:这个矩形必须是符合规范的,否则此函数将失败。你可以在调用此函数之前,调用NormalizeRect来使矩形规范化。
③CRect::SetRectEmpty
void SetRectEmpty();此函数通过将CRect的所有坐标设置为零来使CRect成为一个空矩形。
④CWnd::SetDlgItemText //设定某一控件的值
void SetDlgItemText(intnID,LPCTSTRlpszString);
eg. SetDlgItemText(IDD_XXX, str);
⑤CWnd::SetWindowPos //改变窗口大小 位置 Z次序
BOOL SetWindowPos(const CWnd*pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);
para: pWndInsertAfter表示一个CWnd对象指针,该窗口放在此指针对应的窗口上, x : 窗口左上角的横坐标, y:窗口坐上角纵坐标
cx:该窗口宽度 cy:该窗口的长度 , cy cy可用一个矩形的宽度 长度传递
eg.SetWindowPos(NULL, 0, 0, rectNew.Width(), rectNew.Height() , SWP_NOMOVE | SWP_NOZORDER);
⑥GetWindowRect //获取窗口矩形区域
CWnd::GetWindowRect
void GetWindowRect(LPRECT lpRect)const;
eg.
CRect rect;
GetDlgItem(IDC_XXX)->GetWindowRect(&rect);
5 通过消息读取/赋给控件值
①WM_GETTEXT
SendMessage( (HWND)hWnd, // handle to destination window
WM_GETTEXT, // message to send
(WPARAM)wParam, // number of characters to copy
(LPARAM)lParam// text buffer
);
eg.
::SendMessage(GetDlgItem(IDC_XXX)->m_hWnd, WM_GETTEXT, 10, (LPARAM)buffer); //WIN32 API
or ::SendMessage(m_edit1.m_hWnd, WM_GETTEXT, 10, (LPARAM)buffer); //WIN32 API
or GetDlgItem(IDC_XXX)->SendMessage(WM_GETTEXT, 10, (LPARAM)buffer);
or m_edit.SendMessage(WM_GETTEXT, 10, (LPARAM)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)
);
用法与①类似,但是第三个参数必须没0.
③SendDlgItemMessage
CWnd::SendDlgItemMessage
LRESULT SendDlgItemMessage(int nID,UINTmessage,WPARAMwParam=0,LPARAM lParam=0);
相当于GetDlgItem + SendMessage, 详见MSDN
6 CWnd::GetDlgItem
很重要的一个函数,在当前窗口上可以获取根据控件ID获取控件指针
CWnd*GetDlgItem(intnID)const;
void CWnd::GetDlgItem( int nID, HWND* phWnd) const;
7 图钉置顶效果(总在最前)
通过改变Z次序来实现, 见练习工程39
eg.
void CMy39Dlg::OnButton1()
{
CString str;
if (GetDlgItemText(IDC_BUTTON1, str), str == "置顶")
{
SetDlgItemText(IDC_BUTTON1, "取消置顶");
SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
}
else
{
SetDlgIt?emText(IDC_BUTTON1, "置顶");
SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
}
①HWND SetFocus( HWND hWnd // handle to window
); //WIN32 API
②HWND GetNext?Window( HWND hWnd,// handle to current window
UINT wCmd// direction
); //WIN32 API
③HWND GetNextDlgTabItem( HWND hDlg,// handle to dialog box
HWND hCtl,// handle to known control
BOOL bPrevious// direction flag
); //win32 API
NOTE:按回车键以此移动焦点。 利用Tab键的顺序来使控件依次获得焦点,代码写在缺省(Default)按钮的点击事件里,把该按钮里的基类构造函数的代码屏蔽,在里面写 GetNextDlgTabItem(GetFocus())->SetFocus(); 功能:先取得焦点在哪个控件上,然后取得下一个Tab键顺序控件,再设置焦点。 或者 新添加一个按钮来把代码写在里面。