MFC------------ Q & A

    技术2022-05-12  13

    Q 如何处理ComboBox中的回车键?避免退出程序?A 在一般的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);}

    //-------------------------------------------------Q 动态创建的组合框如何设置下拉列表框的高度?A m_combo.Create(WS_CHILD | WS_VISIBLE | WS_VSCROLL CBC_SORT | CBC_DROPDOWNLIST | WS_TABSTOP, CRect(320,10,580,280),this,114);//CRect的最后一个参数(这里是280)就表示下拉大小

    //-------------------------------------------------Q 是否能不选择下拉列表样式而禁止用户输入值,有什么方法可以实现?A 将下拉列表的编辑控件设置为只读的,方法如下: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();}

    //-------------------------------------------------Q ComboBox的自定义弹出菜单,想在右击组合框的编辑部分的时候弹出菜单?A 一种方法就是在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上显示右键菜单

    //-------------------------------------------------Q 如何给按钮加位图A 对动态创建的按钮: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)));

    //-------------------------------------------------Q 如何在CButton派生类中以及父对话框中捕获BN_CLICKED消息?A 于WM_NOTIFY消息相反,通知消息BN_CLICKED作为WM_COMMAND消息发送。因此应用程序应该使用ON_CONTROL_REFLECT_EC而不是ON_NOTIFY_REFLECT

    //-------------------------------------------------Q 如何判断某个对象是否具有当前焦点?A return (CWnd::GetFocus() == pWnd);

    //-------------------------------------------------Q 如何设置编辑控件的数字限制属性?Along Style = GetWindowLong(m_EditCtrl.m_hWnd,GWL_STYLE);Style |= ES_NUMBER;SetWindowLong(m_EditCtrl.m_hWnd,GWL_STYLE,Style);

    //-------------------------------------------------Q 希望在LISTCTRL中显示文件,如何才能得到explorer使用的相同图象?A 可以将系统的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();

    //-------------------------------------------------Q 如何在列表的任何一列显示图标,而不是第一列?A 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);

    //-------------------------------------------------Q 给LISTBOX添加新项时如何实现自动下滚?A 在调用AddString后,添加如下代码:m_listbox.SetTopIndex(m_listbox.GetCount()-1);

    //-------------------------------------------------Q listBox的文本超过框的宽度时,如何让水平滚动条正常工作?A 用下面的代码,设置滚动条的宽度为最长的字符串宽度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);}

    //-------------------------------------------------Q 在拆分视图的时候,创建了四个视图(2行2列),右下的是CFormView,其他的都是CView,在CMainFrame的OnCreateCilent不管怎么指定CRect的大小,下方的两个视图都占了整个窗口,需要拖动!A 一般只需要在OnCreateClient的末尾添加:m_wndSpitter.SetRowInfo(0,200,0);//添加此行代码

    //-------------------------------------------------Q 如何指定拆分窗口的最小宽度?A 使用CSpitterWnd::SetColumnInfo()  void SetColumnInfo(int col, //指定列       int deal, //理想宽度(像素)       int cxmin); //最小宽度(像素) 在使用SetColumnInfo之后还应该调用RecalLayout();重新调整布局。  //--------------------------------------------------Q 如何判断工具栏是水平还是垂直的?A if((m_toolbar.GetBarStyle() & CBRS_ALIGN_LEFT) == CBRS_ALIGN_LEFT ||

    (m_toolbar.GetBarStyle() & CBRS_ALIGN_RIGHT) == CBRS_ALIGN_RIGHT)     AfxMessageBox("vertical");  else     AfxMessageBox("horizontal");

    //--------------------------------------------------Q 编程方式修改工具栏按钮的可见性?A 示例代码: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;

    //--------------------------------------------------Q 如何在状态栏添加按钮并响应?A 创建一个从CButton派生的CMyButton类,在主框架类添加CMyButton类的成员变量,然后在OnCreate函数中创建按钮,并把它和状态栏关联起来:m_mybtn.Create("MyButton",WS_CHILD | VISIBLE,CRect(0,0,60,20),&m_WndStatusBar,0);通过处理BN_CLICKED消息,可以在CMyButton类中处理所有的点击事件

    //--------------------------------------------------Q 如何隐藏属性CPropertySheet的标题栏,使用ModifyStyle(WINDOW_CAPTION,0)没有效果A 创建自己的CPropertySheet派生类,并覆盖OnInitDialog,转到默认的情况后,使用ModifyStyle来删除WS_CAPTION标志

    //--------------------------------------------------Q 如何让属性页有两行标签?A 从CPropertySheet派生类,添加PreCreateWindow的处理,在调用基类之前添加代码: cs.style |= TCS_MULTILINE;

    //------------------------------------------------------Q 如何在属性表的两个页之间传递数据?A 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;}

    //----------------------------------------------------------Q  如何让属性页具有两行标签?A  从CPropertySheet派生一个自己的类,添加一个PreCreateWindow的处理,然后在调用基类的处理前加如下代码:cs.style |= TCS_MULTILINE;

    //-----------------------------------------------------------Q  如何隐藏属性页的标题栏?A  从CPropertySheet派生一个自己的类,并覆盖OnInitDialog,在转到默认的情况以后,使用 ModifyStyle来删除标题栏标志WS_CAPTION。   ModifyStyle(WS_CAPTION,0);//-------------------------------------------------------------------Q 如何枚举桌面项目?A1 得到指向IShellFolder接口的指针2 得到指向IMalloc接口的指针3 得到指向IEnumIDList接口的指针4 提取枚举中下一项目的PIDL5 测定PIDL代表的标志符的类型6 处理该项目7 释放PIDL分配的内存8 重复4到7步,知道所有的项目都枚举完9 释放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);   }}//-------------------------------------------------------------------Q  如何创建桌面快捷方式?A:1 initialize com2 create LShellLink Object3 Use IShellLink interface to get the pointer about IPersistFile4 Use IShellLink interface to initialize link5 Use LPersistFile interface to save the link6 Release all the com pointer7 Com return to previous status

    1 HRESULT hr = CoInitialize(NULL);if(hr == S_OK){  ...//Continue}

    2IShellLink *pshelllink;pshelllink = CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(void **)&pshelllink);

    3IPersistFile *persistfile;persistfile = pshelllink->QueryInterface(IID_IPersistFile,(void **)&persistfile);

    4pshelllink->SetPath("C://config.sys"); pshelllink->SetDescription("ShortCut to config.sys");

    5char path[MAX_PATH];GetWindowsDirectory(path,MAX_PATH);int len = strlen(path);strcpy(&path[len],"//desktop//config.lik");//change the char from ANSI to UNICODEOLECHAR widepath[MAX_PATH];MultiByteToWideChar(CP_ACP,0,path,-1,widepath,MAX_PATH);persistfile->Save(widepath,TRUE);

    6pshelllink->Release();psersistfile->Release();

    7CoUnInitialize();


    最新回复(0)