逐梦论坛's Archiver

forder 发表于 2006-3-24 10:22

Visual C++编程技巧之六

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 ( 0, 0, 100 , 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);

}

annade123 发表于 2011-7-21 15:20

谢谢分享啊!:)

besteast 发表于 2011-10-12 12:23

[EM18][EM18]

www.dulady.com 发表于 2012-7-31 20:42

呵呵,好帖,好好看看

hotju.com 发表于 2012-9-20 02:57

不服不行,楼主就是有水平

bxumra 发表于 2012-9-23 15:52

不错不错,很好很好,谢谢分享

bxumra 发表于 2012-9-23 16:05

超值强帖,帮你顶,^_^

bxumra 发表于 2012-9-26 20:05

顶......叹为观止.....

我爱辩论 发表于 2013-4-13 18:06

建议你可以参加一下争鸣举办的中华辩论爱好者网络辩论赛(CDA),无论是参赛,还是当观众,都能学习到很多东西,具体可以加QQ171735378

509ckk 发表于 2013-8-28 08:28

没来得急看,应该不错,先帮你顶

wmykt 发表于 2014-7-8 10:35

呵呵,加油!











bjcars.net

页: [1]

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.