VC\MFC 编程经验总结—2(转)

来源:互联网 发布:c语言打印标准杨辉三角 编辑:程序博客网 时间:2024/05/19 03:18
 如何处理ComboBox中的回车键?避免退出程序? 
  在一般的EDIT中采用的方法是处理PretranlateMessage(),执行代码 
  CWnd  *pWnd   GetFocus(); 
  if(pWnd  !=  NULL) 
 
     if(pWnd  ==  GetDlgItem(IDC_EDIT1) 
     
           ...//IDC_EDIT1具有焦点 
     
 
    
 但在ComboBox中好象不同,是ComboBox的编辑控件得到了焦点,所以判断代码: 
  BOOL  CDlg::PreTranslateMessage(MSG  *pMsg) 
 
       if(pMsg->message==WM_KEYDOWN  &&  pMsg->wParam  ==  VK_RETURN) 
       
             CWnd  *pWnd   GetFocus(); 
             if(pWnd  !=  NULL) 
             
                   if(pWnd->GetParent()  ==  GetDlgItem(IDC_COMBO1)//更改ID 
                   
                               return  TRUE; 
                   
             
       
       return  CDialog::PreTranslateMessage(pMsg); 
 
  
 //------------------------------------------------- 
  动态创建的组合框如何设置下拉列表框的高度? 
  m_combo.Create(WS_CHILD   WS_VISIBLE   WS_VSCROLL  CBC_SORT   CBC_DROPDOWNLIST   WS_TABSTOP,  CRect(320,10,580,280),this,114); 
 //CRect的最后一个参数(这里是280)就表示下拉大小 
  
 //------------------------------------------------- 
  是否能不选择下拉列表样式而禁止用户输入值,有什么方法可以实现? 
  将下拉列表的编辑控件设置为只读的,方法如下: 
  CComboBox  *pcombo; 
  CWnd  *pWnd   pcombo->GetWindow(GW_CHILD); 
  while(pWnd) 
 
     char  classname[256]; 
     ::GetClassName(pWnd->m_hWnd,classname,256) 
     if(strcmp(classname,"edit")  ==   0) 
     
           CEdit  *pEdit; 
           pEdit   new  CEdit(); 
           pEdit->SubClassWindow(pWnd->m_hWnd); 
           pEdit->SetReadOnly(); 
           pWnd   pWnd->GetNextWindow(); 
           delete  pEdit; 
     
     if(pWnd) 
           pWnd   pWnd->GetNextWindow(); 
 
  
 //------------------------------------------------- 
  ComboBox的自定义弹出菜单,想在右击组合框的编辑部分的时候弹出菜单? 
  一种方法就是在CCustomCombo的OnCtlColor函数里进行,生成ComboBox中编辑框的子类,示例: 
  HBRUSH  CCustomCombo::OnCtlColor(CDC  *pDC,CWnd  *pWnd,UINT  nCtlColor) 
 
     if(nCtlColor  ==  CTLCOLOR_EDIT) 
     
           if(m_edit.GetSafeHwnd()==NULL) 
                 m_eidt.SubClassWindow(pWnd->GetSafeHwnd()); 
     
     HBRUSH  hbr   CComboBox::OnCtlColor(pDC,pWnd,nCtlColor); 
     return  hbr; 
 
 //其中m_edit是CEdit类的实现,它在WM_RBUTTONUP上显示右键菜单 
  
 //------------------------------------------------- 
  如何给按钮加位图 
   
  对动态创建的按钮: 
  CButton  button; 
 button.Create(_T("My  Button"),WS_CHILD   WS_VISIBLE   BS_BITMAP,CRect(10,10,60,50),pParentWnd,1); 
 button.SetBitmap(::LoadBitmap(NULL,MAKEINTRESOURCE(IBM_CHECK))); 
  或者修改风格: 
  UINT  Style   Button.GetButtonStyle(); 
  Style   Style   BS_BITMAP; 
 Button.SetBitmap(::LoadBitmap(NULL,MAKEINTRESOURCE(IBM_CHECK))); 
  
 //------------------------------------------------- 
  如何在CButton派生类中以及父对话框中捕获BN_CLICKED消息? 
  于WM_NOTIFY消息相反,通知消息BN_CLICKED作为WM_COMMAND消息发送。因此应用程序应该使用ON_CONTROL_REFLECT_EC而不是ON_NOTIFY_REFLECT 
  
 //------------------------------------------------- 
  如何判断某个对象是否具有当前焦点? 
  return  (CWnd::GetFocus()  ==  pWnd); 
  
 //------------------------------------------------- 
  如何设置编辑控件的数字限制属性? 
 
  long  Style   GetWindowLong(m_EditCtrl.m_hWnd,GWL_STYLE); 
  Style  |=  ES_NUMBER; 
 SetWindowLong(m_EditCtrl.m_hWnd,GWL_STYLE,Style); 
  
 //------------------------------------------------- 
  希望在LISTCTRL中显示文件,如何才能得到explorer使用的相同图象? 
  可以将系统的ImageList加到LISTCTRL上,然后用具有SHGFI_ICON标志的SHGetFileInfo获取适当的图标索引: 
  //图象列表设置 
  HIMAGELIST  himagelist; 
  SHFILEINFO  fi; 
  CImageList  m_smalllist; 
  //得到系统小图标列表的句柄 
  himagelist   (HIMAGELIST)SHGetFileInfo((LPCTSTR)_T("C:\\"),0,&fi,sizeof(SHFILEINFO),SHGFI_SYSICONINDEX   SHGFI_SMALLICON); 
  //添加到小图象列表 
 m_smalllist.Attach(himagelist); 
  //设置LISTCTRL的图象列表 
 m_listCtrl.SetImageList(&m_smalllist,LVSIL_SMALL); 
  //分离图象列表 
  m_smalllist.Detach(); 
  
 //------------------------------------------------- 
  如何在列表的任何一列显示图标,而不是第一列? 
   
  LV_ITEM  item; 
  ... 
  item.mask   LVIF_TEXT   LVIF_IMAGE   LVIF_STATE   LVIF_PARAM; 
  item.iItem   ...//设置行号 
  item.lParam   ...//如何需要就设置lparam参数 
 item.iSubItem   ...//设置列号,从0开始的 
 item.stateMask   LVIS_STATEIMAGEMASK; 
  item.state   INDEXTOSTATEIMAGEMASK(...);//参数为图标号 
  item.iImage   ...//设置图标号 
  item.pszText   ...//显示文本 
  //插入新项 
 m_listctrl.InsertItem(&item); 
  //现在设置图标 
 m_listctrl.SetItemText(0,4,szField); 
  
 //------------------------------------------------- 
  给LISTBOX添加新项时如何实现自动下滚? 
  在调用AddString后,添加如下代码: 
 m_listbox.SetTopIndex(m_listbox.GetCount()-1); 
  
 //------------------------------------------------- 
  listBox的文本超过框的宽度时,如何让水平滚动条正常工作? 
  用下面的代码,设置滚动条的宽度为最长的字符串宽度 
  void  SetHorizontalExtent(CListBox  &listbox) 
 
         int  index   listbox.GetCount(); 
         if(index  ==  LB_ERROR) 
               return; 
         int  nExtent    0; 
         if(index) 
         
                 CDC  *pDC   listbox.GetDC(); 
   CFont  *poldfont   pDC->SelectObject(listbox.GetFont()); 
   CString  s; 
   SIZE  text; 
   LONG  maxtxt    0; 
   whilw(index--) 
   
                           listbox.GetText(index,s); 
             text   pDC->GetOutputTextExtent(s); 
             if(text.cx   maxtxt) 
                                   maxtxt   text.cx; 
     
                 text.cx   maxtxt; 
             pDC->LPToDP(&text); 
             nExtent   text.cx+2; 
             pDC->SelectObject(poldfont); 
             listbox.ReleaseDC(pDC); 
               
         listbox.SetHorizontalExtent(nExtent); 
 
  
 //------------------------------------------------- 
  在拆分视图的时候,创建了四个视图(2行2列),右下的是CFormView,其他的都是CView,在CMainFrame的OnCreateCilent不管怎么指定CRect的大小,下方的两个视图都占了整个窗口,需要拖动! 
  一般只需要在OnCreateClient的末尾添加: 
 m_wndSpitter.SetRowInfo(0,200,0);//添加此行代码  
 
 //------------------------------------------------- 
  如何指定拆分窗口的最小宽度? 
  使用CSpitterWnd::SetColumnInfo() 
     void  SetColumnInfo(int  col,  //指定列 
               int  deal,  //理想宽度(像素) 
               int  cxmin);  //最小宽度(像素) 
   在使用SetColumnInfo之后还应该调用RecalLayout();重新调整布局。 
      
 //-------------------------------------------------- 
  如何判断工具栏是水平还是垂直的? 
  if((m_toolbar.GetBarStyle()   CBRS_ALIGN_LEFT)  ==  CBRS_ALIGN_LEFT  ||   
  
 (m_toolbar.GetBarStyle()   CBRS_ALIGN_RIGHT)  ==  CBRS_ALIGN_RIGHT) 
           AfxMessageBox("vertical"); 
     else 
           AfxMessageBox("horizontal"); 
  
 //-------------------------------------------------- 
  编程方式修改工具栏按钮的可见性? 
  示例代码: 
  DWORD  style   m_toolbar.GetButtonStyle(nIndex); 
  if(m_bHide) 
       m_toolbar.SetButtonStyle(nIndex,style   ~WS_VISIBLE); 
  else 
       m_toolbar.SetButtonStyle(nIndex,style   WS_VISIBLE); 
  m_bHide   !m_bHide; 
  
 //-------------------------------------------------- 
  如何在状态栏添加按钮并响应? 
  创建一个从CButton派生的CMyButton类,在主框架类添加CMyButton类的成员变量,然后在OnCreate函数中创建按钮,并把它和状态栏关联起来: 
 m_mybtn.Create("MyButton",WS_CHILD   VISIBLE,CRect(0,0,60,20),&m_WndStatusBar,0); 
 通过处理BN_CLICKED消息,可以在CMyButton类中处理所有的点击事件 
  
 //-------------------------------------------------- 
  如何隐藏属性CPropertySheet的标题栏,使用ModifyStyle(WINDOW_CAPTION,0)没有效果 
  创建自己的CPropertySheet派生类,并覆盖OnInitDialog,转到默认的情况后,使用ModifyStyle来删除WS_CAPTION标志 
  
 //-------------------------------------------------- 
  如何让属性页有两行标签? 
  从CPropertySheet派生类,添加PreCreateWindow的处理,在调用基类之前添加代码: 
   cs.style  |=  TCS_MULTILINE; 
  
 //------------------------------------------------------ 
  如何在属性表的两个页之间传递数据? 
   
 CPropertyPage有一个成员函数QuerySiblings(WPARAM,  LPARAM)。应用程序可以使用这个函数。 
 QuerySiblings生成一条PSM_QUERYSIBLINGS消息,它传递给所有的兄弟,也就是属性表上的其他属性页。      一般可创建一个所有页可见的枚举,如: 
   enum{QUERY_MY_STRING,    QUERY_SOMETHING_ELSE,.......} 
 然后,在一个属性页需要其他属性页中的信息时,使用代码: 
  CString  myString; 
  if(lL  ==  QuerySiblings(QUERY_MY_STRING,(LPARAM)&myString)) 
 
                   ....//获取字符串 
 
 提供字符串的页处理PSM_QUERYSIBLINGS消息: 
  LRESULT  CPageThatHasString::OnQuerySiblings(WPARAM  wParam,  LPARAM  lParam) 
 
                 if(QUERY_MY_STRING  ==  wParam) 
               
                             *((CString  *)lParam)   _T(“Test  String“); 
                               return  1L; 
               
               else 
                             return  0L; 
 
  
 //---------------------------------------------------------- 
    如何让属性页具有两行标签? 
     
 从CPropertySheet派生一个自己的类,添加一个PreCreateWindow的处理,然后在调用基类的处理前加如下代码:cs.style  |=  TCS_MULTILINE; 
  
 //----------------------------------------------------------- 
    如何隐藏属性页的标题栏? 
     
 从CPropertySheet派生一个自己的类,并覆盖OnInitDialog,在转到默认的情况以后,使用  ModifyStyle来删除标题栏标志WS_CAPTION。 
       ModifyStyle(WS_CAPTION,0); 
  
 //------------------------------------------------------------------- 
  如何枚举桌面项目? 
 
  得到指向IShellFolder接口的指针 
  得到指向IMalloc接口的指针 
  得到指向IEnumIDList接口的指针 
  提取枚举中下一项目的PIDL 
  测定PIDL代表的标志符的类型 
  处理该项目 
  释放PIDL分配的内存 
  重复4到7步,知道所有的项目都枚举完 
  释放IShellFolder  IMalloc  IEnumIDList接口的指针 
  
 LPSHELLFOLDER  lpshellfolder; 
  LPMALLOC  lpmalloc; 
  LPENUMIDLIST  lpidlist; 
  m_namecount    0; 
  HRESULT  hr   SHGetDestopFolder(&lpshellfolder); 
  if(hr  ==  NOERROR) 
 
         hr   ::SHGetMalloc(&lpmalloc); 
         if(hr  ==  NOERROR) 
           
                 hr   lpshellfolder->EnumObject(NULL,SHCONTF_FOLDERS   SHCONTF_NONFOLDERS,&lpidlist); 
                 if(hr  ==  NOERROR) 
                           ProcessFolder(lpshellfolder,lpmalloc,lpidlist);//custom  deal  function 
                 lpmalloc->Release(); 
                 lpidlist->Release(); 
                 InValidate(); 
         
         lpshellfolder->Release(); 
 
    
  void  ***::ProcessFolder(LPSHELLFOLDER  lpshellfolder,LPMALLOC  lpmalloc,LPENUMIDLIST  lpidlist) 
 
       STRRET  strret; 
       ULONG  numfetch; 
       LPITEMIDLIST  lpitemlist; 
       HRESULT  hr   lpidlist->Next(1,&lpitemlist,&numfetch); 
       while(hr  ==  NOERROR) 
       
               ULONG  attributes   SFGAO_FOLDER; 
               lpshellfolder->GetAttributes(1,(const  struct  _ITEMIDLIST  **)&lpitemlist,&attributes); 
               if(attributes   SFGAO_FOLDER) 
               
                       hr   lpshellfolder->GetDiaplayNameOf(lpitemlist,SHGDN_NORMAL,&strret); 
                       if(m_nameCount   20) 
                               m_names[m_namecount++]   strret.str; 
               
               lpmalloc->Free(lpitemlist); 
               hr   lpidlist->Next(1,&lpitemlist,&numfetch); 
       
 
 //------------------------------------------------------------------- 
    如何创建桌面快捷方式? 
  A: 
  initialize  com 
  create  LShellLink  Object 
  Use  IShellLink  interface  to  get  the  pointer  about  IPersistFile 
  Use  IShellLink  interface  to  initialize  link 
  Use  LPersistFile  interface  to  save  the  link 
  Release  all  the  com  pointer 
  Com  return  to  previous  status 
  
   
  HRESULT  hr   CoInitialize(NULL); 
  if(hr  ==  S_OK) 
 
     ...//Continue 
 
  
 
  IShellLink  *pshelllink; 
  pshelllink   CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(void  **)&pshelllink); 
  
 
  IPersistFile  *persistfile; 
  persistfile   pshelllink->QueryInterface(IID_IPersistFile,(void  **)&persistfile); 
  
 
 pshelllink->SetPath("C:\\config.sys");   
 pshelllink->SetDescription("ShortCut  to  config.sys"); 
  
 
  char  path[MAX_PATH]; 
 GetWindowsDirectory(path,MAX_PATH); 
  int  len   strlen(path); 
 strcpy(&path[len],"\\desktop\\config.lik"); 
  //change  the  char  from  ANSI  to  UNICODE 
  OLECHAR  widepath[MAX_PATH]; 
 MultiByteToWideChar(CP_ACP,0,path,-1,widepath,MAX_PATH); 
 persistfile->Save(widepath,TRUE); 
  
 
 pshelllink->Release(); 
 psersistfile->Release(); 
  
 
  CoUnInitialize();
转自:http://blog.sina.com.cn/s/blog_5d8cc6410100e42b.html
原创粉丝点击