常用控件中问题总结

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);
怎样调整 Dialog 窗口上控件的 TabStop 的顺序?

1)选择资源管理(ResourceView),选Dialog的ID,双击,选菜单中的LayOut->Tab Order,按住Alt,顺序点下来就行了
2)选择资源管理(ResourceView),选Dialog的ID,双击,按住Ctrl+D顺序点下来就行了

///

Q//控件适应窗体变化

A
CWinsizeDlg::CWinsizeDlg(CWnd* pParent /*=NULL*/)
: CDialog(CWinsizeDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CWinsizeDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_bResizeable=FALSE;//added
}

BOOL CWinsizeDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);// Set big icon
SetIcon(m_hIcon, FALSE);// Set small icon

// TODO: Add extra initialization here

ReSetCtrlSize();//added
m_bResizeable=TRUE;//added
return TRUE;  // return TRUE  unless you set the focus to a control
}

void CWinsizeDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
if(m_bResizeable==TRUE)//added
ReSetCtrlSize();//added
}

void CWinsizeDlg::ReSetCtrlSize()
{
//all is added
//用户自定义函数,用来使窗体变化时EDIT控件也跟着适应变化

CEdit* pEdit=(CEdit*)GetDlgItem(IDC_EDIT_DEMO);

CRect  rcEdit;
CRect  rcDlg;

GetClientRect(rcDlg);//取得对话框的客户区坐标
pEdit->GetWindowRect(rcEdit);   //取得编辑框的屏幕坐标
ScreenToClient(rcEdit);//将编辑框的屏幕坐标转化为相对于对话框客户区的相对坐标

rcEdit.right=rcDlg.right-5;//设置编辑框的新坐标
rcEdit.bottom=rcDlg.bottom-5;

pEdit->MoveWindow(rcEdit);//调整编辑框位置

}

///

Q
CComboBox下拉高度太小问题
A
手工解决方法:
Combo Box Styles属性改为Simple,改变其高度,再该回所需Styles属性

以下是用代码初始化Combo Box的数据
CComboBox * pPort=(CComboBox *) GetDlgItem(IDC_COMBO1);
pPort->AddString("COM1");
pPort->AddString("COM2");
pPort->SetWindowText("TTT");

///

Q
对话框上有一个静态文本IDC_STATIC,要求鼠标点击这个文本,然后弹出ie到一个网站!请问怎么做?

如果再进一步,鼠标移到静态文本的时候,变成手状,静态文本变成蓝色加下划线,就想浏览网站一样!!又怎么做呢?

A
在你对话框的同样函数里
BOOL C****Dlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
switch(pWnd->GetDlgCtrlID())
{
case IDC_STATIC1:  //静态控件的ID
SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR1));
                    //IDC_CURSOR1就是你的手鼠标
return TRUE;
}
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}

点击后要访问网站可以用
ShellExecute(NULL,"open","http://www.google.com","","", SW_SHOW);

///

Q
CFileDialog读写文件

A
{//写文件
TCHAR szFilters[]=_T("设置文件(*.set)|*.set|所有文件|*.*||");
CFileDialog dlg(FALSE, _T("set"), _T("*.set"),
OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilters);
if(dlg.DoModal()==IDOK)
{
CString strTest;
strTest.Format("%s","Hello!");

CString strFileName=dlg.GetPathName();
try
{
CStdioFile file(strFileName,CFile::modeWrite|CFile::modeCreate);
MessageBox(strTest);
file.SeekToEnd();
file.WriteString(strTest);
}
catch(CFileException* e)
{
e->ReportError();
e->Delete();
}

}
}
{//读文件
CString strTest;
TCHAR szFilters[]=_T("设置文件(*.set)|*.set|所有文件|*.*||");
CFileDialog dlg(TRUE, _T("set"), _T("*.set"),
OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,szFilters);
if(dlg.DoModal()==IDOK)
{
CString strFileName=dlg.GetPathName();//取得文件名
try
{
CStdioFile file(strFileName,CFile::modeRead);//创建
file.ReadString(strTest);//读
MessageBox(strTest);//显示
}
catch(CFileException* e)
{
e->ReportError();
e->Delete();
}
}
}

Q
//在一个子窗口或曰控件上绘图
A
void CMy0x10Dlg::OnButton1()
{

CWnd* pWnd = this->GetDlgItem(IDC_STATIC_X);//静态控件
CRectrect;
pWnd->GetClientRect(rect);
CDC *dc=pWnd->GetDC();
//dc->MoveTo(10,10);
//dc->LineTo(100,100);
//dc->Rectangle(1,1,10,10);
Arc(dc->m_hDC,1,1,100,100,200,200,5,5);
}

Q
鼠标自动移动到控件中心(likfeng原创)
//CSDN ID:likfeng 原创
A
1.
对话框上加一个Button,定义关联的CButton变量m_btn1

2.
void CDlgTest::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CPoint pointMouse;//鼠标
CRect rectButton;//按钮
pointMouse = point;

m_btn1.GetWindowRect(rectButton);
ScreenToClient(rectButton);

int dI = 30;//鼠标接近按钮的距离,看需要加以调整,需dI>0


if((pointMouse.x > (rectButton.left - dI))&&
(pointMouse.x < rectButton.right + dI)&&
(pointMouse.y > rectButton.top - dI)&&
(pointMouse.y < rectButton.bottom + dI))
{
ClientToScreen(rectButton);
SetCursorPos(rectButton.left + rectButton.Width()/2,
rectButton.top + rectButton.Height()/2);//设置鼠标在屏幕上的坐标(屏幕坐标)
}

CDialog::OnMouseMove(nFlags, point);
}
3.好了试试吧

你可能感兴趣的:(常用控件中问题总结)