MFC基础知识总结 1.列表视图控件: ClistCtrl类的用法: 1常规操作函数:它们可以完成向列表视图中插入新 条目或新列等操作。 ISubItem-指定条目子索引项 BOOL DeleteAllItems()删除列表控件中所有条目 int InsertColumn(int nCol,const LVCOLUMN * pColum)插入新列 操作成功返回新列索引 nCol-----指定新列索引。 pColum---为LVCOLUMN结构指针,包含将插入的信息。 LVCOLUMN结构 例:m_ListCtrl.InsertColumn( 0, _T( "所有匹配的单词" ), LVCFMT_LEFT, 115 ); int InsertItem(const LVITEM *pItem)调用该函数以 向列表中插入新条目 返回新条目索引值 pItem-------为LVITEM结构,其中包含了将插入的条目信息 列表控制中包含两个非常重要的数据结构LV_ITEM和LV_COLUMN。LV_ITEM用于定义列表控制的一个表项,LV_COLUMN用于定义列表控制的一个表列 例:m_ListCtrl.InsertItem( 0, WordSet.m_Word );//数据项 CString s; s.Format("%d",m_Set.m_column1);//格式化 //int InsertItem(i,s,0)调用该函数以向列表中插入新条目 返回新条目索引值 //相当于插入新的一行 数字代表列数 m_ListCtrlx.InsertItem(i,s,0); EnsureVisible---调用该函数以确保指定的列表视图条目可见,其原型为: BOOL EnsureVisible(int nItem,BOOL bPartialOK) 返回值: nItem:指定了必须可见的条目索引。 bPartialOK:指定了是否允许部分可见。 列表视图控件将在必要时进行滚动,以确保指定条目可见。如果bPartialOK参数为非零值,则当条目部分可见时,列表视图控件不进行滚动。 2。属性操作函数:它们可以完成对列表视图控件的属性的设置和查询等操作。 DWORD SetExtendedStyle(DWORD dwNewStyle) //先设计列表风格 如果函数调用成功,则返回列表视图控件先前所使用的 扩展风格。 LVS_EX_FULLROWSELECT-----对列表视图中的项目进行整行选择,即选择某条目时,该条目的所在行都被选择。 LVS_EX_GRIDLINES----将在列表视图控件中绘制网格线0x21。 例:m_ListCtrl.SetExtendedStyle( LVS_EX_GRIDLINES );//将在列表视图控件中绘制网格线0x21。 POSITION GetFirstSelectedItemPosition() const 如果函数执行成功,则返回条目的POSITION值,如果返回值为KULL,则表示当前列表视图控件中没有条目选中。 Int GetNextSelectedItem(POSITION& pos) const 如果函数执行成功,则返回列表视图控件中下一个被选中的条目索引。其中参数pos为将接收条目POSITION值的变量。 BOOL SetColumnWidth(int nCol,int cx) 调用该函数以设置报表视图或列表视图中指定列的宽度。 nCol----指定了将被设置宽度的列索引。 cx-------指定了列的新宽度。 Int GetItemText(int nItem, int nSubItem,LPTSTR lpszText,int nLen) const; CString GetItemText(int nItem, int nSubItem) const; 对于int,其返回值为所指定的文本长度;对CString,其返回值为包含条目文本的CString对象。 nItem--------指定将被获取文本的条目索引 nSubItem---------指定了将被获取文本的条目子项的索引。 lpszText---------将返回条目文本的缓冲区指针。 nLen----------指定lpszText缓冲区的长度。 如果nSubItem为0,则函数将获取条目的标签,nSubItem不为0,将获取指定条目子项的文本。 例: BOOL SetItemText(int nItem, int nSubItem,LPTSTR lpszText); 如果函数调用成功,则返回非零值,否则返回零值。 nItem--------指定将被设置的条目索引 nSubItem---------指定了将被设置文本的条目子项的索引。 lpszText---------指定了将被设置的新条目文本。 例: char szTemp[27] = { '/0' };//缓冲区 POSITION Pos = m_ListCtrl.GetFirstSelectedItemPosition(); if ( Pos == NULL ) return; int nCurIndex = m_ListCtrl.GetNextSelectedItem( Pos ); m_Display.Empty();//文本编辑框 m_ListCtrl.GetItemText( nCurIndex, 0, szTemp, 26 ); CImageList:图像列表 CImagelist* GetImageList(int nImageList) const; 如果函数执行成功,则返回列表视图控件的图像列表指针。 nImageList----指定了将获得的图像列表类型。 LVSIL_NORMAL---获取大图标图像列表指针 LVSIL_SMALL--获取小图标图像列表指针 LVSIL_STATE--获取状态图像列表指针 CImageList* SetImageList(CImageList* pImageList,int nImageList); 如果函数执行成功,返回先前的图像列表指针 参数: pImageList--指定了要设置的图像列表指针 nImageList--指定了要设置的图像列表类型 COLORREF GetBkColor() const; 调用该函数获得列表视图控件的背景颜色。 函数执行成功,返回32位RGB值 BOOL SetBkColor (COLORREF cr); 调用该函数设置列表视图控件的背景颜色。 函数执行成功,返回非零值,否则返回零值。 CHeaderCtrl* GetHeaderCtrl(); 调用改函数以得到列表视图控件的标头控件指针 函数调用成功,返回列表视图控件所使用的标头控件指针 例: m_imagelist.Create(16,16,TRUE,2,2); m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_YES)); m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_NO)); m_list.SetImageList(&m_imagelist,LVSIL_SMALL); m_list.SetExtendedStyle(0x21); m_list.SetFont(&m_font1);//设置全部字体 // m_list.GetHeaderCtrl()->SetFont(&m_font1);//只设置标头控件的字体 //以下函数与文本有关 m_list.SetBkColor(RGB(247,247,0)); m_list.SetTextColor(RGB(255,255,255));//设置列表视图控件的文本颜色 m_list.SetTextBkColor(RGB(0,0,255));//设置列表视图控件中文本背景色 m_iImageList.Create(24, 24, TRUE,1, 0); HICON hIcon = NULL; hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_KEBIAO), IMAGE_ICON, 24, 24, 0); m_iImageList.Add(hIcon); m_FileTree.SetImageList ( &m_iImageList,TVSIL_NORMAL ); ----------------------事例---------------------------------- 实现排序: BOOL m_Bs; BOOL m_bIsAsc;//互斥信号量:true升序 反之降序 CDRecordset m_Set; void Sort(BOOL isAsc=TRUE,int secol=1); void CBaDialog::Sort(BOOL isAsc,int secol) { if(m_Set.IsOpen()) m_Set.Close(); this->Select(); //打开所选择数据表 m_bSet.Close();//只对m_Set数据标排序 所以关闭m_bSet CODBCFieldInfo fieldInfo; m_Set.GetODBCFieldInfo(secol,fieldInfo);//返回纪录集中字段的特定种类的信息 即所选 择的信息 if(isAsc)//实现排序功能 { m_Set.m_strSort=fieldInfo.m_strName+" ASC";//order by m_bIsAsc=TRUE; } else { m_Set.m_strSort=fieldInfo.m_strName+" DESC"; m_bIsAsc=FALSE; } m_Set.Requery(); } //单击索引 void CBaDialog::OnColumnclickList3(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;//系统自动生成 // TODO: Add your control notification handler code here if(FALSE== m_bS) { int k= pNMListView->iSubItem; //鼠标单击选择第几行 Sort(!m_bIsAsc, k); m_ListCtrlx.DeleteAllItems(); this->Show();//把数据库学生的数据表内容显示 } *pResult = 0; } 右键单击事件 void CCCDlg::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here POSITION pos = m_list.GetFirstSelectedItemPosition(); //得到当前选中的行 if(pos) { int nItem = m_list.GetNextSelectedItem(pos); CPoint pt; ::GetCursorPos(&pt); COfficeXPMenu m_menu; m_menu.LoadMenu(IDR_MENU_LIST); COfficeXPMenu::SetType(TYPE_XP); //设置菜单的风格,(TYPE_XP, TYPE_NORMAL) COfficeXPMenu *psub = (COfficeXPMenu *)m_menu.GetSubMenu(0); DWORD dwID =psub->TrackPopupMenu(TPM_RIGHTBUTTON,pt.x,pt.y ,this); m_menu.DestroyMenu(); } *pResult = 0; } 列表双击事件(实现在编辑框中显示内容) // 双击则显示显示信息 void CListItemDlg::OnDblclkList(NMHDR* pNMHDR, LRESULT* pResult) { CWordDaoSet WordSet; CString strSQL; CString strNewLine( "/r/n" );//回车换行 char szTemp[27] = { '/0' }; //得到双击列的位置 POSITION Pos = m_ListCtrl.GetFirstSelectedItemPosition(); if ( Pos == NULL ) return; int nCurIndex = m_ListCtrl.GetNextSelectedItem( Pos ); m_Display.Empty(); m_ListCtrl.GetItemText( nCurIndex, 0, szTemp, 26 ); strSQL.Format( "SELECT * FROM WordList WHERE word = '%s'", szTemp ); if ( WordSet.IsOpen() ) WordSet.Close(); WordSet.Open( AFX_DAO_USE_DEFAULT_TYPE, strSQL, 0 ); if ( !WordSet.IsEOF() ) { if ( !WordSet.m_Explain0.IsEmpty() ) m_Display += WordSet.m_Explain0 ;//字符串相加 if ( !WordSet.m_Explain1.IsEmpty() ) m_Display += ( strNewLine + WordSet.m_Explain1 ); if ( !WordSet.m_Explain2.IsEmpty() ) m_Display += ( strNewLine + WordSet.m_Explain2 ); if ( !WordSet.m_Phrase0.IsEmpty() ) m_Display += ( strNewLine + WordSet.m_Phrase0 ); if ( !WordSet.m_Phrase1.IsEmpty() ) m_Display += ( strNewLine + WordSet.m_Phrase1 ); if ( !WordSet.m_Phrase2.IsEmpty() ) m_Display += ( strNewLine + WordSet.m_Phrase2 ); if ( !WordSet.m_Sentence0.IsEmpty() ) m_Display += ( strNewLine + WordSet.m_Sentence0 ); if ( !WordSet.m_Sentence1.IsEmpty() ) m_Display += ( strNewLine + WordSet.m_Sentence1 ); } if ( WordSet.IsOpen() ) WordSet.Close(); UpdateData( FALSE );//在编辑框中显示文本 *pResult = 0; } 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 void CCcDlg::OnDblclkList(NMHDR* pNMHDR, LRESULT* pResult) //双击list控件的函数 { POSITION pos = m_list.GetFirstSelectedItemPosition(); //得到当前选中的行 if(pos) //如果选中一行 { int nItem = m_list.GetNextSelectedItem(pos); CAddDlg dlgadd; dlgadd.m_bAddOrModify=1; //修改记录的标志 if(m_list.GetItemText(nItem,0)=="N") dlgadd.m_bPassed=false; //单项按钮 else dlgadd.m_bPassed=true; dlgadd.m_strName=m_list.GetItemText(nItem,1); dlgadd.m_strCollege =m_list.GetItemText(nItem,2); dlgadd.m_strReason =m_list.GetItemText(nItem,3); dlgadd.m_date1 =m_list.GetItemText(nItem,4); dlgadd.m_date2 =m_list.GetItemText(nItem,5); dlgadd.m_strRemark =m_list.GetItemText(nItem,6); dlgadd.DoModal(); } *pResult = 0; } //////// CListCtrl中选择变化时如何获得通知? 我在Report View中使用了一个CListCtrl(自绘制类型),我想知道什么时候选择项发生了改变. 在选择项变化时,可以使用按钮有效或失效,按如下操作: 加入LVN_ITEMCHANGED消息处理. void CYourClassNameHere::OnItemchangedEventList(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; *pResult = 0; if (pNMListView->uChanged == LVIF_STATE) { if (pNMListView->uNewState) GetDlgItem(IDC_DELETE)->EnableWindow(TRUE); else GetDlgItem(IDC_DELETE)->EnableWindow(FALSE); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 树视图控件-树视图控件 属性设置-style:有按钮、有行、line at root 、边框;more style:卷轴、工具栏提示。 属性操作函数 。GetParentItem:调用该函数得到指定树视图条目的父条目. HTREEITEM GetParentItem(HTREEITEM hItem); hItem:指定条目句柄。 常规操作函数 .InsertItem:向树形控件插入新条目 /* TVINSERTSTRUCT tvInsert; //d第一中插入方法 tvInsert.hParent = NULL;//指定了父条目句柄,参数为TVI_ROOT或NULL,则该条目被插入控件的根部 tvInsert.hInsertAfter = NULL; tvInsert.item.mask = TVIF_TEXT; tvInsert.item.pszText = _T("VC知识库www.vckbase.com"); HTREEITEM hCountry = m_CtrlTree.InsertItem(&tvInsert);*/ //第二种方法 HTREEITEM hCountry = m_CtrlTree.InsertItem( _T("VC知识库www.vckbase.com"), NULL, NULL);//根目录 HTREEITEM hPA = m_CtrlTree.InsertItem(TVIF_TEXT,_T("程序员社区"), 0, 0, 0, 0, 0, hCountry, NULL);//二级目录 HTREEITEM hWA = m_CtrlTree.InsertItem(_T("文档代码中心"),0, 0, hCountry, hPA);// 二级目录 // m_CtrlTree.InsertItem(_T("程序员论坛"),0, 0, hPA, TVI_SORT);//三级目录 m_CtrlTree.InsertItem(_T("程序员论坛"), hPA, TVI_SORT); m_CtrlTree.InsertItem(_T("程序员交友"), hPA, TVI_SORT); m_CtrlTree.InsertItem(_T("人才交流"), hPA, TVI_SORT); m_CtrlTree.InsertItem(_T("文档中心"), hWA, TVI_SORT); //三级目录 m_CtrlTree.InsertItem(_T("代码仓库"), hWA, TVI_SORT); m_CtrlTree.InsertItem(_T("个人专辑"), hWA, TVI_SORT); m_CtrlTree.Expand(hCountry,TVE_EXPAND); 。GetItemText:得到指定条目的文本 。SetItemText .Expand:调用该函数以展开或收拢指定条目的子条目。 BOOL Expand(HTREEITEM hItem,UINT nCode); 函数成功,返回非零值,否则返回零值。 hItem:指定将打开或收拢的条目句柄。 nCode:指定了采取的操作,如下: TVE_COLLAPSE:收拢列表 TVE_COLLAPSERESET:收拢列表,并删除子条目 TVE_EXPAND:打开列表 TVE_TOGGLE:如果当前列表已经打开,则收拢之;如果已经收拢,则打开; 选择所单击的内容 void CPppView::OnSelchangingTree1(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; // TODO: Add your control notification handler code here CTreeCtrl* pTree2 = (CTreeCtrl*) GetDlgItem(IDC_TREE1);// HTREEITEM hSelected = pNMTreeView->itemNew.hItem; CPppDoc* pDoc = (CPppDoc*)GetDocument();//一切都以文档传输 CString hParentName; HTREEITEM hParent=pTree2->GetParentItem(hSelected); // if(hSelected!=NULL) { pDoc->Name=pTree2->GetItemText(hSelected);// Name在文档里定义 } *pResult = 0; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2.组合框控件: int GetCurSel() const 得到当前选项的索引, 失败则返回CB_ERR。 Int SetCurSel(int nSelect); 如果函数调用成功,返回当前选项索引。如果nSelect的值超出范围,或为-1,则返回CB_ERR,并清除当前选项。 int GetLBText(int nIndex,Cstring& rString ) const void GetLBText(int nIndex, LPTSTR lpszText) const 如果函数调用成功,则返回字符串的字节长度(不包括末尾的空字符)。如果nIndex并非合法的索引,则返回CB_ERR。 nIndex----指定将获取文本选项的索引。 LpszText---指定将用以存放所得文本的缓冲区指针。该缓冲区必须足够容纳要获取的文本及其结尾空字符。 rString:用于存放所的文本的Cstring对象 int GetLBTextLen( int nIndex) const 如果函数调用成功,则返回字符串的字节长度(不包括末尾的空字符)。如果nIndex并非合法的索引,则返回CB_ERR。 nIndex----指定将获取组合框选项的索引。 ----------------------------------------------------------- ComboBox(下拉框)的用法: CComboBox m_cob; CString m_Getstring; m_cob.GetLBText(m_cob.GetCurSel(),m_Getstring);//把选择的内容传给m_Getstring void CBaDialog::OnTimer(UINT nIDEvent) { //设置列表框的选择 当再一次选择时 重新设置按钮的属性 // TODO: Add your message handler code here and/or call default CString m_string; m_cob.GetLBText(m_cob.GetCurSel(),m_string); if(m_Getstring!=m_string) { GetDlgItem(IDC_STATR)->EnableWindow(TRUE); this->Enable(FALSE); } CDialog::OnTimer(nIDEvent); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 3.BUTTON 操作函数: HICON SetIcon(HICON hIcon); 如果函数操作成功,返回先前与按钮联系的图标句柄。 以链表的方式实现了主界面所有Button的初始化 // 设置按钮风格 // 将其单独定义而不是在ClassWizard中定义,参看InitBuffonStyle(); private: CButtonStyle m_Setting, m_ListItem, m_Addition, m_Remove, m_Modify, m_Search, m_About, m_Exit, m_Previous, m_Next, m_End, m_Home, m_Goto, m_Jump; void CMagicWordDlg::InitButtonStyle() { CList< CButtonStyle*, CButtonStyle* > ButtonList; //ButtonList.AddTail( &m_Setting ); ButtonList.AddTail( &m_ListItem ); ButtonList.AddTail( &m_Addition ); ButtonList.AddTail( &m_Remove ); ButtonList.AddTail( &m_Modify ); ButtonList.AddTail( &m_Search ); ButtonList.AddTail( &m_About ); ButtonList.AddTail( &m_Exit ); ButtonList.AddTail( &m_Previous ); ButtonList.AddTail( &m_Next ); ButtonList.AddTail( &m_End ); ButtonList.AddTail( &m_Home ); ButtonList.AddTail( &m_Goto ); ButtonList.AddTail( &m_Jump ); // 用循环实现必须手动改动Resource.h中的定义 for ( int nIco = IDI_JUMP, nBtn = IDC_JUMP; nBtn >= IDC_LISTITEM; nIco--, nBtn-- ) { CButtonStyle *Button = ButtonList.RemoveTail(); Button->SubclassDlgItem( nBtn, this ); Button->SetIcon( nIco ); Button->SetInactiveBgColor(); Button->SetInactiveFgColor(); Button->SetActiveBgColor(); } } 使按钮不可用 BOOL m_bS; m_bS = GetDlgItem(IDC_STATR)->EnableWindow(FALSE); void CBaDialog::Enable( BOOL p) { BOOL HB; HB=p; GetDlgItem(IDC_ADD)->EnableWindow(HB); GetDlgItem(IDC_DELECT)->EnableWindow(HB); GetDlgItem(IDC_EDIT)->EnableWindow(HB); GetDlgItem(IDC_FIND)->EnableWindow(HB); GetDlgItem(IDC_ALL)->EnableWindow(HB); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 编辑控件 属性操作函数:完成属性的设置和查询等操作〉 常规操作函数:完成清空编辑控件的恢复缓冲区、得到编辑控件中的被选文本等操作。 SetSel:调用该函数以设置编辑控件中的当前被选文本,其原型: void SetSel(DWORD dwSelection,BOOL bNoScroll=FALSE); void SetSel(int nStartChar,int nEndChar,BOOL bNoScroll=FALSE); dwSelection bNoScroll nStartChar nEndCha bNoScroll 剪贴板操作: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////// 状态栏—CstatusBar 构造函数:完成创建状态栏对象、设置状态栏窗格ID等操作。 SetIndicators:调用该函数可以设置各个指示窗口的ID,其原型为: BOOL SetIndicators(const UINT* lpIDArray,int nIDCount); 调用成功,返回非零值,否则,零值。 lpIDArray :为包含状态栏指示窗格ID的数组。 nIDCount:指定了状态栏指示窗格数目。 属性操作函数:完成创建状态栏对象、设置状态栏分栏ID等操作。 CommandToIndex:调用该函数可以获得给定ID值的状态栏指示窗格索引,其原型: Int CommandToIndex(UINT nIDFind) const; 调用成功,返回指示窗格索引,否则,返回-1. nIDFind——指定了将获取其索引的窗格ID。 SetPaneText:调用该函数可以设置给定指示窗格的文本,其原型: BOOL SetPaneText(int nIndex,LPCTSTR lpszNewText,BOOL bUpdate=TRUE); 调用成功,返回非零值,否则,零值。 nIndex:指定了将设置其文本的状态栏指示窗格索引。 lpszNewText:指定了将设置的指示窗格文本。 bUpdate:如果改参数为TRUE,则指示窗格的显示将被更新。 ////////////////////////////////////////////////////////// ///////////////// 检查框(Check boxes)和单选按钮(Radio button) Radio button: m_radio.SetCheck(1);//选中状态 int m_nSel; void CSearchDlg::OnOK() { try { UpdateData(); switch(m_nSel) { case 0: theApp.m_strSQL="SELECT * FROM Records WHERE date1>='"+m_strDate1+"' AND date2<='"+m_strDate2+"'"; break; case 1: theApp.m_strSQL="SELECT * FROM Records WHERE Name LIKE '%"+m_strName+"%'"; break; case 2: theApp.m_strSQL="SELECT * FROM Records WHERE College LIKE '%"+m_strCollege+"%'"; break; case 3: theApp.m_strSQL="SELECT * FROM Records WHERE Reason LIKE '%"+m_strReason+"%'"; break; } ((CCcDlg*)AfxGetMainWnd())->List(theApp.m_strSQL); } catch(_com_error e) { CATCH_ERROR; } CDialog::OnOK(); } ////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 对话框 隐藏和显示对话框:ShowWindow (SW_HIDE); ShowWindow (SW_SHOW); ShowWindow (SW_HIDE); CAcsLogDlg loginDlg; if (loginDlg.DoModal ()==IDOK) { success = TRUE; } else { success = FALSE; ShowWindow (SW_SHOW); } 对话框中的控件:可见(visible)风格通过调用CWnd::ShowWindow()改变可见性。 m_button.ShowWindow(SW_SHOW);//显示按钮 m_button.ShowWindow(SW_HIDE);//隐藏按钮 禁止(disabled)调用CWnd::EnabledWindow() UpdateData();参数为TRUE时,对话框控件中的内容传递给数据成员,为FALSE时反之。 SetDlgItemText(IDC_Use,"");//对话框中的编辑框清空 GetDlgItem(IDC_Use)->SetFocus();//光标停在对话框中的IDC_Use SetDialogBkColor( RGB( 96, 160, 16 ), RGB( 255, 255, 255 ) ); // 设置对话框背景色及文本色 调用对话框 打开文件对话框 void CMediaPlayerDlg::OnOpen() { // TODO: Add your control notification handler code here char szFileFilter[]= "Mp3 File(*.mp3)|*.mp3|" "Wma File(*.wma)|*.wma|" "Video File(*.dat)|*.dat|" "Wave File(*.wav)|*.wav|" "AVI File(*.avi)|*.avi|" "Movie File(*.mov)|*.mov|" "Media File(*.mmm)|*.mmm|" "Mid File(*.mid;*,rmi)|*.mid;*.rmi|" "MPEG File(*.mpeg)|*.mpeg|" "All File(*.*)|*.*||"; CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,szFileFilter); //CFileDialog fileDlg(TRUE, "mdb", "*.mdb", NULL, "Access Files(*.mdb)", NULL); if(dlg.DoModal()==IDOK){ CString PathName=dlg.GetPathName(); PathName.MakeUpper(); m_ActiveMovie.SetFileName(PathName); } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////// 字体 CFont m_font2; CFont m_font1; m_font1.CreateFont(12, 0,0,0,FW_BOLD, 0,0,0, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "宋体");//加粗 /* m_font2.CreateFont(14, 0,0,0,FW_NORMAL, 0,0,0, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "宋体"); */ ///////////////////////////////////////////////////////////////// 4.数据库 ODBC动态添加数据库:Lhwy工程 CDatabase类 public: CDatabase m_DB; extern CLhwyApp theApp; #include <odbcinst.h> //由于 VC的缺省库文件中不包含 SQLConfigDataSource()函数,因此使用该函数之前需要将 odbcinst.h文件包含在工程的头文件中 BOOL CLhwyApp::InitInstance() { //在VC中动态加载ODBC的方法 if (!AfxSocketInit()) { AfxMessageBox(IDP_SOCKETS_INIT_FAILED); return FALSE; } CString sPath;//数据库存放路径 GetModuleFileName(NULL,sPath.GetBufferSetLength(MAX_PATH+1),MAX_PATH); sPath.ReleaseBuffer (); int nPos; nPos=sPath.ReverseFind ('//'); sPath=sPath.Left (nPos); nPos=sPath.ReverseFind('//'); sPath=sPath.Left (nPos); CString lpszFile = sPath + "//lhwy.mdb"; char* szDesc; int mlen; szDesc=new char[256]; sprintf(szDesc,"DSN=%s? DESCRIPTION=TOC support source? DBQ=%s? FIL=MicrosoftAccess? DEFAULTDIR=%s?? ","lhwy",lpszFile,sPath); mlen = strlen(szDesc); for (int i=0; i<mlen; i++) { if (szDesc[i] == '?') szDesc[i] = '/0'; } //Windows系统子目录中的动态链接库 Odbcinst.dll提供了一个可以动态地增加、修改和删除数据源的函数 SQLConfigDataSource()。 // if (FALSE == SQLConfigDataSource(NULL,ODBC_ADD_DSN,"Microsoft Access Driver (*.mdb)/0",(LPCSTR)szDesc)) AfxMessageBox("SQLConfigDataSource Failed"); try { CString strConnect; strConnect.Format("DSN=lhwy;");//指定odbc连接的字符串:数据源的名称和其他//一些选项信息 if(!m_DB.OpenEx(strConnect,CDatabase::useCursorLib))//装载ODBC光标库DLL,如果想直接从Crecordset类得到对象而不是派生得到,就不应该装载光标库/ //要使程序与数据源建立联系,需用CDateBase::OpenEx()或CDatabase::Open()函数来进行初始化。数据库对象必须在使用它构造记录集对象之前初始化。 { AfxMessageBox("Unable to Connect to the Specified Data Source"); return FALSE ; } } catch(CDBException *pE) { pE->ReportError(); pE->Delete(); return FALSE; } AfxEnableControlContainer(); //SetDialogBkColor(RGB(140,130,210),RGB(255,0,0)); SetDialogBkColor (RGB (140, 180, 220), RGB ( 255 ,0 , 0 ) );//背景色 连接数据表 CDRecordset m_Set(&theApp.m_DB);// &theApp.m_DB为CDatabase类型 CBRecordset m_bSet(&theApp.m_DB); CTRecordset m_tSet(&theApp.m_DB); CRecordset类 数据成员 m_nFields:记录集中的字段数目,类型为UINT. m_strFilter:CString对象,包含一个SOL的WHERE字句,作为过滤器对那些满足一定条件的记录进行选择。 m_strSort: CString对象,包含一个SOL的ORDER BY字句,用于控制记录排序的方式。 GetODBCFieldInfo------返回记录集中字段的特定种类的信息。 记录导向操作 MoveFirst------设置记录集的当前记录为第一个记录,此前应调用IsBOF测 试。 记录更新操作 Edit-------准备对当前记录的更改,编辑,调用Update()完成编辑。 AddNew----准备增加一个新记录,调用Update()完成。 Delete------从记录中删除当前记录,在删除之后必须滚动到下一个记录。 操作应用: 打开数据表m_Set.Open(AFX_DB_USE_DEFAULT_TYPE,"[NO2STUDENT]");// [NO2STUDENT为数据表名 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// 用ADO连接数据库 ADO库包含三个基本接口:_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口。 库包含三个基本接口:_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口。 _ConnectionPtr接口返回一个记录集或一个空指针。通常使用它来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。使用_ConnectionPtr接口返回一个记录集不是一个好的使用方法。通常同CDatabase一样,使用它创建一个数据连接,然后使用其它对象执行数据输入输出操作。 _CommandPtr接口返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时,你可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。如果你只执行一次或几次数据访问操作,后者是比较好的选择。但如果你要频繁访问数据库,并要返回很多记录集,那么,你应该使用全局_ConnectionPtr接口创建一个数据连接,然后使用_CommandPtr接口执行存储过程和SQL语句。 _RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定,游标控制等。同_CommandPtr接口一样,它不一定要使用一个已经创建的数据连接,可以用一个连接串代替连接指针赋给_RecordsetPtr的connection成员变量,让它自己创建数据连接。如果你要使用多个记录集,最好的方法是同Command对象一样使用已经创建了数据连接的全局_ConnectionPtr接口,然后使用_RecordsetPtr执行存储过程和SQL语句。 程序中通过_variant_t和_bstr_t转换COM对象和C++类型的数据, _variant_t类封装了OLE自治VARIANT数据类型。在C++中使用_variant_t类要比直接使用VARIANT数据类型容易得多。 在stdafx.h 文件中添加: #include 〈comdef.h〉//头文件comdef.h使我们的应用程序能够使用Visual C++中的一些特殊COM支持类,这些类使得处//理OLE自治更为容易一些,OLE自治是ADO使用的数据类型。 #import "msado15.dll" no_namespace rename("EOF","adoEOF") //#import "c:/program files/common files/system/ado/msado15.dll" no_namespace rename("EOF","adoEOF") #if !defined CATCH_ERROR #define CATCH_ERROR / { / CString strComError; / strComError.Format("错误编号: %08lx/n错误信息: %s/n错误源: %s/n错误描述: %s", / e.Error(), / e.ErrorMessage(), / (LPCSTR) e.Source(), / (LPCSTR) e.Description()); / ::MessageBox(NULL,strComError,"错误",MB_ICONEXCLAMATION); / } #endif 连接数据库: 打开一个库连接。先创建一个实例指针,再用Open打开一个库连接,它将返回一个IUnknown的自动化接口指针。 _ConnectionPtr m_pConnection;//public BOOL CCcApp::InitInstance() { AfxOleInit();//初始化COM库 AfxEnableControlContainer();//系统生成 // 在ADO操作中建议语句中要常用try...catch()来捕获错误信息, // 因为它有时会经常出现一些意想不到的错误。 try { m_pConnection.CreateInstance("ADODB.Connection");///创建Connection对象 //m_pConnection.CreateInstance(__uuidof(Connection)); m_pConnection->ConnectionTimeout=3;///设置超时时间为3秒 m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=data.mdb;","","",adModeUnknown);//Data是数据类型 } catch(_com_error e)///捕捉异常 { CATCH_ERROR; return false; } 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 、、、、、、、、、、、、、、、、、、、、、、、 关闭一个库连接 如果连接状态有效,则用Close方法关闭它并赋于它空值。代码如下所示: if(m_pConnection->State) m_pConnection->Close(); m_pConnection= NULL; _RecordsetPtr智能指针,可以用来打开库内数据表,并可以对表内的记录、字段等进行各种操作。 _RecordsetPtr m_pRecordset; m_pRecordset.CreateInstance("ADODB.Recordset"); //查询数据库,看是否有此用户和密码 m_pRecordset->Open((_variant_t)sql,_variant_t((IDispatch*)theApp.m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText); /* m_pRecordset->Open("SELECT * FROM DemoTable", // 查询DemoTable表中所有字段 theApp.m_pConnection.GetInterfacePtr(), // 获取库接库的IDispatch指针 adOpenDynamic, adLockOptimistic, adCmdText); } */ 具体操作: 附加 #define CATCH_ERROR / catch (_com_error e) / { / CString strComError; / strComError.Format("错误编号: %08lx/r/n/r/n错误信息: %s/r/n/r/n错误源: %s/r/n/r/n错误描述: %s", / e.Error(), / e.ErrorMessage(), / (LPCSTR) e.Source(), / (LPCSTR) e.Description()); / SetDlgItemText(IDC_MESSAGE,strComError); / } #define SET_TEXT SetDlgItemText(IDC_MESSAGE,"!/r/n/r/n/r/n/r/n/t/t操作成功完成!"); 读取表内数据 将表内数据全部读出并显示在列表框内,m_AccessList为列表框的成员变量名。如果没有遇到表结束标志adoEOF,则用GetCollect(字段名)或m_pRecordset->Fields->GetItem(字段名)->Value方法,来获取当前记录指针所指的字段值,然后再用MoveNext()方法移动到下一条记录位置。 插入记录 可以先用AddNew()方法新增一个空记录,再用PutCollect(字段名,值)输入每个字段的值,最后再Update()更新到库中数据既可。其中变量m_Name和m_Age分别为姓名及年龄编辑框的成员变量名。 _variant_t RecordsAffected; theApp.m_strSQL="INSERT INTO Records (Name,YorN,College,date1,date2,Reason,Remark,Flag) values('"+m_strName+"','"+YorN+"','"+m_strCollege+"','"+m_date1+"','"+m_date2+"','"+m_strReason+"','"+m_strRemark+"','"+strNowTime+"')"; theApp.m_pConnection->Execute((_bstr_t)theApp.m_strSQL,&RecordsAffected,adCmdText); 移动记录指针 移动记录指针可以通过MoveFirst()方法移动到第一条记录、MoveLast()方法移动到最后一条记录、MovePrevious()方法移动到当前记录的前一条记录、MoveNext()方法移动到当前记录的下一条记录。但我们有时经常需要随意移动记录指针到任意记录位置时,可以使用Move(记录号)方法来实现,注意: Move()方法是相对于当前记录来移动指针位置的,正值向后移动、负值向前移动,如:Move(3),当前记录是3时,它将从记录3开始往后再移动3条记录位置。 改记录中字段值 可以将记录指针移动到要修改记录的位置处,直接用PutCollect(字段名,值)将新值写入并Update()更新数据库既可。 theApp.m_strSQL="update Records set Name='"+m_strName+ "',YorN='"+YorN+ "',College='"+m_strCollege+ "',Reason='"+m_strReason+ "',date1='"+m_date1+ "',date2='"+m_date2+ "',Remark='"+m_strRemark+ "' where Flag='"+m_strFlag+"'"; _variant_t RecordsAffected; theApp.m_pConnection->Execute((_bstr_t)theApp.m_strSQL,&RecordsAffected,adCmdText); 删除记录 删除记录和上面修改记录的操作类似,先将记录指针移动到要修改记录的位置,直接用Delete()方法删除它并用Update()来更新数据库既可。 登陆窗口连接数据库 BOOL LogonDlg::OnInitDialog() //初始化登陆窗口 { CDialog::OnInitDialog(); // TODO: Add extra initialization here try { m_pRecordset.CreateInstance("ADODB.Recordset");//创建对象 m_pRecordset->Open((_variant_t)"SELECT * FROM Admin",_variant_t((IDispatch*)theApp.m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText); if(!m_pRecordset->adoEOF) { theApp.g_Admin=((LPCTSTR)(_bstr_t)m_pRecordset->GetCollect("AdminName")); SetDlgItemText(IDC_Use,theApp.g_Admin); } m_pRecordset->Close(); } catch (_com_error e) { CATCH_ERROR; return false; } return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void LogonDlg::OnOK() //当点击确定按钮时,所作的操作,成功弹出主界面 { // TODO: Add extra validation here UpdateData(); if(m_Use.IsEmpty() || m_Pass.IsEmpty()) { AfxMessageBox("请输入用户名和密码!"); } else { CString sql="SELECT * FROM Admin where AdminName='"+theApp.g_Admin+"' and pwd='"+m_Pass+"'"; try { //创建Recordset对象的实例 m_pRecordset.CreateInstance("ADODB.Recordset"); //查询数据库,看是否有此用户和密码 m_pRecordset->Open((_variant_t)sql,_variant_t((IDispatch*)theApp.m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText); if(m_pRecordset->adoEOF) //如果没有此用户和密码 { MessageBox("请输入正确的用户名和密码!","错误",MB_ICONASTERISK ); SetDlgItemText(IDC_Use,""); GetDlgItem(IDC_Use)->SetFocus(); } else { theApp.g_Admin=m_Use; theApp.g_Pass=m_Pass; CDialog::OnOK(); } } catch (_com_error e) { CATCH_ERROR; return; } } // CDialog::OnOK(); } void LogonDlg::OnCancel() // { // TODO: Add extra cleanup here //((CCcDlg*)AfxGetMainWnd()):取得主界面的指针 ((CCcDlg*)AfxGetMainWnd())->EndDialog(IDOK);//当点击取消按钮时不弹出主界面 CDialog::OnCancel(); } 显示所查内容 extern CCcApp theApp; void CCcDlg::List(CString sql) //将SQL语句查询的结果显示在列表框中 { m_list.DeleteAllItems(); int nItem=0; try { m_pRecordset.CreateInstance("ADODB.Recordset"); m_pRecordset->Open((_variant_t)sql,_variant_t((IDispatch*)theApp.m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText); if(!m_pRecordset->adoEOF) //如果记录不为空 { while(!m_pRecordset->adoEOF) { if(strcmp((LPCTSTR)(_bstr_t)m_pRecordset->GetCollect("YorN"),"Y")==0) //是否批准 nItem=m_list.InsertItem(0xffff,"Y",0);//0代表正确的图标 0xffff可用数字代替 else nItem=m_list.InsertItem(0xffff,"N",1);//1代表错误的图标 m_list.SetItemText(nItem,1,(LPCTSTR)(_bstr_t)m_pRecordset->GetCollect("Name")); m_list.SetItemText(nItem,2,(LPCTSTR)(_bstr_t)m_pRecordset->GetCollect("College")); m_list.SetItemText(nItem,3,(LPCTSTR)(_bstr_t)m_pRecordset->GetCollect("Reason")); m_list.SetItemText(nItem,4,(LPCTSTR)(_bstr_t)m_pRecordset->GetCollect("date1")); m_list.SetItemText(nItem,5,(LPCTSTR)(_bstr_t)m_pRecordset->GetCollect("date2")); m_list.SetItemText(nItem,6,(LPCTSTR)(_bstr_t)m_pRecordset->GetCollect("Remark")); m_pRecordset->MoveNext(); } } m_pRecordset->Close(); } catch (_com_error e) { CATCH_ERROR; return; } CString strTitle; strTitle.Format("学生请假管理系统 共有%d条记录",nItem+1); SetWindowText(strTitle); } 删除一条记录 void CCcDlg::OnButtonDel() //删除一条记录 { try { POSITION pos = m_list.GetFirstSelectedItemPosition(); if(pos) //如果选中一行,则生成动态的sql语句 { if(MessageBox("你确定要删除此记录吗?","警告",MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2)==IDYES) { int nItem = m_list.GetNextSelectedItem(pos); theApp.m_strSQL="DELETE FROM Records WHERE name='" +m_list.GetItemText(nItem,1)+"' and College='" +m_list.GetItemText(nItem,2)+"' and Reason='" +m_list.GetItemText(nItem,3)+"' and date1='" +m_list.GetItemText(nItem,4)+"' and date2='" +m_list.GetItemText(nItem,5)+"' and Remark='" +m_list.GetItemText(nItem,6)+"'"; _variant_t RecordsAffected; theApp.m_pConnection->Execute((_bstr_t)theApp.m_strSQL,&RecordsAffected,adCmdText); //执行此sql语句 List("SELECT * FROM Records"); } } else AfxMessageBox("请选择一行数据!"); } catch(_com_error e) { CATCH_ERROR; } } 1. 建表 void CADlg::OnCreatetTable() { try { m_pConnection->Execute("CREATE TABLE new(ID INTEGER,username TEXT,old INTEGER)",NULL,adCmdText); SET_TEXT; } CATCH_ERROR; } 2. 删除数据表 void CADlg::OnDropTable() { try { m_pConnection->Execute("DROP TABLE new",NULL,adCmdText); SET_TEXT; } CATCH_ERROR; } void CADlg::OnAddItem() { try { m_pConnection->Execute("ALTER TABLE new ADD newcolumn1 INTEGER",NULL,adCmdText); SET_TEXT; } CATCH_ERROR; } void CADlg::OnDelItem() { try { m_pConnection->Execute("ALTER TABLE new ADD newcolumn1 INTEGER", NULL,adCmdText); SET_TEXT; } CATCH_ERROR; } void CADlg::OnAddRecords() { try { for(int i = 1;i < 10; i ++) { CString strSQL; strSQL.Format("INSERT INTO new(ID,username,old) VALUES (%d, '程红秀',%d)",i,i*3); m_pConnection->Execute((_bstr_t)strSQL,NULL,adCmdText); SET_TEXT; } } CATCH_ERROR; } void CADlg::OnOldAdd1() { try { m_pConnection->Execute("UPDATE new SET old = old+1", NULL,adCmdText); SET_TEXT; } CATCH_ERROR; } void CADlg::OnSum() { try { _RecordsetPtr m_pRecordset; _variant_t RecordsAffected; m_pRecordset =m_pConnection->Execute("SELECT COUNT(*) FROM new where ID > 0",&RecordsAffected,adCmdText); _variant_t vCount = m_pRecordset->GetCollect((_variant_t)(long)0); //取得第一个字段的值放入vCount变量 CString str; str.Format("!/r/n/r/n/r/n/t/t/t共有%d条记录",vCount.lVal); SetDlgItemText(IDC_MESSAGE,str); m_pRecordset->Close(); } CATCH_ERROR; } void CADlg::OnSetIdIndex() { try { m_pConnection->Execute("CREATE UNIQUE INDEX id ON new(ID)",NULL,adCmdText); SET_TEXT; } CATCH_ERROR; } void CADlg::OnOldSum() { try { _RecordsetPtr m_pRecordset; _variant_t RecordsAffected; m_pRecordset =m_pConnection->Execute("select MAX(old) from new",&RecordsAffected,adCmdText); _variant_t vCount = m_pRecordset->GetCollect((_variant_t)(long)0); m_pRecordset->Close(); m_pRecordset.Release(); CString Message; Message.Format("!/r/n/r/n/r/n/t/t/t最大值是%d",vCount.lVal); SetDlgItemText(IDC_MESSAGE,Message); } CATCH_ERROR; } void CADlg::OnOldSum2() { try { _RecordsetPtr m_pRecordset; _variant_t RecordsAffected; m_pRecordset =m_pConnection->Execute("select SUM(old) from new",&RecordsAffected,adCmdText); _variant_t vIndex = (long)0; _variant_t vCount = m_pRecordset->GetCollect(vIndex); m_pRecordset->Close(); m_pRecordset.Release(); CString Message; Message.Format("!/r/n/r/n/r/n/t/t/t总和是%d",(long)vCount); SetDlgItemText(IDC_MESSAGE,Message); } CATCH_ERROR; } void CADlg::OnOldAverage() { try { _RecordsetPtr m_pRecordset; _variant_t RecordsAffected; m_pRecordset =m_pConnection->Execute("select AVG(old) from new",&RecordsAffected,adCmdText); _variant_t vIndex = (long)0; _variant_t vCount = m_pRecordset->GetCollect(vIndex); m_pRecordset->Close(); m_pRecordset.Release(); CString Message; Message.Format("!/r/n/r/n/r/n/t/t/t平均值是%d",(long)vCount); SetDlgItemText(IDC_MESSAGE,Message); } CATCH_ERROR; } //////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// DAO访问ACCESS数据库 CDaoRecordSet类 类成员: 数据成员:m_nFields(),m_strFilter(),m_strSort() m_pSet->m_strFilter=filter; m_pSet->Requery(); . 属性成员函数:CanUpdate() 。记录操作函数: AddNew() 动态连接数据库: #include <afxdao.h> private: CString m_DataSource; //动态连接数据库 char path[ MAX_PATH ] = { '/0' }; GetCurrentDirectory( MAX_PATH, path ); m_DataSource.Format( "%s", path ); m_DataSource += "//MagicWord.mdb";//数据库名 CString CWordDaoSet::GetDefaultDBName() { return _T( m_DataSource );//数据源的路径 m_DataSource不加引号 } //实例化 m_pSet = new CWordDaoSet(); 在视图文档中,采用:在PppView.cpp文件的OnInitialUpdate()函数中得到指向数据集的指针 CFormView::OnInitialUpdate(); CPppDoc* pDoc = (CPppDoc*)GetDocument(); //得到指向文档类指针 m_ShengSet=&pDoc->m_ShengSet;//得到数据库指针 ///////////////////////// //PUBLIC函数 打开数据表进行操作 void CMagicWordDlg::DisplayFirstRecord() { try { if ( m_pSet->IsOpen() ) m_pSet->Close(); m_pSet->Open(); PublicAssign();//操作函数 } catch( CDaoException *exception ) { exception->ReportError(); return; } } 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 添加功能:执行添加、删除、查找等操作。 首先。写SQL查询语句 其次。创建一个新的纪录集对象 功能操作 关闭数据表 添加新单词 // 实例化m_pSet m_pSet = new CWordDaoSet(); void CMagicWordDlg::OnAddition() //添加函数 { CWordInfoDlg WordInfoDlg; //添加对话框 CWordDaoSet TempSet;//数据库表 CString strSQL;//SQL查询 // 如果点击了取消按钮,则不执行添加操作。 if ( WordInfoDlg.DoModal() != IDOK )// 调用添加对话框 return; // 查询当前单词是否已经被收录于数据库中 if ( TempSet.IsOpen() )//关闭原有的记录集 TempSet.Close(); //查询功能,看添加的内容是否已经存在 strSQL.Format( "SELECT * FROM WordList WHERE word = '%s'", WordInfoDlg.m_word.operator LPCTSTR() ); //创建一个新的纪录集对象 TempSet.Open( AFX_DAO_USE_DEFAULT_TYPE, strSQL, 0 ); if ( !TempSet.IsEOF() ) { MessageBox( _T( "当前单词纪录已存在,没有添加的必要!" ), _T( "已经存在!" ), MB_OK | MB_ICONASTERISK ); return; } if ( TempSet.IsOpen() ) TempSet.Close(); // 执行添加操作 try { m_pSet->AddNew(); //添加内容 m_pSet->m_Word = WordInfoDlg.m_word; m_pSet->m_Explain0 = WordInfoDlg.m_explain0; m_pSet->m_Explain1 = WordInfoDlg.m_explain1; m_pSet->m_Explain2 = WordInfoDlg.m_explain2; m_pSet->m_Phrase0 = WordInfoDlg.m_phrase0; m_pSet->m_Phrase1 = WordInfoDlg.m_phrase1; m_pSet->m_Phrase2 = WordInfoDlg.m_phrase2; m_pSet->m_Sentence0 = WordInfoDlg.m_sentence0; m_pSet->m_Sentence1 = WordInfoDlg.m_sentence1; //更新数据库 if ( m_pSet->CanUpdate() ) { m_pSet->Update(); MessageBox( _T( "添加新单词完成!" ), _T( "添加成功!" ), MB_OK | MB_ICONASTERISK ); } } catch( CDaoException *exception )//异常操作 { exception->ReportError(); // 否则指针会指向出现异常的纪录 m_pSet->MoveNext(); m_pSet->MovePrev(); return; } } 直接通过DAO读写Access文件 CDaoDatabase db; //数据库 CDaoRecordset RecSet(&db); //记录集 void CRWAccessDlg::OnWriteAccess() //创建数据库,并向数据表中添加数据 { //获取主程序所在路径,存在sPath中 CString sPath; GetModuleFileName(NULL,sPath.GetBufferSetLength (MAX_PATH+1),MAX_PATH); sPath.ReleaseBuffer (); int nPos; nPos=sPath.ReverseFind ('//'); sPath=sPath.Left (nPos); //默认创建数据名:Demo.mdb,内部表名:DemoTable,表内有二个字段:姓名、年龄 CString lpszFile = sPath + "//Demo.mdb"; CFileFind fFind;//查找文件 BOOL bSuccess; bSuccess=fFind.FindFile(lpszFile); fFind.Close (); //是否已有创建好的Demo.mdb文件,没有则创建它 if(!bSuccess) { db.Create(lpszFile);//创建数据库 CString SqlCmd = "CREATE TABLE DemoTable(Name VARCHAR(20),Age VARCHAR(3));"; db.Execute(SqlCmd);//创建数据表 //打开已创建的数据表 RecSet.Open(AFX_DAO_USE_DEFAULT_TYPE, "SELECT * FROM DemoTable", 0); //加入第一个记录,用SQL语句 db.Execute("INSERT INTO DemoTable (Name,Age) VALUES ('徐景周',26)"); //加入第二个记录,用DAO涵数 RecSet.AddNew(); RecSet.SetFieldValue("Name","徐志慧"); RecSet.SetFieldValue("Age","21"); RecSet.Update(); //加入第三个记录,用DAO涵数 RecSet.AddNew(); RecSet.SetFieldValue("Name","郭徽"); RecSet.SetFieldValue("Age","27"); RecSet.Update(); //关闭记录集及库 RecSet.Close(); db.Close(); AfxMessageBox("Access文件写入成功!"); } else AfxMessageBox("Demo.mdb数据库已经创建!"); } void CRWAccessDlg::OnReadAccess() //直接读取数据库 { COleVariant var; // 字段类型 var.ChangeType(VT_BSTR, NULL); CString strName,strAge,strFile; //清空列表框 m_AccessList.ResetContent(); //获取主程序所在路径,存在sPath中 CString sPath; GetModuleFileName(NULL,sPath.GetBufferSetLength (MAX_PATH+1),MAX_PATH); sPath.ReleaseBuffer (); int nPos; nPos=sPath.ReverseFind ('//'); sPath=sPath.Left (nPos); strFile = sPath + "//demo.mdb"; db.Open(strFile); // 打开已创建的demo数据库及DamoTable表 RecSet.Open(AFX_DAO_USE_DEFAULT_TYPE,"SELECT * FROM DemoTable",NULL); while(!RecSet.IsEOF()) // 有没有到表结尾 { RecSet.GetFieldValue("Name",var); strName = (LPCSTR)var.pbstrVal; RecSet.GetFieldValue("Age",var); strAge = (LPCSTR)var.pbstrVal; m_AccessList.AddString( strName + " --> "+strAge ); RecSet.MoveNext(); } //关闭记录集及库 RecSet.Close(); db.Close(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////// ////////////////////////////// ////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// CString类的用法: IsEmpty()//字符串是否为空 Empty()//置空 Find( )//查找字符串 此为查找空格 GetAt(0)//得到第一个字符 SetAt( , )// WordSet.m_Word.SetAt( 0, WordSet.m_Word.GetAt( 0 ) - 32 ); 将第一个字母转换为大写状态 MakeLower()//转化为小写状态 MakeUpper()// GetLength()//得到字符串长度 TrimRight()// MakeLower()//转换成小写字母 MakeUpper()//转换成大写字母 设置字体 CString s; s = "<font color='255,255,255' face='宋体' size='12' align='center'><br><p>"; s += "<font color='200,250,100' size='18' face='宋体' style='ui'>直接通过DAO读、写Access文件示例</font><br><br><p>"; s += "<font color='200,250,100' size='14' face='宋体'>作者:徐景周</font><br><br><p>"; s += "<font color='200,250,100' size='14' face='宋体'>未来工作室出品</font><br><p>"; 应用: 1符匹配: 匹配单个字符(不区分大小写) void CListItemDlg::MatchSingleCharacter() { CWordDaoSet WordSet; CString strLower; CString strUpper; try { if ( WordSet.IsOpen() ) WordSet.Close(); WordSet.Open(); while ( !WordSet.IsEOF() ) { m_word.MakeLower(); strLower = m_word; m_word.MakeUpper(); strUpper = m_word; // 对单个字符不区分大小写,只与单词的第一个字母比较 if ( WordSet.m_Word.GetAt(0) == strLower || WordSet.m_Word.GetAt(0) == strUpper ) m_ListCtrl.InsertItem( 0, WordSet.m_Word ); WordSet.MoveNext(); } } catch ( CDaoException *exception ) { exception->ReportError(); return; } } 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 匹配字符串(区分大小写) void CListItemDlg::MatchString() { CWordDaoSet WordSet; try { if ( WordSet.IsOpen() ) WordSet.Close(); WordSet.Open(); while ( !WordSet.IsEOF() ) { if ( m_bChecked )//判断是否区分大小写 { if ( WordSet.m_Word.Find( m_word ) != -1 ) m_ListCtrl.InsertItem( 0, WordSet.m_Word ); } else { // 将比较双方都转换为小写状态 WordSet.m_Word.MakeLower(); m_word.MakeLower(); if ( WordSet.m_Word.Find( m_word ) != -1 ) { // 匹配则将第一个字母转换为大写状态 WordSet.m_Word.SetAt( 0, WordSet.m_Word.GetAt( 0 ) - 32 ); m_ListCtrl.InsertItem( 0, WordSet.m_Word ); } } WordSet.MoveNext(); } } catch ( CDaoException *exception ) { exception->ReportError(); return; } } /////////////////////////////////////////////////////////////////////// 文件: 查找文件: { UpdateData(); if(!m_strfile.GetLength())//得到输入文件名 { AfxMessageBox("请输入要查找的文件"); return ; } WIN32_FIND_DATA fd; m_listfile.ResetContent();//m_listfile 用来保存查找结果 HANDLE hd=::FindFirstFile((LPCTSTR)m_strfile,&fd);// 它有两个参数,第一个是要查找的文件名,第二个是保存查找到的信息,类//型为WIN32_FIND_DAT,返回一个句柄。 if(hd==INVALID_HANDLE_VALUE) {return;} m_listfile.AddString(fd.cFileName); while(FindNextFile(hd,&fd)) //继续查找 { m_listfile.AddString(fd.cFileName); }; FindClose(hd);//关闭查找 } ////////////////////////////////////////////////////////// 其它: 1// 此程序只能运行一次,用互斥来判断程序是否已经运行 编译了可执行程序,不能再次编译,必须先关掉已执行文件 若程序已执行完,则弹出对话框! BOOL CMagicWordApp::InitInstance() { AfxEnableControlContainer(); // 此程序只能运行一次,用互斥来判断程序是否已经运行 HANDLE m_hMutex = CreateMutex( NULL, TRUE, m_pszAppName ); if ( GetLastError() == ERROR_ALREADY_EXISTS ) { AfxMessageBox( "程序已经运行!" ); return FALSE; } #ifdef _AFXDLL Enable3dControls(); #else Enable3dControlsStatic(); #endif //设置对话框背景和文本颜色 SetDialogBkColor(RGB(160,180,220),RGB(0,0,0)); 2 // 删除最大化命令 pSysMenu->DeleteMenu( 4, MF_BYPOSITION ); 3.查找注册表 注册表使用类:E:/兴辉俊武/vc++学习笔记/注册表 void CMyRegistryDlg::OnButton1() { // TODO: Add your control notification handler code here CRegistry reg; BOOL bReturn; DWORD dw=10,dw2; CString s; int i=1,j; bReturn=reg.Open ("Software/0"); bReturn= reg.CreateKey ("vckbase/0"); bReturn= reg.Write ("name","xiaojin");//把xiaojin写入注册表 bReturn= reg.Write ("age",i); bReturn= reg.Write ("sarary",dw); bReturn=reg.Read ("name",&s);//读出来 AfxMessageBox(s); } // 跳转到上次退出时的记录 void CMagicWordDlg::OnJump() { HKEY hKey = 0; BYTE szBuffer[26] = { '/0' }; DWORD dwType = REG_SZ; DWORD dwSize = 27; //查询指定的值 memset( szBuffer, 0, dwSize ); // 如果打开注册表成功,获取键值并实现跳转。 //RegOpenKeyEx(注册表主键的名称,欲打开注册表项的地址,) // RegQueryValueEx(获得键值,欲设置值的名,NULL,定义读取数据类型,所查询注册表键值的内容,) //用&hKey获得键值 if ( RegOpenKeyEx( HKEY_CURRENT_USER, "SOFTWARE//MagicWord", NULL, KEY_ALL_ACCESS, &hKey ) == ERROR_SUCCESS ) { if ( RegQueryValueEx( hKey, "CurrentWord", NULL, &dwType, szBuffer, &dwSize ) == ERROR_SUCCESS ) { CWordDaoSet TempSet; CString strSQL; if ( TempSet.IsOpen() ) TempSet.Close(); strSQL.Format( "SELECT * from WordList WHERE word = '%s'", szBuffer ); TempSet.Open( AFX_DAO_USE_DEFAULT_TYPE, strSQL, 0 ); // 没有找到则不移动m_pSet,保证了OnNext/OnModify()等可以正常操作 if ( TempSet.IsEOF() ) { MessageBox( _T( "单词库中没有这个单词!" ), _T( "跳转失败!" ), MB_OK | MB_ICONASTERISK ); return; } } } // 找到的话,则m_pSet跳转到该处。 m_pSet->MoveFirst();//从第一个开始找 while ( !m_pSet->IsEOF() ) { if ( m_pSet->m_Word == szBuffer ) { PublicAssign(); break; } m_pSet->MoveNext(); } } ///////////////////////////////////////////////////////////////////////// // 注册最后一个被显示的单词信息 void CMagicWordDlg::RegCurrentRecord() { HKEY hKey = 0; char szStatus[26] = { '/0' }; DWORD dwSize = 27; if ( RegOpenKeyEx( HKEY_CURRENT_USER, "SOFTWARE//MagicWord", NULL, KEY_ALL_ACCESS, &hKey ) == ERROR_SUCCESS ) { wsprintf( szStatus, "%s", m_pSet->m_Word ); RegSetValueEx( hKey, "CurrentWord", 0, REG_SZ, (CONST BYTE*) szStatus, dwSize ); RegCloseKey( hKey ); } else { RegCreateKey( HKEY_CURRENT_USER, "SOFTWARE//MagicWord", &hKey ); wsprintf( szStatus, "%s", m_pSet->m_Word ); RegSetValueEx( hKey, "CurrentWord", 0, REG_SZ, (CONST BYTE*) szStatus, dwSize ); RegCloseKey( hKey ); } } 4。定时器 先请看SetTimer这个API函数的原型 UINT_PTR SetTimer( HWND hWnd, // 窗口句柄 UINT_PTR nIDEvent, // 定时器ID,多个定时器时,可以通过该ID判断是哪个定时器 UINT uElapse, // 时间间隔,单位为毫秒 TIMERPROC lpTimerFunc // 回调函数 ); 取消定时器 不再使用定时器后,我们应该调用KillTimer来取消定时,KillTimer的原型如下 BOOL KillTimer( HWND hWnd, // 窗口句柄 UINT_PTR uIDEvent // ID );//在MFC程序中我们可以直接调用KillTimer(int nIDEvent)来取消定时器。 void CGraphDlg::OnDestroy() { CDialog::OnDestroy(); KillTimer(1); } 例如 int iInstallresult; iInstallresult=SetTimer(1, 50, NULL); if(iInstallresult==0) { MessageBox("cannot install timer!"); } SetTimer(m_hWnd,1,1000,NULL); //一个1秒触发一次的定时器 在MFC程序中SetTimer被封装在CWnd类中,调用就不用指定窗口句柄了,例如: UINT SetTimer(1,100,NULL); //函数反回值就是第一个参数值1,表示此定时器的ID号。 第二个参数表示要等待100毫秒时间再重新处理一次。第三个参数在这种方法中一般用NULL。 注意:设置第二个参数时要注意,如果设置的等待时间比处理时间短,程序就会出问题了。 取得系统时间 CString strTimeNow; //得到系统时间 CTime now=CTime::GetCurrentTime(); strTimeNow=now.Format(_T("%Y%m%d")); 时钟显示: 在 OninitDialog()的return TRUE 前面添加:// 完成定时器的安装 int iInstallresult; iInstallresult=SetTimer(1,1000,NULL); if(iInstallresult==0) { MessageBox("fail to install the timer!"); } else CurrentTime(); 在OnTimer()里添加CurrentTime(); void CClockDlg::CurrentTime()//得到系统时间并显示在文本框上 { time_t tCurrentTime; ///声明 char szBuffer [ 256 ]; // 获取系统时间 tCurrentTime = time ( ( time_t* ) NULL ); strftime ( szBuffer, sizeof ( szBuffer ), "%H", localtime ( &tCurrentTime ) ); m_hours = szBuffer; strftime ( szBuffer, sizeof ( szBuffer ), "%M", localtime ( &tCurrentTime ) ); m_minutes = szBuffer; strftime ( szBuffer, sizeof ( szBuffer ), "%S", localtime ( &tCurrentTime ) ); m_seconds = szBuffer; // 将各变量值赋给对话框相应ID号 对应的项 ( GetDlgItem ( IDC_HOUR ) ) -> SetWindowText ( m_hours ); ( GetDlgItem ( IDC_MINUTE ) ) -> SetWindowText ( m_minutes ); ( GetDlgItem ( IDC_SECOND ) ) -> SetWindowText ( m_seconds ); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 网络编程 ////////////////////////////////////////////////////////// 超连接: m_Mail.SetURL(_T("mailto:jingzhou_xu@163.net")); 在图形框中加入图片或动画――调用PictureEX.h类 在E:/兴辉俊武/vc++学习笔记/动画图片操作/加入图片 CPictureEx m_Flag; //IDR_FLAG为图形框id if(m_Flag.Load(MAKEINTRESOURCE(IDR_FLAG),_T("GIF"))) { m_Flag.SetBkColor(RGB(160,180,220)); m_Flag.Draw(); } 求主机名和IP地址#include <afxsock.h> // MFC socket extensions void CGetIPDlg::OnQuery() { char szHostName[128]; char szT[20]; if( gethostname(szHostName, 128) == 0 ) { // Get host adresses m_HostName.SetWindowText(szHostName); struct hostent * pHost; int i; pHost = gethostbyname(szHostName); for( i = 0; pHost!= NULL && pHost->h_addr_list[i]!= NULL; i++ ) { char str[100]; char addr[20]; int j; LPCSTR psz=inet_ntoa (*(struct in_addr *)pHost->h_addr_list[i]); m_IPAddr.AddString(psz); } } } 简单的通信: 服务器:发送一个圆的信息给客户端 struct yuan { int x; int y; int r; int color; } yuan1,*p; void CFasonDlg::OnSend() { // TODO: Add your control notification handler code here UpdateData(TRUE); CString m_Getstring; this->m_Cob.GetLBText(m_Cob.GetCurSel(),m_Getstring); if(m_Getstring==_T("Red")) yuan1.color=1; if(m_Getstring==_T("Green")) yuan1.color=2; if(m_Getstring==_T("Blue")) yuan1.color=3; yuan1.x=m_x; yuan1.y=m_y; yuan1.r=m_r; p=&yuan1; CDSocket m_hSocket; m_hSocket.Create(2330,SOCK_DGRAM); m_hSocket.SendTo( p,sizeof(yuan1),3550,"127.0.0.1"); m_x=0; m_y=0; m_r=0; m_hSocket.Close(); UpdateData(FALSE); } 客户端: void CDASocket::OnReceive(int nErrorCode) { // TODO: Add your specialized code here and/or call the base char buff[256]; int ret=0; ret=Receive(buff,256); if(ret==ERROR) { TRACE("ERROR!"); } else m_pDoc->Presscessding(buff); class CAsyncSocket::OnReceive(nErrorCode); } CJieshouDoc::CJieshouDoc() { // TODO: add one-time construction code here m_hSocket=new CDASocket(this); m_hSocket->Create(3550,SOCK_DGRAM); } void CJieshouDoc::Presscessding(char* lbuff) { buff=(struct yuan*)lbuff; p.x=buff->x; p.y=buff->y; p.r=buff->r; p.color=buff->color; UpdateAllViews(NULL); } void CJieshouView::OnDraw(CDC* pDC) { CJieshouDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here x=pDoc->p.x; y=pDoc->p.y; r=pDoc->p.r; if(pDoc->p.color==1) pDC->SelectObject(new CBrush(RGB(255,0,0))); if(pDoc->p.color==2) pDC->SelectObject(new CBrush(RGB(0,255,0))); if(pDoc->p.color==3) pDC->SelectObject(new CBrush(RGB(0,0,255))); //if(pDoc->p.color==0) // pDC->SelectObject(new CBrush(RGB(255,255,255))); pDC->Ellipse(x-r,y-r,x+r,y+r); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// 外观设计 修改窗口标题栏 void CMainFrame::OnUpdateFrameTitle(BOOL Nada) { //本函数用于修改窗口标题栏 CString csAppName; csAppName.Format(AFX_IDS_APP_TITLE); SetWindowText("动画窗口程序的示例---作者:宁波陈萌 2001.06.17"); } BOOL CMySqlPlusApp::InitInstance() { AfxEnableControlContainer(); 。。。。。。。。。。。。。。。。。。。。。。。 // The one and only window has been initialized, so show and update it. m_pMainWnd->ShowWindow(SW_SHOW); m_pMainWnd->UpdateWindow(); m_pMainWnd->SetWindowText ("窗口标题"); return TRUE; } 修改主窗口风格 AppWizard生成的应用程序框架的主窗口具有缺省的窗口风格,比如在窗口标题条中自动添加文档名、窗口是叠加型的、可改变窗口大小等。要修改窗口的缺省风格,需要重载CWnd::PreCreateWindow(CREATESTRUCT& cs)函数,并在其中修改CREATESTRUCT型参数cs。 CWnd::PreCreateWindow 函数先于窗口创建函数执行。如果该函数被重载,则窗口创建函数将使用CWnd::PreCreateWindow 函数返回的CREATESTRUCT cs参数所定义的窗口风格来创建窗口;否则使用预定义的窗口风格。 CREATESTRUCT结构定义了创建函数创建窗口所用的初始参数,其定义如下: typedef struct tagCREATESTRUCT { LPVOID lpCreateParams; // 创建窗口的基本参数 HANDLE hInstance; // 拥有将创建的窗口的模块实例句柄 HMENU hMenu; // 新窗口的菜单句柄 HWND hwndParent; // 新窗口的父窗口句柄 int cy; // 新窗口的高度 int cx; // 新窗口的宽度 int y; // 新窗口的左上角Y坐标 int x; // 新窗口的左上角X坐标 LONG style; // 新窗口的风格 LPCSTR lpszName; // 新窗口的名称 LPCSTR lpszClass; // 新窗口的窗口类名 DWORD dwExStyle; // 新窗口的扩展参数 } CREATESTRUCT; CREATESTRUCT结构的style域定义了窗口的风格。比如,缺省的MDI主窗口的风格中就包括FWS_ADDTOTITLE(在标题条中显示当前的工作文档名)、FWS_PREFIXTITLE(把文档名放在程序标题的前面)、WS_THICKFRAME(窗口具有可缩放的边框)等风格。由于多种风格参数由逻辑或(“|”)组合在一起的,因此添加某种风格,就只需用“|”把对应的参数加到CREATESTRUCT结构的style域中;删除已有的风格,则需用“&”连接CREATESTRUCT结构的style域与该风格的逻辑非值。 CREATESTRUCT结构的x、y、cx、cy域分别定义了窗口的初始位置和大小,因此,在CWnd::PreCreateWindow 函数中给它们赋值,将能定义窗口的初始显示位置和大小。 下例中的代码将主框窗口的大小将固定为1/4屏幕,标题条中仅显示窗口名,不显示文档名。 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs // 修改主窗风格 cs.style &= ~FWS_ADDTOTITLE; //去除标题条中的文档名 cs.style &= ~WS_THICKFRAME; //去除可改变大小的边框 cs.style |= WS_DLGFRAME; //增加不能改变大小的边框 // 确定主窗的大小和初始位置 int cxScreen = ::GetSystemMetrics(SM_CXSCREEN);//获得屏幕宽 int cyScreen = ::GetSystemMetrics(SM_CYSCREEN); //获得屏幕高 cs.x = 0; // 主窗位于左上角 cs.y = 0; cs.cx = cxScreen/2; // 主窗宽为1/2屏幕宽 cs.cy = cxScreen/2; // 主窗高为1/2屏幕高 return CMDIFrameWnd::PreCreateWindow(cs); } //设置对话框背景和文本颜色 SetDialogBkColor(RGB(160,180,220),RGB(0,0,0)); //对话框居中显示 CRect dlgRect; GetWindowRect(dlgRect); CRect desktopRect; GetDesktopWindow()->GetWindowRect(desktopRect); MoveWindow( (desktopRect.Width() - dlgRect.Width()) / 2, (desktopRect.Height() - dlgRect.Height()) / 2, 0, 0 ); 文档设置背景色 public: CBrush m_wndbkBrush; COLORREF m_crBackground; CAnimatewindowView::CAnimatewindowView() { // TODO: add construction code here m_crBackground=RGB(146,177,231); m_wndbkBrush.CreateSolidBrush(m_crBackground); } BOOL CAnimatewindowView::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default CView::OnEraseBkgnd(pDC); CRect rect; GetClientRect(&rect); pDC->FillRect(&rect,&m_wndbkBrush);//设置背景色 return TRUE; } 菜单------CMenu CToolBar 取得菜单项指针: CWnd*pParent=GetParent();//得到指向主窗口的指针 CMenu*pMenu=pParent->GetMenu();//得到系统菜单 CMenu*SubMenu=pMenu->GetSubMenu(0);//得到子菜单 初始化函数 菜单操作函数 菜单项操作函数 UINT CheckMenuItem(UINT nEDCheckItem, UINT nCheck) nEDCheckItem---指定要被复选的菜单项,它既可以是常规菜单项,也可以是弹出菜单项。 nCheck------指定复选方式: MF_BYCOMMAND:通过ID号选择菜单该值为默认值,Windows检查CMenu对象拥有的所有的弹出式菜单项。因此,除非存在完全相同的菜单项,否则使用菜单栏的CMenu对象完全可以,而不必区分弹出式菜单和菜单栏菜单。 MF_BYPOSITION:菜单项的位置如果为第一项,则nEDCheckItem 为0 MF_CHECKED:复选指定菜单项。 MF_ENABLED:解除指定菜单项的选择 例:SubMenu-> CheckMenuItem(ID_LXC, MF_CHECKED); UINT EnableMenuItem(UNIT nIDEnableItem,UINT nEnable) 函数将使能、禁止、加灰指定菜单项 返回值:调用成功,返回非零值,否则返回零值。函数将返回菜单项先前的状态。 nIDEnableItem:指定了将要操作的菜单项 nEnable:指定了将要采取的操作, MF_BYCOMMAND:通过ID号选择菜单项 MF_BYPOSITION: MF_DISABLED:使菜单项无效,即使菜单不能被选中,但并不用灰色显示。 MF_ENABLED:使菜单项有效 MF_GRAYED:除去菜单项前的检查标记 CToolBar 构造函数: 。SetSizes:调用该函数设置工具栏按钮大小,原型: Void SetSizes(SIZE sizeButton,SIZE sizeImage); sizeButton:指定了工具栏按钮的尺寸。 sizeImage:指定了工具栏位图中按钮图像的尺寸。 属性操作函数: 。SetButtonText:设置工具栏按钮的文本。 BOOL SetButtonText() 1、定制工具条 很酷的功能,:-).... 首先在Create时使用 CCS_ADJUSTABLE风格。 调用CToolBar::Customize(void); 此外记得使用RestoreState,SaveState。 2、增加文字 调用CToolBar::SetButtonText(...) 调用CToolBar::SetSizes(...)将按钮尺寸放大到适当大小。 3、TrueColor image on ToolBar,生成和初始化工具栏,方法很简单有些不可思议。 m_bmToolbarHi为框架窗口的成员变量。CToolBar m_wndToolBar; 在OnCreate中 if (!m_wndToolBar.Create(this) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { 。。。。。。。。。//增加工具栏的其它功能 TRACE0("Failed to create toolbar/n"); return -1; // fail to create } 4、增加工具栏按钮停放功能,可以改变工具栏的位置。 m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);// CBRS_ALIGN_ANY使工具栏停放在四个窗口边的任意边框。调用CControlBar中的EnableDocking函数,允许工具栏本身的停放 EnableDocking(CBRS_ALIGN_ANY);//调用CFrameWnd中的EnableDocking函数,允许主窗口停放 DockControlBar(&m_wndToolBar); m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);// CBRS_TOOLTIPS:激活工具栏提示特性;CBRS_FLYBY:使光标放在键上时 显示命令提示。 CenterWindow();//使窗口运行时居于屏幕正中央 动画(图片、声音) CListBox:列表框控件类,管理列表框的显示和选择 CListBox m_AccessList; m_AccessList.ResetContent();//清空列表框 m_AccessList.AddString( strName + " --> "+strAge );//向列表框中添加数据 CDC 设备情景对象类,是其它设备情景的基类 CpaintDC:它的构造函数调用BeginPaint,它的析构函数调用 EndPaint。 生成自定义的绘图工具: CPaintDC dc(this); CPen MyNewPen; COLORREF mm_color=dlg.m_color;//颜色对话框选择的颜色 MyNewPen.CreatePen(PS_SOLID,10,mm_color);//RGB(255,0,0)初始化 //调用CDC::SelectObject把生成的对象调入设备情景 CPen* pOriginalPen; pOriginalPen=dc.SelectObject(&MyNewPen); CRect MyRectangle(30,10,20+m_Radius*2,10+m_Radius*2); //通过m_Radius的大小显示动态圆:右图 dc.Ellipse(&MyRectangle);//画圆 dc.SelectObject(pOriginalPen); CDialog::OnPaint(); 设置文本的颜色 void CAnimatewindowView::OnDraw(CDC* pDC) { CAnimatewindowDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here CRect rect; GetClientRect(&rect); //取客户区尺寸大小 pDC->SetBkMode(RGB(255,255,255));//设置背景颜色模式为透明色 pDC->SetTextColor(RGB(255,255,0));//设置文本前景色为黄色 pDC->TextOut((rect.Width()-280)/2,(rect.Height()-30)/2,"用一点点动画装饰您的程序,祝您好运!"); //输出文本,同时用客户区宽度与高度计算文本输出位置,280为文本长度, //30为文本高度,这个值为经验值并不专业,可以用别的方法精确计算, //但对于本文没有必要。 } 设置文档的背景颜色: public: CBrush m_wndbkBrush; COLORREF m_crBackground; CAnimatewindowView::CAnimatewindowView()//初始化 { // TODO: add construction code here m_crBackground=RGB(146,177,231); m_wndbkBrush.CreateSolidBrush(m_crBackground); } BOOL CAnimatewindowView::OnEraseBkgnd(CDC* pDC) //以CView为基类 { // TODO: Add your message handler code here and/or call default CView::OnEraseBkgnd(pDC); CRect rect; GetClientRect(&rect); pDC->FillRect(&rect,&m_wndbkBrush);//设置背景色 return TRUE; } HBRUSH CKechengView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) // 以CFormView为基类 { HBRUSH hbr = CFormView::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: Change any attributes of the DC here // if (nCtlColor==CTLCOLOR _ DLG ) return (HBRUSH) m_wndbkBrush.GetSafeHandle ( ); //return CFormView : : OnCtlColor (pDC, pWnd , nCtlColor); // TODO: Return a different brush if the default is not desired return hbr; } CBitmap类:提供对位图的操作。 用绘图函数生成位图,基本过程如下: 1. 创建空白位图对象; 2. 创建内存设备描述表DC对象 3. 将位图选入内存DC 4. 利用内存DC对象的成员函数在位图内绘制位图 LoadBitmap:从资源加载位图,并将它连接到CBitmap对象 GetBitmap:取得CBitmap对象的信息赋给一个BITMAP结构体 CDC MemDC; //创建内存DC BITMAP bm; //创建位图结构变量 CBitmap m_bitmap; //创建位图对象 CBitmap *old_bitmap; //创建位图对象指针 m_bitmap.LoadBitmap(IDB_BITMAP1);//拷贝资源位图 m_bitmap.GetBitmap(&bm);//得到位图结构中的大小信息 制作闪烁效果: #include "LjxWnd.h"//在E:/兴辉俊武/vc++学习笔记/动画图片操作/闪屏图形特技效果的实现 BOOL CAnimatesplashApp::InitInstance() { AfxEnableControlContainer(); #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif //增加的代码 CLjxWnd *ljxljx=new CLjxWnd; //建立一个新窗口对象 ljxljx->CreatLjxWnd (); //创建窗口――函数中重载功能 // CWnd类功能 ljxljx->CenterWindow (); //在屏幕中央 ljxljx->ShowWindow (SW_SHOW); //显示窗口 ljxljx->UpdateWindow (); //更新窗口,激活OnPait函数 Sleep(2000); //等待函数指定秒钟 if (ljxljx!=NULL) ljxljx->SendMessage (WM_CLOSE); //关闭窗口 //增加的代码结束 CAnimatesplashDlg dlg; //显示对话框 m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE; } 控件类添加背景位图基本过程如下: 在树型控件中使用背景位图 CMyTreeCtrl继承类 CTreeCtrl CMyTreeCtrl m_CtrlTree;//控件变量 BOOL CTreeDlg::OnInitDialog() { ………. m_CtrlTree.SetBKImage("cibas.bmp");// SetBKImage为实现背景位图的函数在CMyTreeCtrl中实现 ………. } 在MFC程序中显示JPG/GIF图像 在“E:/兴辉俊武/vc++学习笔记/动画图片操作/JPG图像加载及超连接”定义了所需的类 CPictureCtrl 使你可以在任何对话框或窗口中把图像作为子窗口显示。 例如: 关于对话框中加载IDC_MYIMAGE图像 class CAboutDialog : public CDialog { protected: CPictureCtrl m_wndPict; virtual BOOL OnInitDialog(); }; BOOL CAboutDialog::OnInitDialog() { m_wndPict.SubclassDlgItem(IDC_MYIMAGE,this);// IDC_MYIMAGE和变量m_wndPict建立联系 return CDialog::OnInitDialog(); } 在文档/视图中加载JPG/GIF图像 在doc.h中 #pragma once #include "Picture.h" protected: CPicture m_pict; public: CPicture* GetPicture() { return &m_pict; doc.cpp #include <afxdisp.h> #include <afxpriv2.h> void CPictureDoc::Serialize(CArchive& ar)//打开图片在文档中显示 { if (ar.IsLoading()) { VERIFY(m_pict.Load(ar)); } else { } } BOOL CPictureDoc::OnNewDocument()/*为了使程序更实用,CPictureDoc::OnNewDocument从程序资源数据加载了一幅图像。为了显示这幅图像,CPictureView::OnDraw要调用CPicture::Render。这样程序一启动便会显示一幅默认的图像。*/ { m_pict.Load(IDR_MAINFRAME); return TRUE; } void CPictureView::OnDraw(CDC* pDC) { CPictureDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CPicture* ppic = pDoc->GetPicture(); ASSERT(ppic); if (*ppic) { CRect rc; GetImageRect(rc);// GetImageRect是CPictureView类的一个成员函数 ppic->Render(pDC,rc); } } AnimateWindow函数:实现动画效果 函数原型:BOOL AnimateWindow(HWND hWnd,DWORD dwTime,DWORD dwFlags)。 函数功能:该函数能在显示与隐藏窗口时产生两种特殊类型的动画效果:滚动动画和滑动动画。 参数含义: hWnd:指定产生动画的窗口的句柄。 dwTime:指明动画持续的时间(以微秒计),完成一个动画的标准时间为200微秒。 dwFags:指定动画类型。这个参数可以是一个或多个下列标志的组合。标志描述: AW_SLIDE:使用滑动类型。缺省则为滚动动画类型。当使用AW_CENTER标志时,这个标志就被忽略。 AW_ACTIVATE:激活窗口。在使用了AW_HIDE标志后不能使用这个标志。 AW_BLEND:实现淡出效果。只有当hWnd为顶层窗口的时候才可以使用此标志。 AW_HIDE:隐藏窗口,缺省则显示窗口。 AW_CENTER:若使用了AW_HIDE标志,则使窗口向内重叠,即收缩窗口;若未使用AW_HIDE标志,则使窗口向外扩展,即展开窗口。 AW_HOR_POSITIVE:自左向右显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时,该标志将被忽略。 AW_VER_POSITIVE:自顶向下显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时,该标志将被忽略。 AW_VER_NEGATIVE:自下向上显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时,该标志将被忽略。 返回值:如果函数成功,返回值为非零;如果函数失败,返回值为零。在下列情况下函数将失败: 窗口使用了窗口边界;窗口已经可见仍要显示窗口;窗口已经隐藏仍要隐藏窗口。 实例:动画窗口的实现 在工程里的StdAfx.h文件靠前位置加上如下定义 #undef WINVER #define WINVER 0X500 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { …… AnimateWindow(GetSafeHwnd(),1000,AW_CENTER); return 0; } void CMainFrame::OnClose() { // TODO: Add your message handler code here and/or call default AnimateWindow(GetSafeHwnd(),1000,AW_HIDE|AW_CENTER); //AnimateWindow(GetSafeHwnd(),1000,AW_HIDE|AW_BLEND); CFrameWnd::OnClose(); } 实现对话框的分块消失:E:/兴辉俊武/vc++学习笔记/动画图片操作/实现窗体分块消失 void CRWAccessDlg::OnOK() { CWindowAnima wa(this); //CWindowAnima类在上文件夹中 //将窗体分为6块动画窗体效果 wa.Scatter6(90,10); CDialog::OnOK(); } 窗口 CSplitterWnd类 CSplitterWnd m_wndSpMain; BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) //在此生成分割函数 { // TODO: Add your specialized code here and/or call the base class if (!m_wndSpMain.CreateStatic(this, 1, 2)) //创建一行两列的分割窗口 { TRACE0("Failed to create splitter window/n"); return FALSE; } // Get the client rect first for calc left pane size // create the left tree view first. if (!m_wndSpMain.CreateView(0, 0, RUNTIME_CLASS(CPppView),CSize(200, 200), pContext)) { //在0行0列加入CPppView视图 TRACE0("Failed to create left pane view/n"); return FALSE; } // The right pane is a frame which and contain several different views. if (!m_wndSpMain.CreateView(0, 1, RUNTIME_CLASS(CShengView), CSize(100,100), pContext)) { //在0行1列加入CShengView函数 TRACE0("Failed to create right pane frame/n"); return FALSE; } return TRUE; }