天天看點

常用控件中問題總結

Q 如何處理ComboBox中的Enter鍵?避免退出程式?

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 )

: 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.好了試試吧

繼續閱讀