现在的位置: 首页 > 综合 > 正文

孙鑫VC++讲座笔记-(7)对话框

2018年02月12日 ⁄ 综合 ⁄ 共 6110字 ⁄ 字号 评论关闭

孙鑫VC++讲座笔记-(7)对话框
模态对话框和非模态对话框
A modal dialog box must be closed by the user before the application continues. A modeless dialog box allows the user to display the dialog box and return to another task without canceling or removing the dialog box.

创建模态对话框 CDialog::DoModal 返回一个int值,结束这个模态窗口时候,传递这个int值给CDialog::EndDialog(int)。DoModal函数本身有显示的作用,不用show函数
非模态对话框 使用CDialog::Create 创建
{……
CDlgTest dlg;
dlg.Create(IDD_DIALOG1,this);
dlg.ShowWindow(SW_SHOW);]
……
}
dlg是个局部变量,所以这样对话框不会显示,可以将dlg改为一个指针,然后在堆上分配内存如CDlgTest *pdlg = new CDlgTest();(会造成内存泄露)或者将dlg作为一个类的成员变量,或者将dlg声明为static。
在非模态对话框上点击“确定”按钮是将窗口隐藏,而模态对话框则是销毁。这个是由基类的虚函数OnOk函数响应。
CDialog::OnOK
virtual void OnOK( );
If you implement the OK button in a modeless dialog box, you must override the OnOK member function and call DestroyWindow from within it. Don’t call the base-class member function, because it calls EndDialog, which makes the dialog box invisible but does not destroy it.

所以必须调用DestroyWindow函数。

或得对话框上某一控件,用CWnd::GetDlgItem
Return Value

A pointer to the given control or child window. If no control with the integer ID given by the nID parameter exists, the value is NULL.

获取窗口上文字CWnd::GetWindowText,设置用SetWindowText.要使静态文本框可以接受消息,必须将它stytles中的notify勾选。

2006-1-18 09:19上午
今天刚装了个插件,Visual.Assist,很好用,代码提示和eclipse一样好。
好,开始。
给控件关联变量,在程序中是在 //{{AFX_DATA(???)宏之间插入几个变量。构造函数中宏//{{AFX_DATA_INIT(CD??)后初始化。
怎么关联呢?看代码 ::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgTest)
DDX_Text(pDX, IDC_EDIT1, m_num1);
DDX_Text(pDX, IDC_EDIT2, m_num2);
DDX_Text(pDX, IDC_EDIT3, m_num3);
//}}AFX_DATA_MAP
}
对了,是在DoDataExchange中关联的。不同的控件有不同的DDX_*函数。DoDataExchange不会主动被调用,调用UpdateData()时候才被调用。

要使关联的变量获取控件的数据,需要先UpdateData()。
UpdateData(FALSE)说明对话框正在被初始化,控件可以接受到输入的值或者将关联变量的值赋到控件上。
UpdateData(TRUE)说明正在接受数据,将控件中的数据赋给关联变量。
当一个模态对话框创建的时候,自动调用UpdateData(FALSE)。
也可以将一个空间变量和一个空间直接关联起来。

WM_GETTEXT消息用来要求获取文本,可以如下使用
To send this message, call the SendMessage function with the following parameters.
<API>
SendMessage(
(HWND) hWnd, // handle to destination window
WM_GETTEXT, // message to send
(WPARAM) wParam, // number of characters to copy
(LPARAM) lParam // text buffer char*可以被强制转换为LPARAM
);

CWnd::LRESULT SendMessage(
UINT message,
WPARAM wParam = 0,
LPARAM lParam = 0 );

几种用法
int n1,n2,n3;
char a1[10],a2[10],a3[10];
::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)a1);
GetDlgItem(IDC_EDIT2)->SendMessage(WM_GETTEXT,10,(LPARAM)a2);
n1 = atoi(a1);
n2 = atoi(a2);
n3 = n1+n2;
itoa(n3,a3,10);
m_edit3.SendMessage(WM_SETTEXT,0,(LPARAM)a3);
也可以直接给对话框的子控件发送消息
CWnd::SendDlgItemMessage
This method sends a message to a control.

The SendDlgItemMessage method does not return until the message has been processed.

Using SendDlgItemMessage is identical to obtaining a CWnd* to the given control and calling the SendMessage method.

LRESULT SendDlgItemMessage(
int nID,
UINT message,
WPARAM wParam = 0,
LPARAM lParam = 0 );
Parameters
nID
Specifies the identifier of the dialog control that will receive the message.
message
Specifies the message to be sent.
wParam
Specifies additional message-dependent information.
lParam
Specifies additional message-dependent information.
实际上这个函数相当于先调用GetDlgItem()函数再调用SendMessage(),它只是把这两个函数封装了一下。
SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,10,a1);

一个消息 获取编辑框上选择了的文本(即经过拖拉背景色变了的部分),要想显示复选的部分,它必须获得当前焦点,用函数
CWnd::SetFocus().
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.

To send this message, call the SendMessage function with the following parameters.

SendMessage(
(HWND) hWnd, // handle to destination window
EM_GETSEL, // message to send
(WPARAM) wParam, // starting position (LPDWORD)
(LPARAM) lParam // ending position (LPDWORD)
);
发生EM_SETSEL消息的时候,如果开始位置为0,结束位置为-1,那么所有的文字被选择。

总结,对话框控件访问七种方式

1.GetDlgItem()->Get(Set)WindowText()
2.GetDlgItemText()/SetDlgItemText()
3.GetDlgItemInt()/SetDlgItemInt()
4.将控件和整型变量相关联
5.将控件和控件变量相关联
6.SendMessage()
7.SendDlgItemMessage()

对话框的收缩与扩展
要点:获得扩展后窗口大小和收缩后大小调用CWnd::SetWindowPos()。
IsRectNULL()当4点都为0时为真
IsrectEmpth()当宽和高为0时为真。
获得矩形用GetWindowRect();
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(const CWnd* pWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags );

flags: SWP_NOMOVE Retains current position (ignores the x and y parameters).的时候说明保持当前窗口的位置而不移动,所以忽略x和y坐标。
SWP_NOZORDER Retains current ordering (ignores pWndInsertAfter).说明保持当前的z次序。

回车键默认响应的是缺省Button,可以在资源编辑器里设置。
SetWindowLong可以设置窗口的默认窗口过程winProc
LONG SetWindowLong(
HWND hWnd, // handle to window
int nIndex, // offset of value to set
LONG dwNewLong // new value
);
WindowProc
The WindowProc function is an application-defined function that processes messages sent to a window. The WNDPROC type defines a pointer to this callback function. WindowProc is a placeholder for the application-defined function name.

LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);

WM_INITDIALOG消息是在对话框创建完成并且它上的子控件创建完成,马上要显示的时候发送。
WM_CREATE消息发生的时候子控件尚未创造完成。
要使一个编辑框响应回车消息,必须让它支持多行,在资源编辑器里设置。

获得下一个窗口的句柄:HWND GetNextWindow(
HWND hWnd, // handle to current window
UINT wCmd // direction
);
wCmd可取GW_HWNDNEXT和GW_HWNDPREV
另外几个获得窗口句柄的函数
GetWindow
HWND GetWindow(
HWND hWnd, // handle to original window
UINT uCmd // relationship
);
GetNextDlgTabItem
HWND GetNextDlgTabItem(
HWND hDlg, // handle to dialog box
HWND hCtl, // handle to known control
BOOL bPrevious // direction flag
); //bPrevious为false的时候搜索下一个否则搜索上一个

三句代码
// ::SetFocus(::GetNextWindow(hwnd,GW_HWNDNEXT));
// ::SetFocus(::GetWindow(hwnd,GW_HWNDNEXT));
::SetFocus(::GetNextDlgTabItem(GetParent(hwnd),hwnd,FALSE));
GetNextDlgTabItem()会循环查找窗口。
获得当前具有焦点的窗口
CWnd *GetFocus().

缺省的OKButton的ID为IDOK。  

抱歉!评论已关闭.