首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题SUNIBM微 软微 创精 华Donews人 邮
我的技术中心 
我的分类 我的文档
全部文章 发表文章
专栏管理 使用说明



 RSS 订阅 
最新文档列表
Windows/.NET
.NET  (rss)    
Visual C++  (rss)    
Delphi  (rss)    
Visual Basic  (rss)    
ASP  (rss)    
JavaScript  (rss)    
Java/Linux
Java  (rss)    
Perl  (rss)    
综合
其他开发语言  (rss)    
文件格式  (rss)    
企业开发
游戏开发  (rss)    
网站制作技术  (rss)    
数据库
数据库开发  (rss)    
软件工程
其他  (rss)    

积极原创作者 
tellmenow (22)
cutemouse (22)
softj (78)
iiprogram (69)
qdzx2008 (50)
goodboy1881 (14)
wangchinaking (58)
fancyhf (1)
harrymeng (41)
yjz0065 (113)
CSDN - 文档中心 - Visual C++ 阅读:5567   评论: 0    参与评论
标题   VC/MFC Q&A 200411     选择自 laiyiling 的 Blog
关键字   VC/MFC Q&A 200411
出处  

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 如何设置编辑控件的数字限制属性?
A
long 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  如何让属性页具有两行标签?

从CPropertySheet派生一个自己的类,添加一个PreCreateWindow的处理,然后在调用基类的处理前加如下代码:cs.style |= TCS_MULTILINE;

//-----------------------------------------------------------
Q  如何隐藏属性页的标题栏?

从CPropertySheet派生一个自己的类,并覆盖OnInitDialog,在转到默认的情况以后,使用 ModifyStyle来删除标题栏标志WS_CAPTION。
   ModifyStyle(WS_CAPTION,0);

//-------------------------------------------------------------------
Q 如何枚举桌面项目?
A
1 得到指向IShellFolder接口的指针
2 得到指向IMalloc接口的指针
3 得到指向IEnumIDList接口的指针
4 提取枚举中下一项目的PIDL
5 测定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 com
2 create LShellLink Object
3 Use IShellLink interface to get the pointer about IPersistFile
4 Use IShellLink interface to initialize link
5 Use LPersistFile interface to save the link
6 Release all the com pointer
7 Com return to previous status

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

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

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

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

5
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);

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

7
CoUnInitialize();


相关文章
对该文的评论