Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1676294
  • 博文数量: 585
  • 博客积分: 14610
  • 博客等级: 上将
  • 技术积分: 7402
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-15 10:52
文章存档

2013年(5)

2012年(214)

2011年(56)

2010年(66)

2009年(44)

2008年(200)

分类: C/C++

2012-01-27 03:09:49

 Visual C++ 编程技巧之五和六
分类: 2.3 VC技巧收集 175人阅读 评论(0) 收藏 举报

33、如何获取一个对话控件的指针 
34、如何禁止和使能控件 
35、如何改变控件的字体 
36、如何在OLE控件中使用OLE_COLOR数据类型 
37、在不使用通用文件打开对话的情况下如何显示一个文件列表 
38、为什么旋转按钮控件看起来倒转 
39 为什么旋转按钮控件不能自动地更新它下面的编辑控件 
40、如何用位图显示下压按钮 
41、如何一个创建三态下压按钮 
42、如何动态创建控件 
43、如何限制编辑框中的准许字符 
44、如何改变控件的颜色 
45、当向列表框中添加多个项时如何防止闪烁 
46、如何向编辑控件中添加文本 
47、如何访问预定义的GDI对象 
48、如何获取GDI对象的属性信息

33、如何获取一个对话控件的指针  
 
有两种方法。其一,调用CWnd: : GetDlgItem,获取一个CWnd*指针调用成员函数。下例调用GetDlgItem,将返回值传给一个CSpinButtonCtrl*以便调用CSpinButtonCtrl : : SetPos 函数:  
 
BOOL CSampleDialog : : OnInitDialog ( )  
{  
    CDialog : : OnInitDialog ( ) ;  
    //Get pointer to spin button .  
    CSpinButtonCtrl * pSpin - ( CSpinButtonCtrl *) GetDlgItem (IDC_SPIN) ;  
    ASSERT _ VALID (pSpin) ;  
    //Set spin button's default position .  
    pSpin —> SetPos (10) ;  
    return TRUE ; 
}  
 
其二, 可以使用ClassWizard将控件和成员变量联系起来。在ClassWizard中简单地选择Member Variables标签,然后选择Add Variable …按钮。如果在对话资源编辑器中,按下Ctrl键并双击控件即可转到Add Member Variable对话。  
 
34、如何禁止和使能控件  
 
控件也是窗口,所以可以调用CWnd : : EnableWindow使能和禁止控件。  
 
//Disable button controls .  
m_wndOK.EnableWindow (FALSE ) ;  
m_wndApply.EnableWindow (FALSE ) ;  
 
35、如何改变控件的字体  
 
由于控件是也是窗口,用户可以调用CWnd: : SetFont指定新字体。该函数用一个Cfont指针,要保证在控件撤消之前不能撤消字体对象。下例将下压按钮的字体改为8点Arial字体:  
 
//Declare font object in class declaration (.H file ).  
private :  
Cfont m_font ;  
// Set font in class implementation (.Cpp file ). Note m_wndButton is a  
//member variable added by ClassWizard.DDX routines hook the member  
//variable to a dialog button contrlo.  
BOOL CSampleDialog : : OnInitDialog ( )  
{  
    …  
    //Create an 8-point Arial font  
    m_font . CreateFont (MulDiv (8 , -pDC—> GetDeviceCaps (LOGPIXELSY) , 72).  
    0 , 0 , 0 , FW_NORMAL , 0 , 00, ANSI_CHARSER, OUT_STROKE_PRECIS ,  
    CLIP_STROKE _PRECIS , DRAFT _QUALITY  
    VARIABLE_PITCH |FF_SWISS, _T ("Arial") );  
    //Set font for push button .  
    m_wndButton . SetFont (&m _font );  
    …  
}  
 
36、如何在OLE控件中使用OLE_COLOR数据类型  
 
诸如COleControl : : GetFortColor和COleControl : : GetBackColor等函数返回OLE _COLOR数据类型的颜色,而GDI对象诸如笔和刷子使用的是COLORREF数据类型,调用COleControl : : TranslateColor可以很容易地将OLE_COLOR类型改为COLORREF类型。下例创建了一个当前背景颜色的刷子:  
 
void CSampleControl : : OnDraw (CDC* pdc ,const Crect& rcBounds , const Crect& rcInvalid )  
{  
    //Create a brush of the cuttent background color .  
    CBrush brushBack (TranslateColor (GetBackColor ( ) ) );  
    //Paint the background using the current background color .  
    pdc—> FilllRect (rcBounds , &brushBack) ; 
    //other drawign commands  
    …  
}  
 
37、在不使用通用文件打开对话的情况下如何显示一个文件列表  
 
调用CWnd: : DlgDirList或者CWnd: : DlgDirListComboBox, Windows 将自动地向列表框或组合框填充可用的驱动器名或者指定目录中的文件,下例将Windows目录中的文件填充在组合框中:  
 
BOOL CSampleDig : : OnInitDialog ( )  
{  
    CDialog : : OnInitDialog ( )  
    TCHAR szPath [MAX_PATH] = {"c://windows"} ;  
    int nReslt = DlgDirListComboBox (szPath , IDC_COMBO , IDC_CURIDIR,  
    DDL_READWRITE |DDL_READONLY|DDL_HIDDEN| DDL_SYSTEM|DDL_ARCHIVE ) ;  
    return TRUE ;  
}  
 
38、为什么旋转按钮控件看起来倒转  
 
需要调用CSpinCtrl : : SetRange 设置旋转按钮控件的范围,旋转按钮控件的缺省上限为0,缺省下限为100,这意味着增加时旋转按控件的值由100变为0。下例将旋转按钮控件的范围设置为0到100:  
 
BOOL CAboutDlg : : OnInitDialog ( )  
{  
    CDialog : : OnInitDialog ( )  
    //set the lower and upper limit of the spin button  
    m_wndSpin . SetRange ( 0 ,100 ) ;  
    return TRUE ;  
}  
 
Visual C++ 4.0 Print对话中的Copise旋转按钮控件也有同样的问题:按下Up按钮时拷贝的数目减少,而按下Down 按钮时拷贝的数目增加。  
 
39为什么旋转按钮控件不能自动地更新它下面的编辑控件  
 
如果使用旋转按钮的autu buddy特性, 则必须保证在对话的标记顺序中buddy窗口优先于旋转按钮控件。从Layout菜单中选择Tab Order菜单项(或者按下Crtl+D)可以设置对话的标签顺序。  
 
40、如何用位图显示下压按钮  
 
Windows 95按钮有几处新的创建风格,尤其是BS_BITMAP和BS_ICON,要想具有位图按钮,创建按钮和调用CButton : : SetBitmap或CButton : : SetIcon时要指定BS_BITMAP或BS_ICON风格。  
首先,设置按钮的图标属性。  
然后,当对话初始化时调用CButton: : SetIcon。注意:下例用图标代替位图,使用位图时要小心,因为不知道背景所有的颜色——并非每个人都使用浅灰色。  
 
BOOL CSampleDlg : : OnInitDialog ( )  
{  
    CDialog : : OnInitDialog ( ) ;  
    //set the images for the push buttons .  
    m_wndButton1.SetIcon (AfxGetApp ( ) —> LoadIcon (IDI _ IPTION1) )  
    m_wndButton2.SetIcon (AfxGetApp ( ) —> LoadIcon (IDI _ IPTION2) )  
    m_wndButton3.SetIcon (AfxGetApp ( ) —> LoadIcon (IDI _ IPTION3) )  
    return TRUE ;  
}  
 

41、如何一个创建三态下压按钮  
 
可以使用新的BS_PUSHBUTTON 风格位和检测框以及按钮来创建一个三态下压按钮。这很容易,只需将检测框和按钮拖拉到对话中并指定属性Push—like即可。不用任何附加程序就可以成为三态下压按钮。  
 
42、如何动态创建控件  
 
分配一个控件对象的实例并调用其Create成员函数。开发者最容易忽略两件事:忘记指定WS_VISBLE标签和在栈中分配控件对象。下例动态地创建一个下压按钮控件:  
//In class declaration (.H file ).  
private :  
CButton* m _pButton ;  
//In class implementation (.cpp file ) .  
m_pButton =new CButton ;  
ASSERT_VALID (m_pButton);  
m_pButton —>Create (_T ("Button Title ") , WS_CHILD |WS_VISIBLE |BS_PUSHBUTTON,Crect ( 00100 , 24) , this , IDC _MYBUTTON )  
 
43、如何限制编辑框中的准许字符  
 
如果用户在编辑控件中只允许接收数字,可以使用一个标准的编辑控件并指定新的创建标志ES_NUMBERS,它是Windows 95新增加的标志,该标志限制 编辑控件只按收数字字符。如果用户需要复杂的编辑控件,可以使用Microsoft 的屏蔽编辑控件,它是一个很有用的OLE定制控件。  
如果希望不使用OLE 定制控件自己处理字符,可以派生一个CEdit 类并处理WM_CHAR消息,然后从编辑控件中过滤出特定的字符。首先,使用ClassWizard 建立一个 CEdit的派生类,其次,在对话类中指定一个成员变量将编辑控件分类在OnInitdialog 中调用CWnd: : SubclassDlgItem .  
 
//In your dialog class declaration (.H file )  
private :  
CMyEdit m_wndEdit ; // Instance of your new edit control .  
//In you dialog class implementation (.CPP file )  
BOOL CSampleDialog : : OnInitDialog ( )  
{  
    …  
    //Subclass the edit lontrod .  
    m_wndEdit .SubclassDlgItem (IDC_EDIT,this );  
    …  
}  
 
使用ClassWizard处理WM_CHAR消息,计算nChar参量并决定所执行的操作,用户可以确定是否修改、传送字符。下例说明了如何显示字母字符,如果字符是字母字符,则调用CWnd ; OnChar,否则不调用OnChar.  
 
//Only display alphabetic dharacters .  
 
void CMyEdit : : OnChar (UINT nChar , UINT nRepCnt , UITN nFlags )  
{  
    //Determine if nChar is an alphabetic character .  
    if (: : IsCharAlpha ( ( TCHAR) nChar ) )  
    CEdit : : OnChar (nChar, nRepCnt , nFlags );  
}  
 
如果要修改字符,则不能仅仅简单地用修改过的nChar调用CEdit : : OnChar,然后CEdit: : OnChar调用CWnd: : Default获取原来的wParam 和lParam 的值 ,这样是不行的。要修改一个字符,需要首先修改nChar,然后用修改过的nChar调用CWnd: : DefWindowProc。下例说明了如何将字符转变为大写:  
 
//Make all characters uppercase  
 
void CMyEdit : : OnChar (UINT nChar , UINT nRepCnt , UINT nFlags )  
{  
    //Make sure character is uppercase .  
    if (: : IsCharAlpha ( .( TCHAR) nChar)  
    nChar=: : CharUpper (nChar ) ;  
    //Bypass default OnChar processing and directly call  
    //default window proc.  
    DefWindProc (WM_CHAR, nChar , MAKELPARAM (nRepCnt , nFlags )) ;  
}  
 
44、如何改变控件的颜色  
 
有两种方法。其一,可以在父类中指定控件的颜色,或者利用MFC4.0新的消息反射在控件类中指定颜色。当控件需要重新着色时,工作框调用父窗口(通常是对话框)的CWnd: : OnCrtlColor,可以在父窗口类中重置该函数并指定控件的新的绘画属性。例如,下述代码将对话中的所有编辑控件文本颜色改为红色:  
 
HBRUSH CAboutDig : : OnCtlColor (CDC * pDCM , CWnd * pWnd , UINT nCtlColor)  
{  
    HBRUSH hbr = CDialog : : OnCtlColor (pDC, pWnd , nCtlColor );  
    //Draw red text for all edit controls .  
    if (nCtlColor= = CTLCOLOR_EDIT )  
    pDC —> SetTextColor (RGB (255 , 0 , 0 , ) ) ;  
    return hbr ;  
}  
 
然而,由于每个父窗口必须处理通知消息并指定每个控件的绘画属性,所以,这种方法不是完全的面向对象的方法。控件处理该消息并指定绘画属性更合情合理。消息反射允许用户这样做。通知消息首先发送给父窗口,如果父窗口没有处理则发送给控件。创建一个定制彩色列表框控件必须遵循下述步骤。  
 
首先,使用ClassWizard 创建一个CListBox 的派生类并为该类添加下述数据成员。  
 
class CMyListBox ; publilc CListBox  
{  
    …  
    private;  
    COLORREF m_clrFor ; // foreground color  
    COLORREF m_clrBack ; //background color  
    Cbrush m_brush ; //background brush  
    …  
} ;  
 
其次,在类的构造函数中,初始化数据中。  
 
CMyListBox : : CMyListBox ()  
{  
    //Initialize data members .  
    m_clrFore =RGB (255 , 255 , 0) ; // yellow text  
    m_clrBack=RGB (0 , 0 , 255) ; // blue background  
    m_brush . CreateSolidBrush (m _clrBack );  
}  
 
最后,使用ClassWizard处理反射的WM_CTLCOLOR(=WM_CTLCOLOR)消息并指定新的绘画属性。  
 
HBRUSH CMyListBox : : CtlColor (CDC* pDC, UINT nCtlColor )  
{  
    pDC—>SetTextColor (m_clrFore);  
    pDC—>SetBkColor (m_clrBack);  
    return (HBRUSH) m_brush.GetSafeHandle ()  
}  
 
现在,控件可以自己决定如何绘画,与父窗口无关。  
 
45、当向列表框中添加多个项时如何防止闪烁  
 
调用CWnd::SetRedraw 清除重画标志可以禁止CListBox(或者窗口)重画。当向列表框添加几个项时,用户可以清除重画标志,然后添加项,最后恢复重画标志。为确保重画列表框的新项,调用SetRedraw (TRUE) 之后调用CWnd::Invalidate。  
//Disable redrawing.  
pListBox->SetRedraw (FALSE);  
//Fill in the list box gere  
//Enable drwing and make sure list box is redrawn.  
pListBox->SetRedraw (TRUE);  
pListBox->Invalidate ();  
 
46、如何向编辑控件中添加文本  
 
由于没有CEdit:: AppendText函数,用户只好自己做此项工作。调用CEdit:: SetSel移动到编辑控件末尾,然后调用CEdit:: ReplaceSel添加文本。下例是AppendText 的一种实现方法:  
 
void CMyEdit:: AppendText (LPCSTR pText)  
{  
    int nLen=GetWindowTextLength ();  
    SetFocus ();  
    SetSel (nLen, nLen);  
    ReplaceSel (pText);  
}  
 
47、如何访问预定义的GDI对象  
 
可以通过调用CDC:: SlectStockObject使用Windows的几个预定义的对象,诸如刷子、笔以及字体。下例使用了Windows预定义的笔和刷子GDI对象在视窗中画一个椭圆。  
 
//Draw ellipse using stock black pen and gray brush.  
void CSampleView:: OnDraw (CDC* pDC)  
{  
    //Determine size of view.  
    CRect rcView;  
    GetClientRect (rcView);  
    //Use stock black pen and stock gray brush to draw ellipse.  
    pDC->SelectStockObject (BLACK_PEN);  
    pDC->SelectStockObject (GRAY_BRUSH)  
    //Draw the ellipse.  
    pDC->Ellipse (reView);  
}  
 
也可以调用新的SDK函数GetSysColorBrush获取一个系统颜色刷子,下例用背景色在视窗中画一个椭圆:  
 
void CsampleView:: OnDraw (CDC* pDC)  
{  
    //Determine size of view.  
    CRect rcView;  
    GetClientRect (rcView);  
    //Use background color for tooltips brush.  
    CBrush * pOrgBrush=pDC->SelectObject (  
    CBrush::FromHandle (::GetSysColorBrush (COLOR_INFOBK)));  
    //Draw the ellipse.  
    pDC->Ellipse (rcView);  
    //Restore original brush.  
    pDC->SelectObject (pOrgBrush);  
}  
 
48、如何获取GDI对象的属性信息  
 
可以调用GDIObject:: GetObject。这个函数将指定图表设备的消息写入到缓冲区。下例创建了几个有用的辅助函数。  
 
//Determine if font is bold.  
 
BOOL IsFontBold (const CFont&font)  
{  
    LOGFONT stFont;  
    font.GetObject (sizeof (LOGFONT), &stFont);  
    return (stFont.lfBold)? TRUE: FALSE;  
}  
 
//Return the size of a bitmap.  
 
CSize GetBitmapSize (const CBitmap&bitmap)  
{  
    BITMAP stBitmap;  
    bitmap.GetObject (sizeof (BITMAP), &stBitmap);  
    return CSize (stBitmap.bmWidth, stBitmap. bmHeight);  
}  
 
//Create a pen with the same color as a brush.  
 
BOOL CreatePenFromBrush (Cpen&pen, cost Cbrush&brush)  
{  
    LOGBRUSH stBrush;  
    brush.Getobject (sizeof (LOGBRUSH), &stBrush);  
    return pen. Createpen (PS_SOLID, 0, stBrush.ibColor);  
}  
 
 

阅读(441) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~