MFC 技巧之四

來源:互聯網
上載者:User
31. 如何在編輯控制項中以追加的方式添入字元?

 [問題提出]
  SetDlgItemText可以向Edit控制項中輸入字元,發送更新的訊息也可是Edit控制項顯示與其關聯的變數的值,但若是向已有的Edit字元後追加字元,該如何做?
 [程式實現]
  建立名為My的對話方塊工程,添加一個Edit和一個Button控制項.Edit的ID=IDC_EDIT1,Button的ID=IDC_BUTTON1.建立和IDC_BUTTON1的響應函數:OnButton1()
  void CMyDlg::OnButton1()
  {
    CString pText="你好";
    CEdit *m_Edit=(CEdit *)GetDlgItem(IDC_EDIT1);
    int nLen=m_Edit->GetWindowTextLength();
    m_Edit->SetFocus();
    m_Edit->SetSel(nLen, nLen);
    m_Edit->ReplaceSel(pText);
  }
  在Edit控制項中輸入字元,想追加時按IDC_BUTTON1按鈕.看看效果.

32.屬性頁面標題改名

我用CPropertySheet建立屬性頁面,用的CPropertyPage對象只有一個,也就是每個屬性頁面的內容一樣.現在的問題是:這樣每個屬性頁面的標題都是一樣的,是對話方塊的標題!怎樣動態改變這個標題,使每個屬性頁面的標籤的名稱都不同??

CTabCtrl * pCtrl = pSheet->GetTabControl();
TCITEM tc;
tc.mask = TCIF_TEXT;
tc.pszText = "新標題";
pCtrl->SetItem(0,&tc);//0即是你要改的TAb的索引

33. 怎樣去掉屬性頁面的Apply與Help按鈕?

//去掉Help
  m_psh.dwFlags |= PSH_HASHELP ;
  m_psh.dwFlags &= ~PSH_HASHELP ;
//除掉應用按鈕 m_psh.dwFlags|=PSH_NOAPPLYNOW;

34. 如何給樹控制項加入工具提示

1.首先給樹控制項加入TVS_INFOTIP屬性風格,如下所示:

if (!m_ctrlTree.Create(WS_CHILD|WS_VISIBLE|
  TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT|TVS_SHOWSELALWAYS|TVS_INFOTIP, //加入提示TVS_INFOTIP,jingzhou xu(樹控制項ID:100)
   CRect(0, 0, 0, 0), &m_wndTreeBar, 100))
  {
   TRACE0("Failed to create instant bar child/n");
   return -1;
  }

2.其次加入映射訊息聲明,如下所示:

afx_msg void OnGetInfoTip(NMHDR* pNMHDR,LRESULT* pResult);    //樹控制項上加入提示訊息,jingzhou xu  

ON_NOTIFY(TVN_GETINFOTIP, 100, OnGetInfoTip)       //樹控制列目上加入提示,jingzhou xu

3.最後加入呼應涵數處理:

void CCreateTreeDlg::OnGetInfoTip(NMHDR* pNMHDR,
                  LRESULT* pResult)
 {
 *pResult = 0;
 NMTVGETINFOTIP* pTVTipInfo = (NMTVGETINFOTIP*)pNMHDR;
 LPARAM itemData = (DWORD) pTVTipInfo->lParam;
 //對應每個條目的資料
 HTREEITEM hItem = pTVTipInfo->hItem;
 CString tip;
 HTREEITEM hRootItem = m_chassisTree.GetRootItem();
 if (hRootItem != pTVTipInfo->hItem)
 {
  tip = "樹結點的提示";
 }
 else
 {
  tip = "樹根上的提示";
 }
 strcpy(pTVTipInfo->pszText, (LPCTSTR) tip);
}

35. 如何在TreeList中加表徵圖?

 [問題提出]
 請問treeview控制項和treectrl控制項的用法有何不同呢?向如何imagelist控制項中加圖象呀?
 [解決方案]
 1)
  HICON hicon[8];
  m_imageList.Create(16,16,0,8,8);
  hicon[0]=AfxGetApp()->LoadIcon(IDI_ICON0);
  hicon[1]=AfxGetApp()->LoadIcon(IDI_ICON1);
  hicon[2]=AfxGetApp()->LoadIcon(IDI_ICON2);
  hicon[3]=AfxGetApp()->LoadIcon(IDI_ICON3);
  hicon[4]=AfxGetApp()->LoadIcon(IDI_ICON4);
  hicon[5]=AfxGetApp()->LoadIcon(IDI_ICON5);
  hicon[6]=AfxGetApp()->LoadIcon(IDI_ICON6);
  hicon[7]=AfxGetApp()->LoadIcon(IDI_ICON7);
  for(int n=0;n<8;n++)
    m_imageList.Add(hicon[n]);

  CTreeCtrl *pTree=(CTreeCtrl *)GetDlgItem(IDC_TREE);
  pTree->SetImageList(&m_imageList,TVSIL_NORMAL);

 2)
  CImageList cil1;
  cil1.Create(32,32,TRUE,2,2);
  cil1.Add(pApp->LoadIcon(IDI_DAO1));
  cil1.Add(pApp->LoadIcon(IDI_DAO2));
  cil1.Add(pApp->LoadIcon(IDI_DAO3));
  cil1.Add(pApp->LoadIcon(IDI_DAO4));
  cil1.Add(pApp->LoadIcon(IDI_DAO5));
  cil1.Add(pApp->LoadIcon(IDI_DAO6));
  cil1.Add(pApp->LoadIcon(IDI_DAO7));
  cil1.Add(pApp->LoadIcon(IDI_DAO8));
  cil1.Add(pApp->LoadIcon(IDI_DAO9));
  
  //設定圖象列表
  m_list.SetImageList(&cil1,LVSIL_NORMAL);

36. 如何雙擊列表框項啟動一個與檔案關聯的程式?

有人問我如何雙擊列表框項啟動一個程式?其實這個問題很簡單,Windows中有一個API函數可以開啟任何類型的檔案:

ShellExecute(NULL,"open",lpFileName,NULL,NULL,SW_SHOWNORMAL);

參數 lpFileName
是檔案的全路徑名。用這個變數你可以傳遞象“C://MyExcelFile.xls”或者“http://www.vckbase.com”啟動
Excel程式或者瀏覽器程式。如果你只是想擷取與檔案關聯的程式名,而不是要運行程式,那麼調用::FindExecutable就可以了。

37. 如何防止在listbox中添加很多資料出現不停的重新整理?

 [問題提出]
  在listbox添加很多資料的時候,由於控制項不停的重新整理,導致出現閃爍,如何解決?
 [解決方案]
  再添加資料以前,禁止控制項重新整理,資料添加完畢以後,再重新整理一次。
 [程式實現](其中:m_ListBox是CListBox的控制項類型的變數)
  m_ListBox.LockWindowUpdate();//禁止本listbox重新整理。
  for(int i=0;i<9999;i++)
  {
     m_ListBox.AddString("test");
  }//添加資料。
  this->RedrawWindow(NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);

38. 如何得到CListBox所選擇項的String?

 [問題提出]
 如何得到CListBox所選擇項的String
 [解決方案]
 用到:CListBox::GetText()
 [程式實現]
 CString scInfo;
 pList->GetText( GetCurSel(),scInfo);

39. 用滑鼠移動基於對話方塊的無標題列程式的簡單方法

void CVCTestDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
  //一句話解決問題
  SendMessage(WM_SYSCOMMAND,0xF012,0);
  CDialog::OnLButtonDown(nFlags, point);
}

40. 如何改變框對話或表單視窗的背景顏色

調用CWinApp : : SetDialogBkColor可以改變所有應用程式的背景顏色。第一個參數指定了背景顏色,第二個參數指定了文本顏色。下例將應用程式對話設定為藍色背景和黃色文本。
BOOL CSampleApp : : InitInstance ( )
{

//use blue dialog with yellow text .
SetDialogBkColor (RGB (0, 0, 255 ), RGB ( 255 , 255 , 0 ) ) ;

}
需要重畫對話(或對話的子控制項)時,Windows向對話發送訊息WM_CTLCOLOR,通常使用者可以讓Windows選擇繪畫背景的刷子,也可重設該訊息指定刷子。下例說明了建立一個紅色背景對話的步驟。
首先,給對話基類增加一人成員變數CBursh :
class CMyFormView : public CFormView
{

private :
CBrush m_ brush ; // background brush

} ;
其次, 在類的建構函式中將刷子初始化為所需要的背景顏色。
CMyFormView : : CMyFormView ( )
{
// Initialize background brush .
m_brush .CreateSolidBrush (RGB ( 0, 0, 255 ) )
}
最後,使用ClassWizard處理WM_CTLCOLOR訊息並返回一個用來繪畫對話背景的刷子控制代碼。注意:由於當重畫對話控制項時也要調用該函數,所以要檢測nCtlColor參量。
HBRUSH CMyFormView : : OnCtlColor (CDC* pDC , CWnd*pWnd , UINT nCtlColor )
{
// Determine if drawing a dialog box . If we are , return +handle to
//our own background brush . Otherwise let windows handle it .
if (nCtlColor = = CTLCOLOR _ DLG )
return (HBRUSH) m_brush .GetSafeHandle ( ) ;
return CFormView : : OnCtlColor (pDC, pWnd , nCtlColor );
}

41.如何禁止對話方塊關閉按鈕和浮動工具條上的系統功能表

1、禁止對話方塊中的關閉按鈕有二種方法。
第一種方法,用ModiftMenu()涵數來實現:

CMenu* pMenu = this->GetSystemMenu(FALSE);
pMenu->ModifyMenu(SC_CLOSE,MF_BYCOMMAND | MF_GRAYED );

第二種方法,用EnableMenuItem()涵數來實現:

CMenu* pMenu = this->GetSystemMenu(FALSE);
pMenu->EnableMenuItem( SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);

2、禁止浮動工具條上的系統功能表。
建立一個CToolBar的衍生類別CxxToolBar,在新類中的左鍵雙擊(CxxToolBar::OnLButtonDblClk(...))
和左鍵單擊(CxxToolBar:: OnLButtonDown(...))涵數中分別加入下面代碼既可:
if (IsFloating()) //工具條正在浮動狀態中
{
  CWnd* pMiniFrame;
  CWnd* pDockBar;

  pDockBar = GetParent();
  pMiniFrame = pDockBar->GetParent();

  //去除其上系統功能表
  pMiniFrame->ModifyStyle(WS_SYSMENU, NULL);

  //重繪工具條
  pMiniFrame->ShowWindow(SW_HIDE);
  pMiniFrame->ShowWindow(SW_SHOW);
}

3、禁止視窗最大化按鈕
在PreCreateWindow()涵數中去掉WS_MAXIMIZEBOX風格顯示既可。
BOOL CxxFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
{
  cs.style &= ~WS_MAXIMIZEBOX;
  return CFrameWnd::PreCreateWindow(cs);
}

42.如何拷貝一個工程的對話方塊資源到另一個工程中?

 有兩種方法可以實現:
 
 1)你可以直接拷貝resource,用VC++以文本的方式或者直接用文字編輯器開啟.rc檔案,將有關的片段從
一個工程拷貝到另一個工程.你可以通過尋找如下字樣的片段(此片段用來定義對話方塊資源)來拷貝你要
的部分:
 
 IDD_MYDIALOG_ID DIALOG DISCARDABLE 0, 0, 235, 55
 
 這裡的IDD_MYDIALOG_ID是你的對話方塊的ID,將到此片段結尾的部分全拷下來,通常你還要給新的工程
加一個ID(通過DevStudio的工具或者直接修改resource.h檔案).

 2)可以通過DevStudio的copy/paste功能.首先,在編輯器以"auto"模式開啟.rc檔案,這時resource
正確的顯示出來.然後,選中要拷貝的對話方塊的ID,在Edit菜單裡選Copy或者按住Ctrl+C.然後開啟目標
resource檔案,在Edit菜單裡選Paste或者按住Ctrl+V.

43.如何?點一下對話方塊外面的地區,自動隱藏對話方塊?

 [問題提出]
  如果想在點擊對話方塊外面的地方使得對話方塊關閉,該如何做?

 [解決方案]
  試試下面的代碼,原理是在啟用對話方塊時,捕獲滑鼠的動作,當滑鼠點擊時判斷是否點擊在對話方塊外,是的話就解除配置框.

 [程式實現]
  建立名為My的對話方塊程式.實現如下步驟:
  在MyDlg.h中加入:

  class CShowWindow1Dlg : public CDialog
  {
   // Construction
   public:
     int m_cx;
     int m_cy;
     ......
  };

  在MyDlg.cpp中:

  //定義訊息映象,處理按一下滑鼠及啟用
  BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
    //{{AFX_MSG_MAP(CMyDlg)
    ON_WM_LBUTTONDOWN()
    ON_WM_ACTIVATE()
    //}}AFX_MSG_MAP
  END_MESSAGE_MAP()

  void CMyDlg::OnLButtonDown(UINT nFlags, CPoint point)
  {
    CRect rect;
    GetClientRect(&rect);
    rect.InflateRect(m_cx, m_cy);
 
    //Release dialog if the user click outside it.
    if(!rect.PtInRect(point))
    {
      EndDialog(IDCANCEL);
    }

    CDialog::OnLButtonDown(nFlags, point);
  }

  void CMyDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
  {
    CDialog::OnActivate(nState, pWndOther, bMinimized);

    if( nState == WA_ACTIVE || nState == WA_CLICKACTIVE)
      SetCapture();
    else
      ReleaseCapture();
  }

  BOOL CMyDlg::OnInitDialog()
  {
    CDialog::OnInitDialog();
    .....
    
    OSVERSIONINFO info;
    memset((char*)&info, 0, sizeof(OSVERSIONINFO));
    info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    if(GetVersionEx(&info))
    { //we don't run on Win32s, so check only two values
      if(info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
      { //On windows 95
       m_cx = GetSystemMetrics(SM_CXFIXEDFRAME);
       m_cy = GetSystemMetrics(SM_CYFIXEDFRAME);
      }
      else
      { //On NT
       m_cx = GetSystemMetrics(SM_CXDLGFRAME);
       m_cy = GetSystemMetrics(SM_CYDLGFRAME);
      }
    }
  }

   說明:
   1)WM_ACTIVATE訊息在ClassWizard中沒有,按如下步驟添加,右擊CMyDlg類,選Add Windows
Message Handle,接著在Filter for messages available to中選Window,在New Windows
messages/events列表中就會出現WM_ACTIVATE,選中,點擊Add Handler
   2)SM_CXDLGFRAME,SM_CYDLGFRAME  NT中取得有WS_DLGFRAMEstyle風格的視窗的高和寬 95中已經廢棄而採用SM_CX_FIXEDFRAME和SM_CYFIXEDFRAME

44. 初始化應用程式的大小

如果想使應用程式介面(文檔)在開始運行是按你的尺寸展現在螢幕上,
 添加代碼如下:
 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
 {
   int xsize=::GetSystemMetrics(SM_CXSCREEN);
   int ysize=::GetSystemMetrics(SM_CYSCREEN);
   cs.cx=xsize*5/10;
   cs.cy=ysize*5/10;
   cs.x=(xsize-cs.cx)/2;
   cs.y=(ysize-cs.cy)/2; 

 }
 其中的5/10是你的初始介面占螢幕的百分比,可以自己修改。如果想使應用程式大小固定添加cs.style&=~WS_THICKFRAME;

45. 如何得到視圖指標?

[問題提出]
  現在你有一個多線程的Demo,你想在多線程裡處理視圖指標裡的函數,我們給這個函數起個名字:Put();該如何?呢?
  //有兩種方法可以實現你的要求:
  //1)第一種方法:
  //要是多線程不是在App.cpp裡出現,那麼要在多線程的.cpp中加上extern CYourApp theApp;
  //獲得文件範本:
  POSITION curTemplatePos = theApp.GetFirstDocTemplatePosition();
  CDocTemplate *m_doc=theApp.GetNextDocTemplate(curTemplatePos);

  //獲得文檔:
  curTemplatePos=m_doc->GetFirstDocPosition();
  CYourDoc *m_pdoc=(CA8Doc*)m_doc->GetNextDoc(curTemplatePos);
 
  //獲得視圖:
  curTemplatePos=m_pdoc->GetFirstViewPosition();
  CYourView *m_pview=(CYourView*)m_pdoc->GetNextView(curTemplatePos);

  //調用視圖函數:
  m_pview->Put();

  //2)第二種方法:
  //獲得表單指標:
  CMainFrame *pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;

  //獲得與該表單符合的視圖:
  CYourView *m_pView = (CYourView *) pFrame->GetActiveView();

  //調用視圖函數:
  m_pView->Put();

46. 如何使我的程式在啟動時不建立一個新文檔?

[問題]
如何使我的程式在啟動時不建立一個新文檔?
[解答]
在程式的InitInstance中的ProcessShellCommand函數之前加入: cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing

47. 如何將標題列上的右鍵菜單屏蔽掉?

 [解決方案]
  右鍵菜單是系統功能表,只要將其WS_SYSMENU的屬性去掉即可.
 [程式實現]
  int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  {
     ........
  long style = GetWindowLong(m_hWnd, GWL_STYLE);
     style &= ~WS_SYSMENU;
     SetWindowLong(m_hWnd, GWL_STYLE, style);

  return 0;
  }

48.如何全螢幕顯示(沒有標題,沒有菜單,沒有工具條)

 [解決方案]
  重載CMainFrame的ActivateFrame函數:
  void CMainFrame::ActivateFrame(int nCmdShow)
  {
     CRect cRectdesktop;
     WINDOWPLACEMENT windowplacement;
     ::GetWindowRect(::GetDesktopWindow(),&cRectdesktop);
     ::AdjustWindowRectEx(&cRectdesktop,GetStyle(),TRUE,GetExStyle());
     windowplacement.rcNormalPosition=cRectdesktop;
     windowplacement.showCmd=SW_SHOWNORMAL;
     SetWindowPlacement(&windowplacement);

     CFrameWnd::ActivateFrame(nCmdShow);
  }

49.如何設定有背景顏色的文本

(1)[解決方案]
  用到了CDC::SetBkMode();
 
 [程式實現]
  void CMyView::OnDraw(CDC* pDC)
  {
    CMyDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    CRect rcView;//加這兩句
    GetClientRect(rcView);
    // TODO: add draw code for native data here
    CString str (_T("Perfect Text..."));
    pDC->SetBkMode(TRANSPARENT);
    rcView.OffsetRect (1,1);
    pDC->SetTextColor(RGB (0,0,0));
    pDC->DrawText(str,str.GetLength(),rcView,DT_SINGLELINE | DT_CENTER | DT_VCENTER);
    rcView.OffsetRect(-1,-1);
    pDC->SetTextColor(RGB (255,0,0));
    pDC->DrawText(str,str.GetLength(),rcView,DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  }
(2) 建立名為My的SDI或MDI,並響應WM_ERASEBKGND.
  BOOL CMyView::OnEraseBkgnd(CDC* pDC)
  {
   // TODO: Add your message handler code here and/or call default
   CBrush Brush (RGB(114,147,171));
   // Select the brush into the device context .
   CBrush* pOldBrush = pDC->SelectObject(&Brush);
   // Get the area that needs to be erased .
   CRect ViewClip;
   pDC->GetClipBox(&ViewClip);
   //Paint the area.
   pDC->PatBlt(ViewClip.left,ViewClip.top,ViewClip.Width(),ViewClip.Height(),PATCOPY);
   //Unselect brush out of device context .
   pDC->SelectObject (pOldBrush );
   // Return nonzero to half fruther processing .

   return TRUE;
   return CView::OnEraseBkgnd(pDC);
  }
  此方法也適合基類是EditView的SDI或MDI的情況,但是字型的顏色和底色不行.建議用WM_CTLCOLOR.

50.串太長時往讓其末尾顯示一個省略符號(在SDI或MDI的View中)

 [問題提出]
  如何在串太長時往讓其末尾顯示一個省略符號(在SDI或MDI的View中)?
 [程式實現]
  建立名為My的SDI或MDI工程.
  void CMyView::OnDraw(CDC* pDC)
  {
    CMyDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here
    pDC->DrawText(CString("It's a long string,so we will add a '...'
at the end."),CRect (110, 110, 180, 130),DT_LEFT | DT_END_ELLIPSIS);
    //Add ellpsis to middle of string if it does not fit
    pDC->DrawText(CString("It's a long string,so we will add a '...'
at the end."),CRect (110, 140, 300, 160),DT_LEFT | DT_PATH_ELLIPSIS);
  }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.