逐梦论坛's Archiver

forder 发表于 2006-3-23 12:51

Visual C++编程技巧之四

25、如何获取有关窗口正在处理的当前消息的信息

调用cwnd: : getcurrentmessage可以获取一个msg指针。例如,可以使用

classwizard将几个菜单项处理程序映射到一个函数中,然后调用getcurrentmessage

来确定所选中的菜单项。

viod cmainframe : : oncommmonmenuhandler ( )

{

//display selected menu item in debug window .

trace ("menu item %u was selected . \n" ,

getcruuentmessage ( ) —> wparam );

}

26、如何创建一个不规则形状的窗口

可以使用新的sdk函数setwindowrgn。该函数将绘画和鼠标消息限定在窗口的一

个指定的区域,实际上使窗口成为指定的不规则形状。

使用appwizard创建一个基于对的应用程序并使用资源编辑器从主对话资源中删

除所在的缺省控件、标题以及边界。

给对话类增加一个crgn数据成员,以后要使用该数据成员建立窗口区域。

class crounddlg : public cdialog

{



private :

crgn m_rgn : // window region



} ;

修改oninitdialog函数建立一个椭圆区域并调用setwindowrgn将该区域分配给

窗口:

bool crounddlg : : oninitdialog ( )

{

cdialog : : oninitdialog ( ) ;

//get size of dialog .

crect rcdialog ;

getclientrect (rcdialog );

// create region and assign to window .

m_rgn . createellipticrgn (0 , 0 , rcdialog.width ( ) , rcdialog .height ( ) );

setwindowrgn (getsafehwnd ( ) , (hrgn) m_ rgn , true );

return true ;

}

通过建立区域和调用setwindowrgn,已经建立一个不规则形状的窗口,下面的例

子程序是修改onpaint函数使窗口形状看起来象一个球形体。

voik crounddlg : : onpaint ( )

{

cpaintdc de (this) ; // device context for painting .

//draw ellipse with out any border

dc. selecstockobject (null_pen);

//get the rgb colour components of the sphere color

colorref color= rgb( 0 , 0 , 255);

byte byred =getrvalue (color);

byte bygreen = getgvalue (color);

byte byblue = getbvalue (color);

// get the size of the view window

crect rect ;

getclientrect (rect);

// get minimun number of units

int nunits =min (rect.right , rect.bottom );

//calculate he horiaontal and vertical step size

float fltstephorz = (float) rect.right /nunits ;

float fltstepvert = (float) rect.bottom /nunits ;

int nellipse = nunits/3; // calculate how many to draw

int nindex ; // current ellipse that is being draw

cbrush brush ; // bursh used for ellipse fill color

cbrush *pbrushold; // previous brush that was selected into dc

//draw ellipse , gradually moving towards upper-right corner

for (nindex = 0 ; nindes < + nellipse ; nindes ++)

{

//creat solid brush

brush . creatsolidbrush (rgb ( ( (nindex *byred ) /nellipse ).

( ( nindex * bygreen ) /nellipse ), ( (nindex * byblue) /nellipse ) ) );

//select brush into dc

pbrushold= dc .selectobject (&brhsh);

//draw ellipse

dc .ellipse ( (int) fltstephorz * 2, (int) fltstepvert * nindex ,

rect. right -( (int) fltstephorz * nindex )+ 1,

rect . bottom -( (int) fltstepvert * (nindex *2) ) +1) ;

//delete the brush

brush.delecteobject ( );

}

}

最后,处理wm_nchittest消息,使当击打窗口的任何位置时能移动窗口。

uint crounddlg : : onnchittest (cpoint point )

{

//let user move window by clickign anywhere on the window .

uint nhittest = cdialog : : onnchittest (point) ;

rerurn (nhittest = = htclient)? htcaption: nhittest ;

}

27、如何在代码中获取工具条和状态条的指针

缺省时, 工作框创建状态条和工具条时将它们作为主框窗口的子窗口,状态条

有一个afx_idw_status_bar标识符,工具条有一个afx_idw_toolbar标识符,下例说

明了如何通过一起调用cwnd: : getdescendantwindow和afxgetmainwnd来获取这些

子窗口的指针:

//get pointer to status bar .

cstatusbar * pstatusbar =

(cstatusbar *) afxgetmainwnd ( ) —> getdescendantwindow

(afx_idw_stutus_bar);

//get pointer to toolbar .

ctoolbar * ptoolbar =

(ctoolbar * ) afxgetmainwnd ( ) —> getdescendantwindow (afx_idw_toolbar);

28、如何使能和禁止工具条的工具提示

如果设置了cbrs_tooltips风格位,工具条将显示工具提示,要使能或者禁止

工具提示,需要设置或者清除该风格位。下例通过调用ccontrolbar : : getbarstyle

和ccontrolbar : : setbarstyle建立一个完成此功能的成员函数:

void cmainframe : : enabletooltips ( bool bdisplaytips )

{

assert_valid (m_wndtoolbar);

dword dwstyle = m _wndtoolbar.getbarstyle ( ) ;

if (bdisplaytips)

dwstyle |=cbrs_tooltips ;

else

dwstyle & = ~ cbrs_tooltips ;

m_wndtoolbar.setbarstyle (dwstyle );

}

29、如何设置工具条标题

工具条是一个窗口,所以可以在调用cwnd : : setwindowtext来设置标题,例子如下:

int cmainframe : : oncreate (lpcreatestruct lpcreatestruct )

{



// set the caption of the toolbar .

m_wndtoolbar.setwindowtext (_t "standdard");

30、如何创建和使用无模式对话框

mfc将模式和无模式对话封装在同一个类中,但是使用无模式对话需要几

个对话需要几个额处的步骤。首先,使用资源编辑器建立对话资源并使用

classwizard创建一个cdialog的派生类。模式和无模式对话的中止是不一样的:

模式对话通过调用cdialog : : enddialog 来中止,无模式对话则是调用

cwnd: : destroywindow来中止的,函数cdialog : : onok和cdialog : : oncancel

调用enddialog ,所以需要调用destroywindow并重置无模式对话的函数。

void csampledialog : : onok ( )

{

// retrieve and validate dialog data .

if (! updatedata (true) )

{

// the updatedata rountine will set focus to correct item

traceo (" updatedata failed during dialog termination .\n") ;

return ;

}

//call destroywindow instead of enddialog .

destroywindow ( ) ;

}

void csampledialog : : oncancel ( )

{

//call destroywindow instead of enddialog .

destroywindow ( ) ;

}

其次,需要正确删除表示对话的c++对象。对于模式对来说,这很容易,需要创建函数返回后即可删除c++对象;无模式对话不是同步的,创建函数调用后立即返回,因而用户不知道何时删除c++对象。撤销窗口时工作框调用cwnd : : postncdestroy,可以重置该函数并执行清除操作,诸如删除this指针。

void csampledialog : : postncdestroy ( )

{

// declete the c++ object that represents this dialog .

delete this ;

}

最后,要创建无模式对话。可以调用cdialog : : domodal创建一个模式对放, 要创建一个无模式对话则要调用cdialog: : create。下面的例子说明了应用程序是如何创建无模式对话的:

void cmainframe : : onsampledialog ( )

{

//allocate a modeless dialog object .

csampledilog * pdialog =new csampledialog ;

assert_valid (pdialog) ;

//create the modeless dialog .

bool bresult = pdialog —> creste (idd_idalog) ;

assert (bresult ) ;

}

31、如何在对话框中显示一个位图

这要归功于win 32先进的静态控件和microsoft的资源编辑器, 在对话框中显示位图是很容易的, 只需将图形控件拖到对话中并选择适当属性即可,用户也可以显示图标、位图以及增强型元文件。

32、如何改变对话或窗体视窗的背景颜色

调用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 );

}

forder 发表于 2006-3-23 12:52

明天继续

页: [1]

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