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

44 篇文章 0 订阅
26 篇文章 0 订阅
  如何处理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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值