初学者对话框应用程序指南 - 第二部分






4.85/5 (32投票s)
2000年6月22日

478726

10443
一步一步的教程,展示如何使用MFC创建你的第一个Windows程序。
引言
对话框是Windows程序用来显示信息和接收用户输入的主要方法之一。因此,在本教程中,我们将使用一个基于对话框的应用程序来收集用户的某些信息。在实际项目中,您将在程序中的其他地方使用此信息,或者它将存储在数据库中。但对于本教程,我们只会在消息框中显示信息。
在这个项目中,用户必须提供姓名,并选择他们最喜欢的操作系统和编程语言。用户选择他们最喜欢的编程技术,然后通过单击提交按钮来提交信息。
信息将显示在消息框中,如下所示
创建新项目和设计对话框
创建一个名为Dialog2的新基于对话框的应用程序项目,在每个步骤中接受默认设置,就像我们在上一个教程中所做的那样。
删除取消按钮和文本(TODO: Place dialog controls here)
,并将确定按钮的Caption更改为Close
。
将一个按钮、一个组合框、两个编辑框控件、两个列表框控件、六个静态文本控件和一个分组框拖放到对话框中,并按如下所示排列控件。
将四个单选按钮放在第一个分组框内。确保按顺序一个接一个地放置单选按钮,并且不要在它们之间放置任何其他控件。
将三个复选框放在第二个分组框内,如下所示
自定义控件属性
按照如下所示更改每个控件的Caption。有关更改每个控件的ID和Caption的完整详细信息,请参阅基于对话框的应用程序入门指南 - 第一部分(上一个教程)。
对于新的分组框、单选按钮和复选框控件,更改标题和ID的过程与其他控件类似(右键单击控件,然后从上下文菜单中选择属性)。
在第一个编辑框控件的编辑属性中,将ID更改为IDC_FIRSTNAME
,将第二个编辑框控件的ID更改为IDC_LASTNAME
。
在组合框属性中将ID更改为IDC_TITLE
。在组合框属性中点击数据,并按如下所示填充数据
在样式选项卡上,将组合框的类型
更改为下拉列表,以阻止用户添加新标题。将鼠标悬停在组合框按钮上,然后单击。会出现另一个矩形。使用此矩形指定打开的组合框列表的大小。
对于对话框左侧的列表框,将ID更改为IDC_PROG_TECH
,对于右侧的列表框,将ID更改为IDC_YOUR_FAVOURITE_TECH
。
在带单选按钮的分组框的Properties中勾选Tab Stop选项(指定用户可以使用TAB键移动到此控件)。
将标题为Windows 95/98的第一个单选按钮的Properties ID更改为IDC_WIN98
,并勾选Group选项(指定组的第一个控件)。
请确保在对话框中放置的最后一个单选按钮之后放置的第一个控件的属性中勾选Group选项。这将隐式将前一个控件(最后一个单选按钮)标记为组中的最后一个。
将Windows NT/2000单选按钮的ID更改为IDC_WINNT
。将Unix的ID更改为IDC_UNIX
,将Linux的ID更改为IDC_LINUX
。
对于第二个分组框,将标题为Java的复选框的ID更改为IDC_JAVA
。将Visual Basic 复选框的ID更改为IDC_VISUAL_BASIC
,将Visual CPP 复选框的ID更改为IDC_VISUAL_CPP
。
将提交按钮的ID更改为IDC_SUBMIT
,将标题为>>的按钮的ID更改为IDC_SELECT
,将<<按钮的ID更改为IDC_DESELECT
。
为控件分配成员变量
按Ctrl + W启动类向导,或从View菜单中选择ClassWizard。选择Member Variables选项卡。在Class name组合框中选择对话框类;选择CDialog2Dlg。
将类型为CString
的m_strFirstName
分配给IDC_FIRSTNAME
,将类型为CString
的m_strLastName
分配给IDC_LASTNAME
,将类型为int
的m_nTitle
分配给IDC_TITLE
。
将类型为BOOL
的m_bJava
分配给IDC_JAVA
,将类型为BOOL
的m_bVisualBasic
分配给IDC_VISUAL_BASIC
,将类型为BOOL
的m_bVisualCpp
分配给IDC_VISUAL_CPP
。
将类型为int
的m_Win98
分配给IDC_WIN98
。
您会注意到,我们只为一个单选按钮分配了一个变量。这是因为单选按钮是成组工作的。因此,我们可以通过第一个单选按钮访问其余的单选按钮。每个单选按钮代表一组互斥选项中的一个。当单击单选按钮时,它会选中自身,并取消选中组中的其他单选按钮。当然,前提是单选按钮属性的样式选项卡中已勾选了Auto选项。Auto选项默认是勾选的。
将类型为CListBox
的m_YourFavouriteTech
分配给IDC_YOUR_FAVOURITE_TECH
,并将类型为CListBox
的m_ProgTech
分配给IDC_PROG_TEACH
。
在类视图选项卡中,右键单击CDialog2Dlg
类并选择Add Member Variable。将出现一个Add Member Variable对话框。添加三个类型为CString
的成员变量:m_strFullInfo
、m_strOpertingSystem
、m_strProgLanguage
。请确保选择Protected Access选项。
初始化变量
现在变量已添加,必须分别初始化它们。类向导已在程序中创建了代码,用于在类构造函数中初始化变量。
但是,对于m_nWin98
和m_nTitle
,这些值初始化为-1,这意味着如果此时构建并运行程序,当对话框首次显示时,将不会选择任何单选按钮,并且标题组合框将显示为空选择。
因此,我们需要将值更改为0,以选择第一个单选按钮和第一个标题。为此,我们需要编辑类向导在CDialog2Dlg
类构造函数中创建的初始化代码。双击类构造函数,构造函数函数将显示如下。注释掉类向导生成的m_nTitle
和m_nWin98
,并在构造函数末尾为变量分配新值,如下所示。
CDialog2Dlg::CDialog2Dlg(CWnd* pParent /*=NULL*/) : CDialog(CDialog2Dlg::IDD, pParent) { //{{AFX_DATA_INIT(CDialog2Dlg) m_strFirstName = _T(""); m_strLastName = _T(""); m_bJava = FALSE; //m_nTitle = -1; m_bVisualBasic = FALSE; m_bVisualCpp = FALSE; //m_nWin98 = -1; //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent // DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_nWin98 = 0; m_nTitle = 0; }
添加成员函数
右键单击CDialog2Dlg
类,并为Function Type添加成员函数。
输入void
,对于Function Declaration,键入PopulateProgTech()
。请确保在Access中选择Public选项,如下所示。
我们将使用此函数来填充编程技术列表框。
键入以下代码
void CDialog2Dlg::PopulateProgTech() { //Populate Programming Technologies List Box m_Prog_Tech.AddString("MFC"); m_Prog_Tech.AddString("COM/DCOM"); m_Prog_Tech.AddString("ADO"); m_Prog_Tech.AddString("OLE DB"); m_Prog_Tech.AddString("ASP"); m_Prog_Tech.AddString("ATL"); }
请记住,我们在上一个教程中使用了AddString()
,它是CListBox
的成员函数,用于向列表框添加新文本。
双击CDialog2Dlg
类中的OnInitDialog()
函数,并在return
语句上方调用PopulateProgTech()
成员函数,如下所示。
BOOL CDialog2Dlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here //Populate Programming Technologies List Box PopulateProgTech(); return TRUE; // return TRUE unless you set the focus to a control }
打开ClassWizard,选择Message Maps选项卡。
在Class name中,选择CDialog2Dlg
,在Object IDs中选择IDC_SELECT
,然后从Messages list中选择BN_CLICKED
,单击Add Function。单击OK,然后单击Edit Code。将以下代码添加到OnSelect()
函数中。
void CDialog2Dlg::OnSelect() { // TODO: Add your control notification handler code here //Get the index of the selected item int nSelectted=m_ProgTech.GetCurSel(); if (nSelectted != LB_ERR) //Check for Selection { CString Sel; //Get the Selectted Text m_ProgTech.GetText(nSelectted,Sel); //Add string to list to Favourite Technology m_YourFavouriteTech.AddString(Sel); //Delete the Selectted item from the list of Techologies m_ProgTech.DeleteString(nSelectted); } }
假设您已从技术列表框中选择了一个项目,则单击>>按钮会将选定的项目传输到您最喜欢的技术列表框。OnSelect()
函数首先检查选择。将选定项目的文本复制到局部变量Sel
。将此文本添加到您最喜欢的技术列表框,然后从技术列表框中删除选定的项目。
双击>>按钮。一旦这样做,Add Member Function对话框将打开,如下所示。
接受默认名称OnDeselect()
并键入以下代码。
void CDialog2Dlg::OnDeselect() { // TODO: Add your control notification handler code here //Get the index of the selected item int nSelectted=m_YourFavouriteTech.GetCurSel(); if (nSelectted != LB_ERR) //Check for Selection { CString Sel; //Get the Selectted Text m_YourFavouriteTech.GetText(nSelectted,Sel); //Add the deselectted technology to list to back Technology m_ProgTech.AddString(Sel); //Delete the Selectted item from the list of Favourite Techologies m_YourFavouriteTech.DeleteString(nSelectted); } }
上面的函数将选定的项目从您最喜欢的技术列表框转移回技术列表框(取消选择该项目)。
双击提交按钮。接受新函数OnSubmit()
的默认名称,并添加以下代码。
void CDialog2Dlg::OnSubmit() { // TODO: Add your control notification handler code here CString strTitle; int nReturnValue; m_strProgLanguage="Programming Languages your prefer \n" ; UpdateData(); //Transfer data from controls to variables //Get the text of the selected radio button GetDlgItem(IDC_WIN98+m_nWin98)->GetWindowText(m_strOpertingSystem); //Get the text of the checked Check Boxes if(m_bJava) m_strProgLanguage+="Java\n " ; if(m_bVisualBasic) m_strProgLanguage+="Visual Basic\n " ; if(m_bVisualCpp) m_strProgLanguage+="C++/Visual C++\n " ; //get currently selected text of the Combo Box nReturnValue=GetDlgItemText(IDC_TITLE, strTitle); m_strFullInfo = "You are "+strTitle + " "+m_strFirstName + " "+ m_strLastName; UpdateData(FALSE); //Transfer data from variables to controls CString Sel; m_strSelectedTech=""; //Get number of items in the list box int nCount = m_YourFavouriteTech.GetCount(); if(nCount > 0) //Check for empty list box { for(int i=0; i<nCount; i++) { m_YourFavouriteTech.GetText(i, Sel); m_strSelectedTech+=Sel + "\n"; } } m_strFullInfo=m_strFullInfo+"\n"+ m_strProgLanguage +"\n" + "favourite technology\n "+m_strSelectedTech+ "\nand your favourite operating System is \n" +m_strOpertingSystem; MessageBox(m_strFullInfo); //Show the information in Message Box }
OnSubmit()
收集所有用户信息并将它们放入消息框。
构建并运行您的程序
到目前为止,您已经学会了如何
- 添加、编辑和自定义按钮、编辑框控件、组合框、列表框、分组框、复选框、单选按钮。
- 使用类向导为控件分配成员变量。
- 添加成员变量。
- 添加成员函数。
- 使用项数据,
- 选择项。
- 确定选择了哪个项。
- 获取项信息。
- 处理
CButton
通知。
多互联网搜索引擎
引言
在本教程部分,我们将构建一个简单但非常有用的程序:一个多互联网搜索引擎。实际上,它只是一个程序,使用户能够访问许多互联网搜索引擎,如Altavista、Yahoo等,而无需记住每个搜索引擎的地址。用户只需选择一个搜索引擎,输入他们想查找的内容,然后单击搜索按钮。下面,用户尝试使用Altavista查找有关物理学的一些信息。
创建新项目、设计和自定义对话框
首先创建一个新的基于对话框的应用程序,名为Search_me,就像我们之前所做的那样。
删除取消按钮和文本(TODO: Place dialog controls here)
。将对话框的大小调整到大约300 x 70,将确定按钮的标题更改为Close。
将按钮、编辑框、组合框和两个静态文本控件拖放到对话框中。将静态文本Caption更改为Search Engine和Search for:将组合框的ID更改为IDC_ENGINE
。
在组合框属性中点击数据,并按如下所示填充数据。请记住在每个条目后按Ctrl + Enter。
在样式选项卡上,将组合框的类型更改为下拉列表,以确保用户无法添加新搜索引擎。
将鼠标悬停在组合框按钮上,然后单击。会出现另一个矩形。使用此矩形指定打开的组合框列表的大小。
将编辑框的ID更改为IDC_SEARCHFOR
。
将按钮的Caption更改为Search,ID更改为IDC_SEARCH
。使用类向导为编辑框分配类型为CString
的成员变量m_strSearchFor
,为组合框分配类型为int
的成员变量m_nEngine
。
向CSearch_meDlg
类添加类型为CString
的成员变量m_strSearch
。
按Ctrl + W启动类向导,选择Message Maps选项卡。在Class name中,选择CSearch_meDlg
,在Object IDs中选择IDC_ENGINE
,然后从Messages list中选择BN_CLICKED
。单击Add
函数,接受默认名称OnSearch()
,然后单击Edit Code。然后键入以下代码。
void CSearch_meDlg::OnSearch() { // TODO: Add your control notification handler code here CString strEngine; int nReturnValue; UpdateData(); //Transfer data from controls to variables m_strSearch = m_strSearchFor; //get currently selected text nReturnValue=GetDlgItemText(IDC_ENGINE, strEngine); UpdateData(FALSE); //Transfer data from variables to controls if(nReturnValue>0) //Check for Search engine selection { if(strEngine=="Yahoo") { m_strSearch = "http://search.yahoo.com/search?p=" + m_strSearch; ShellExecute(NULL, "open", m_strSearch, NULL,NULL,SW_SHOWDEFAULT); } else if(strEngine=="Altavista") { m_strSearch = "http://www.altavista.digital.com/cgi-bin/query?" + " pg=q&what=web&fmt=.&q=" + m_strSearch; ShellExecute(NULL, "open", m_strSearch, NULL,NULL,SW_SHOWDEFAULT); } else if(strEngine=="Excite") { m_strSearch = "http://www.excite.com/search.gw?trace=a&search=" +m_strSearch; ShellExecute(NULL, "open", m_strSearch, NULL,NULL,SW_SHOWDEFAULT); } else if(strEngine=="Askjeeves") { m_strSearch = "http://www.askjeeves.com/AskJeeves.asp?ask=" +m_strSearch; ShellExecute(NULL, "open", m_strSearch, NULL,NULL,SW_SHOWDEFAULT); } } }
我们使用了ShellExecute()
函数来打开Internet Explorer或其他任何默认的Internet客户端程序。有关ShellExecute()
的更多信息,请参阅MSDN Library文件。
编辑CSearch_meDlg
类的构造函数,并将m_nEngine
的值从-1更改为0,就像我们之前做的那样,以确保当Search_me对话框首次显示时,Altavista将在组合框中被选中。
构建并运行您的程序
如果您喜欢这个程序的想法,您可以为Search_me程序添加更多搜索引擎。添加新搜索引擎的最佳方法是使用Internet Explorer或任何Internet客户端访问您想添加的特定搜索引擎,进行简单的搜索。然后从Explorer的组合框复制地址,这是一个附加到URL后面的查询字符串(以名称/值对形式传递给服务器的信息),后面跟着一个问号“?”。使用您刚刚复制到程序中的Explorer的组合框中的地址。
例如,如果您使用excite搜索引擎搜索Books,结果页面将具有地址http://search.excite.com/search.gw?search=Physics,这是一个URL( http://search.excite.com/search.gw)、“?”和查询字符串(search=Books)。您需要做的就是将Physics替换为m_strSearch
。
希望您觉得这个教程很有趣。
延伸阅读
- 有关MFC消息处理的更深入的介绍,请参阅Daniel Kopitchinski的文章Windows消息处理文章。
- 有关创建SDI应用程序的分步教程,请参阅Daniel Kopitchinski的创建您的第一个Windows应用程序。
- 有关在应用程序中使用标准列表控件所需的所有信息,请参阅Matt Weagle的文章使用列表控件。