`
javasalatu
  • 浏览: 723286 次
  • 性别: Icon_minigender_2
  • 来自: 北京
博客专栏
96df99eb-e89d-3228-9c8e-967fc745ec52
程序员的自我经营之道
浏览量:7701
文章分类
社区版块
存档分类
最新评论

第七章:无模式对话框 和 Windows通用对话框类

阅读更多

第七章:无模式对话框 Windows通用对话框类

1[无模式对话框]在它处于激活状态下还允许用户在(同一个应用程序中)其它地方工作。

[通用对话框]则是C++和一组Windows的实用对话框之间的程序设计借口,包括File Open,Page Setup,Color等等,它们都是通过COMDLG32.DLL来实现的。

2,两种发送Windows消息:

CWnd::SendMessage//立刻导致对窗口控制函数的调用

CWnd::PostMessage//将消息放进Windows消息队列。对消息的处理可能被滞后。

具体:

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

//Sends the specified message to this window. The SendMessage member function calls the window procedure directly and does not return until that window procedure has processed the message. This is in contrast to the PostMessage member function, which places the message into the window’s message queue and returns immediately.

2BOOL PostMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );

//Places a message in the window’s message queue and then returns without waiting for the corresponding window to process the message. Messages in a message queue are retrieved by calls to the GetMessage or PeekMessage Windows function.

3,对话框实际上应该属于应用程序的主框架窗口,而不属于视图。(对话框默认弹出特性)

(注:还未领悟,先留着。)

4,对话框窗口的创建和取消完全取决与用户的操作,而对话框对象则将直到应用程序被终止时才会被删除。

(除了主框架窗口之外,对于几乎所有的窗口类型,DestroyWindow函数都不会将C++对象删除掉。所以要注意手动添加删除对话框对象代码)

5Windows 常量WM_USER是用户自定义消息中可以利用的第一个消息ID

#define WM_USER 0x0400

//The WM_USER constant is used by applications to help define private messages, usually of the form WM_USER+X, where X is an integer value.

说明:

1CWnd::PostMessage//发送消息。利用wParam , LPARAM可以向响应消息的处理函数传送附加数据信息。

BOOL PostMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );

2)在WIN32中,用wParam LPARAM参数来传递消息数据是最常用的手段(如:将鼠标的XY坐标压缩进lParam)。而在MFC库中,消息数据可以更多样的类型来传递(如:可以CPoint对象来传递鼠标信息)。

对于用户自定义消息,只能使用wParam LPARAM参数来传递消息附加数据信息。

3)案例说明:

在对话框类中:

#define WM_GOODBYE WM_USER + 5//定义自定义消息

m_pView->PostMessage(WM_GOODBYE, IDOK);//View类发送WM_GOODBYE消息,附加消息IDOK存放在wParam 中。m_pView指向当前View类对象。

View 类对象中

afx_msg LRESULT OnGoodbye(WPARAM wParam, LPARAM lParam);

ON_MESSAGE(WM_GOODBYE, OnGoodbye)

LRESULT CEx07aView::OnGoodbye(WPARAM wParam, LPARAM lParam)

{

return 0L;

}

4)技巧:在对话框类中重载构造函数,参数为CView*指针。再在对话框类中定义一个CView*指针数据成员。这样,如果在View类中通过传入this指针来构造对话框对象的时候,对话框类中CView*指针数据成员可以在带参数为CView*指针重载构造函数里方便获取构造它的View类指针。

6ClassWizard并不支持用户自定义消息的响应,所以当使用用户自定义消息编程的时候,必须自己编写自定义消息的处理代码。(三步,首先是消息响应函数原型声明,其次消息映射,最后是编写消息响应函数代码。这里要注意:用户自定义消息的消息映射一定要加在BEGIN_MESSAGE_MAP(..)~~END_MESSAGE_MAP()之间,//{{AFX_MSG_MAP(CEx07aView)~~ //}}AFX_MSG_MAP注释宏对之外)

7,对于无模式对话框一定要注意不要调用CDialog::OnOk或者CDialog::OnCancel函数,既在无模式对话框类中必须重载这些虚函数;否则当使用ESC键,回车键或者用鼠标单击OK|CANCEL按钮的时候,会激发对应基类函数的调用,进而导致调用Windows EndDialog函数,EndDialog函数只适合于模式对话框。对于无模式对话框,必须调用DestroyWindow函数。

如果需要的话,还可调用Updatedata函数来将数据从对话框控件中传到类数据成员中。

8,Windows通用对话框:

共同特点:都从用户处获得消息,但并不对信息做处理。如:文件对话框只为程序提供路径名,字体对话框只是填充一个描叙字体的结构,并不创建字体。

所有的通用对话框类都从公有基类CCommonDialog派生而来。

COMDLG32中类列表如下:

CColorDialog 允许用户选择或创建颜色

CFileDialog 允许用户打开或者保存一个文件

CFindReplaceDialog 允许用户将一个字符串换成另一个字符串

CPageSetupDialog 允许用户输入页面参数

CFontDialog 允许用户从列出的可用字体中选择一种字体

CPrintDialog 允许用户设置打印机并打印文档

9,注意:在Win32中,不能在标准文件对话框内部动态创建控件。(其它标准对话框中也应该如此吧)

10,嵌套对话框(这些内容熔入EX07B事例中讲解了,不打算重复,强烈建议看看和跟着做做,页码:P135-141。下面只对其中重要的函数做些说明笔记。)

利用MFC,从通用

1CFileDialog::m_ofn

//m_ofn is a structure of type OPENFILENAME. Use this structure to initialize the appearance of a File Open or File Save As dialog box after it is constructed but before it is displayed with the DoModal member function.

2CFileDialog::CFileDialog

CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL );

//bOpenFileDialog

Set to TRUE to construct a File Open dialog box or FALSE to construct a File Save As dialog box.

3CFileDialog::DoModal

//Call this function to display the Windows common file dialog box and allow the user to browse files and directories and enter a filename.

//If you want to initialize the various file dialog-box options by setting members of the m_ofn structure, you should do this before calling DoModal, but after the dialog object is constructed.

//When the user clicks the dialog box’s OK or Cancel buttons, or selects the Close option from the dialog box’s control menu, control is returned to your application. You can then call other member functions to retrieve the settings or information the user inputs into the dialog box.

4CFileDialog::GetPathName

//Call this function to retrieve the full path of the file entered in the dialog box. The path of the filename includes the file’s title plus the entire directory path.

5)事例中注意设置自己创建的子对话框上的组筐控件的IDstc32。这样才保证文件通用对话框嵌入的位置在组筐所在的位置上,否则默认为自己创建的子对话框的同宽度。(stc32应该是与文件通用对话框相关联的,具体是如何关联的哦?)

6)事例中可见到这样的代码(GetParent()->GetDlgItem(IDOK)->SetWindowText("Delete");)来获取文件通用对话框上的控件指针,这里要理解为什么要用GetParent()函数来获得父窗口指针(因为事例中自己所创建的对话框被设置成Child Style。)(Child style,None border,Group box ID=stc32这些设置都是必不可少的,自己可以试着改变这些设置,看看效果印象也就深了)

7)事例中CSpecialFileDialog::OnDelete() 函数中代码(GetParent()->GetDlgItem(0x480)->GetWindowText(m_strFileName);)通过获取文件通用对话框上文件名对应的编辑框的指针调用CWnd::GetWindowText函数来获取编辑框中的文本保存在m_strFileName数据成员中。其中0x480应该是文件通用对话框上文件名对应的编辑框的ID

8)事例中CSpecialFileDialog::OnDelete() 函数中代码(GetParent()->SendMessage(WM_COMMAND,IDCANCEL);)向文件通用对话框发送IDCANCEL消息,该操作引起OnCancel函数的调用终止当前模式对话框同时使得CFileDialog::DoModal函数返回IDCANCEL值。

MSDN

CDialog::OnCancel The default simply terminates a modal dialog box by calling EndDialog and causing DoModal to return IDCANCEL.

9SDK函数:FindFirstFileDeleteFile

//FindFirstFile Searches a directory for a file whose name matches the specified file name on the destination site identified by this object. It examines subdirectory names as well as file names.

//DeleteFile Deletes the given file from the destination site.

10CFile::Remove

A static function deletes the file specified by the path. It will not remove a directory. (注意:用这函数删除的文件是不经过回收站的哦。)

11,在对话框标题栏添加图标:在对话框类OnInitDialog函数中添加如下代码。

HICON hIcon =AfxGetApp()->LoadIcon(ID_MYICON);//ID_MYICON是用资源编辑器创建的图标ID

this->SetIcon(hIcon,TRUE);

this->SetIcon(hIcon,FALSE);注:这里带上this指针目的是为了强调必须使用目的对话框类对象指针调用SetIcon设置图标。

比如在书EX07B事例中,由于CSpecialFileDialog类设置为子窗口类,而且所关联的资源窗口没有Tittle Bar,要在父窗口文件通用对话框Tittle Bar上添加图标,必须获取父窗口文件通用对话框对象指针来调用SetIcon设置图标。

如在书EX07B事例中:在CSpecialFileDialog::OnInitDialog函数中添加如下代码,可设置文件通用对话框标题图标:

HICON hIcon =AfxGetApp()->LoadIcon(ID_MYICON);

GetParent()->SetIcon(hIcon,TRUE);

GetParent()->SetIcon(hIcon,FALSE);

第六章:模式对话框和Windows通用控件

1,对话框也是窗口,它不当可以接受消息,而且还可以被移动和关闭,甚至可以在它的客户区中进行绘图操作。

2,模式对话框在被关闭之前,用户无法在同一应用程序的其它地方进行工作。模式对话框更易于编程。

无模式对话框在它仍保留在屏幕的同时,用户还可以在应用程序的其它窗口进行工作。

3,对话框控件既可以通过CWnd指针来引用,也可以通过资源文件定义的索引值(和#define常量相关联)来引用。对话框控件本身就是一个窗口。控件通过向上级对话框发送消息来响应用户的动作。

利用ClassWizard可以帮助产生CDialog派生类,还可以使对话框类数据成员和对话框控件相联系。

4,在现存在项目中添加模式对话框步骤:

1)用对话框编辑器创建包含各种控件的对话框资源。对话框编辑器会对项目的资源文件更新,使之包含新的对话框资源,并且该项目的resource.h文件也会被更新,以便能够包含新的#define常量。

2)利用ClassWizard创建CDialog派生类,并将它和第一步所创建的资源相连接。

3)利用ClassWizard添加控件消息响应函数,并进行编辑。

4)在其它类中需要使用地方先构造该对话框类对象,再调用DoModal显示模式对话框。

说明:

1)在产生的对话框头文件中包含一个枚举类型常量IDD,用于设置该对话框资源ID。枚举常量IDD的使用减弱了CPP文件对资源ID的依赖。

2)《在其它类中显示模式对话框后,只有当模式对话框退出后,才继续执行该类显示模式对话框代码后的代码。》

5,在组合筐中Data属性页下,添加一条后按CTRL+RETURN来结束(或添加下条item)。(VC6中按?键可以获取相关帮助提示的)。组合框有Simple,Dropdown,Drop List三中风格,可以是Styles中选择。

列表筐中,用户只能用鼠标选择选择一个条目,而且在对话框编辑器中不能输入列表框的初始选择条目。

在静态文本控件中可以内置'&'符号。运行时候,&符号后面的字符下将有一个下划线。用户在按下ALT键后同时按下相应带下划线的字母,则就可以跳转到相应的控件上去。注意同一对话框中跳转字符不能重复。

6,当DoModal被调用后,实际在幕后引起一系列如下的动作:

CDialog::DoModal->CEx06Dialog::OnInitDialog->其它的初始化->CDialog::OnInitDialog->CWnd::UpdateData(FALSE)->CEx06Dialog::DoDataExchange

用户输入数据...

用户单击OK按钮

CEx06Dialog::OnOk->...其它的确认处理...->CDialog::OnOk->CWnd::UpDateData(TURE)->CEx06Dialog::DoDataExchange->CDialog::EndDialog(IDOK)

说明:

1virtual BOOL OnInitDialog( );

//CDialog::OnInitDialog This member function is called in response to the WM_INITDIALOG message. This message is sent to the dialog box during the Create, CreateIndirect, or DoModal calls, which occur immediately before the dialog box is displayed.

//Override this member function if you need to perform special processing when the dialog box is initialized.

2BOOL UpdateData( BOOL bSaveAndValidate = TRUE );

//CWnd::UpdateData Call this member function to initialize data in a dialog box, or to retrieve and validate dialog data.

//bSaveAndValidateFlag that indicates whether dialog box is being initialized (FALSE) or data is being retrieved (TRUE).

//By default UpdateData(TRUE) is called in the default CDialog::OnOK handler and UpdateData(FALSE) is called in the default CDialog::OnInitDialog.

3virtual void DoDataExchange( CDataExchange* pDX );

//CWnd::DoDataExchange Called by the framework to exchange and validate dialog data.

//Never call this function DoDataExchange directly. It is called by the UpdateData member function.

//Call UpdateData to initialize a dialog box’s controls or retrieve data from a dialog box.

4void EndDialog( int nResult );

//CDialog::EndDialog makes the dialog box invisible but does not destroy it.

//Call this member function to terminate a modal dialog box. This member function returns nResult as the return value of DoModalIDOK表示接受对话框数据,IDCANCEL表示取消对话框数据). You must use the EndDialog function to complete processing whenever a modal dialog box is created.

//注意:If you implement the OK button in a modeless dialog box, you must override the OnOK member function and call DestroyWindow from within it.

5)当DoModal函数返回的时候,对话框窗口不再存在。我们可以在堆栈中创建模式对话框对象,这样就可以保证当程序控制转向到C++对话框对象所在的范围之外时,它及时的删除掉。

7,代码解释:

void CEx06aDialog::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CEx06aDialog)

DDX_Text(pDX, IDC_BIO, m_strBio);//

DDX_Radio(pDX, IDC_CAT, m_nCat);

...

DDV_MinMaxInt(pDX, m_nSsn, 0, 999999999);

//}}AFX_DATA_MAP

}

说明:

1DoDataExchangeDDX_(交换)、DDV_(确认)函数都具有双向性。如果调用UpdateData(FALSE)(参数为FALSE),则这些数据就会将与控件相关联(值关联)的数据成员的值传递给对话框中的控件;相反,如果UpDateData(TURE)(参数是TURE),则这些函数会将数据从对话框控件中传递给与之相关联(值关联)的数据成员。

2)这里DDX_Text函数被重载,具体参阅MSDNThe DDX_Text function manages the transfer of int, UINT, long, DWORD, CString, float, or double data between an edit control in a dialog box, form view, or control view and a CString data member of the dialog box, form view, or control view object.

其它DDX_函数参阅MSDN

8,Enter键触发OnOk函数调用:

当用户按下ENTER键后,OS会自动去查找输入焦点落在哪个按钮上,获得焦点的按钮四周将被点线矩形框包围。如果所有的按钮都没获得输入焦点,则OS会自动去寻找程序或资源所指定的默认按钮(默认按钮边框较粗)。如果对话框没有默认按钮,那么即使对话框中没有OK按钮,OnOk函数也会自动被调用。

由于OnOk函数是虚函数,可以重写OnOk函数,将其函数体置空,变可以使使ENTER键无效。

分离OK按钮:改写OK按钮ID,并除掉其默认按钮(Default Button)的设置。

9,p107WIN32程序员:强烈建议看看,下为简要笔记。

对话框控件会向他们父对话框发送WM_COMMAND通告消息。大多数窗口程序处理函数都是通过一个嵌套的switch结构了处理这些通告消息的,而MFC则更直接了当地把这些控件通知消息和其它的Windows消息放在同一个层次上处理。

10Esc键触发OnCancel函数的调用,导致控制从对话框中退出,如果是模式对话框则DoModal的还返回IDCANCEL值。其消除方法同ENTER键。

分享到:
评论

相关推荐

    Windows编程循序渐进(清晰完整版)part2

    第7章 网络通信基础 第8章 密码学算法 第9章 多媒体技术 第10章 数据库技术 第11章 综合实例开发 第三篇 Windows系统程序设计篇 第12章 进程与线程 第13章 内存管理 第14章 进程间通信 第15章 线程同步 第16章 动态...

    Windows编程循序渐进(清晰完整版)part1

    第7章 网络通信基础 第8章 密码学算法 第9章 多媒体技术 第10章 数据库技术 第11章 综合实例开发 第三篇 Windows系统程序设计篇 第12章 进程与线程 第13章 内存管理 第14章 进程间通信 第15章 线程同步 第16章 动态...

    Windows编程循序渐进(清晰完整版)part3

    第7章 网络通信基础 第8章 密码学算法 第9章 多媒体技术 第10章 数据库技术 第11章 综合实例开发 第三篇 Windows系统程序设计篇 第12章 进程与线程 第13章 内存管理 第14章 进程间通信 第15章 线程同步 第16章 动态...

    Windows编程循序渐进(清晰完整版).part2

     第1章 软件开发起步 2 1.1 建立MFC应用程序 2 1.2 分析框架结构 4 1.2.1 框架代码文件的结构 4 1.2.2 应用程序类 5 1.2.3 对话框类 6 1.2.4 添加消息响应 7 第2章 对话框应用程序 9 2.1 模态对话框 9 2.1.1 实例:...

    Windows编程循序渐进(清晰完整版).part3

     第1章 软件开发起步 2 1.1 建立MFC应用程序 2 1.2 分析框架结构 4 1.2.1 框架代码文件的结构 4 1.2.2 应用程序类 5 1.2.3 对话框类 6 1.2.4 添加消息响应 7 第2章 对话框应用程序 9 2.1 模态对话框 9 2.1.1 实例:...

    Windows编程循序渐进(清晰完整版).part1

     第1章 软件开发起步 2 1.1 建立MFC应用程序 2 1.2 分析框架结构 4 1.2.1 框架代码文件的结构 4 1.2.2 应用程序类 5 1.2.3 对话框类 6 1.2.4 添加消息响应 7 第2章 对话框应用程序 9 2.1 模态对话框 9 2.1.1 实例:...

    VISUAL C++MFC扩展编程实例(想学MFC的朋友一定不要错过)

    第7章 对话框和对话条 179 7.1 实例21:动态改变对话框的尺寸 179 7.2 实例22:自定义数据交换并验证 184 7.3 实例23:重载通用文件对话框 187 7.4 实例24:重载通用颜色对话框 190 7.5 实例25:获得目录名 192 7.6 ...

    一份很实用的MFC资料

    第7章 对话框和对话条 179 7.1 实例21:动态改变对话框的尺寸 179 7.2 实例22:自定义数据交换并验证 184 7.3 实例23:重载通用文件对话框 187 7.4 实例24:重载通用颜色对话框 190 7.5 实例25:获得目录名 192 7.6 ...

    Visual C++ MFC扩展编程实例.PDF

    第7章 对话框和对话条 179 7.1 实例21:动态改变对话框的尺寸 179 7.2 实例22:自定义数据交换并验证 184 7.3 实例23:重载通用文件对话框 187 7.4 实例24:重载通用颜色对话框 190 7.5 实例25:获得目录名 192 7.6 ...

    VISUAL C++MFC扩展编程实例

    第7章 对话框和对话条 179 7.1 实例21:动态改变对话框的尺寸 179 7.2 实例22:自定义数据交换并验证 184 7.3 实例23:重载通用文件对话框 187 7.4 实例24:重载通用颜色对话框 190 7.5 实例25:获得目录名 192 7.6 ...

    VISUAL C MFC扩展编程实例与源码

    第7章 对话框和对话条 179 7.1 实例21:动态改变对话框的尺寸 179 7.2 实例22:自定义数据交换并验证 184 7.3 实例23:重载通用文件对话框 187 7.4 实例24:重载通用颜色对话框 190 7.5 实例25:获得目录名 192...

    Visual C++MFC编程实例

    第7章 工具栏和状态栏 120 7.1 例22 使用工具栏编辑器 120 7.2 例23 启用和禁用工具栏按钮 122 7.3 例24 为工具栏按钮添加字 123 7.4 例25 非标准工具栏大小 128 7.5 例26 保持工具栏按钮按下 129 7.6 例27 保持工具...

    Windows编程技术

    第7章 工具栏与状态栏 131 7.1 工具栏 131 7.1.1 编辑工具栏 131 7.1.2 处理工具栏命令 133 7.1.3 工具栏按钮状态 135 7.1.4 自定义工具栏 135 7.2 状态栏 141 7.2.1 默认状态栏 142 7.2.2 操作状态栏 143 7.3 小结 ...

    Windows编程循序渐进.part2

    第7章 网络通信基础 80 7.1 网络模型 80 7.1.1 OSI参考模型 80 7.1.2 TCP/IP参考模型 81 7.2 基础协议 82 7.2.1 IP协议 82 7.2.2 TCP协议 83 7.2.3 UDP协议 84 7.2.4 ICMP协议 85 7.3 套接字编程 85 7.3.1...

    Windows编程循序渐进.part3

    第7章 网络通信基础 80 7.1 网络模型 80 7.1.1 OSI参考模型 80 7.1.2 TCP/IP参考模型 81 7.2 基础协议 82 7.2.1 IP协议 82 7.2.2 TCP协议 83 7.2.3 UDP协议 84 7.2.4 ICMP协议 85 7.3 套接字编程 85 7.3.1...

    Visual C++ MFC编程详解和实例

    第7章 工具栏和状态栏 120 7.1 例22 使用工具栏编辑器 120 7.2 例23 启用和禁用工具栏按钮 122 7.3 例24 为工具栏按钮添加字 123 7.4 例25 非标准工具栏大小 128 7.5 例26 保持工具栏按钮按下 129 7.6 例27 保持工具...

    china-pub的精品MFC教程(超清晰)

    第7章 工具栏和状态栏 120 7.1 例22 使用工具栏编辑器 120 7.2 例23 启用和禁用工具栏按钮 122 7.3 例24 为工具栏按钮添加字 123 7.4 例25 非标准工具栏大小 128 7.5 例26 保持工具栏按钮按下 129 7.6 例27 保持工具...

    VISUAL C++MFC编程实例

    第7章 工具栏和状态栏 120 7.1 例22 使用工具栏编辑器 120 7.2 例23 启用和禁用工具栏按钮 122 7.3 例24 为工具栏按钮添加字 123 7.4 例25 非标准工具栏大小 128 7.5 例26 保持工具栏按钮按下 129 7.6 例27 保持工具...

    Visual C++ MFC编程实例.PDF

    第7章 工具栏和状态栏 120 7.1 例22 使用工具栏编辑器 120 7.2 例23 启用和禁用工具栏按钮 122 7.3 例24 为工具栏按钮添加字 123 7.4 例25 非标准工具栏大小 128 7.5 例26 保持工具栏按钮按下 129 7.6 例27 保持工具...

Global site tag (gtag.js) - Google Analytics