Board logo

标题: [VC++] Visual C++编程技巧之八 [打印本页]

作者: forder    时间: 2006-3-24 10:24     标题: Visual C++编程技巧之八

57、为什么即使调用enablemenuitem菜单项后,菜单项还处于禁止状态

需要将cframewnd:: m_bautomenuenable设置为false,如果该数据成员为true(缺省值),工作框将自动地禁止没有on_update_command_ui或者on_command的菜单项。

//disable mfc from automatically disabling menu items.

m_bauomenuenable=false;

//now enable the menu item.

cmenu* pmenu=getmenu ();

assert_valid (pmenu);

pmenu->enablemenuitem (id_menu_item,mf_bycommand | mf_enabled);

58、如何给系统菜单添加一个菜单项

给系统菜单添加一个菜单项需要进行下述三个步骤:

首先,使用resource symbols对话(在view菜单中选择resource symbols...

可以显示该对话)定义菜单项id,该id应大于0x0f而小于0xf000;

其次,调用cwnd::getsystemmenu获取系统菜单的指针并调用cwnd:: appendmenu将菜单项添加到菜单中。下例给系统菜单添加两个新的菜单项:

int cmainframe:: oncreate (lpcreatestruct lpcreatestruct)

{



//make sure system menu item is in the right range.

assert (idm_mysysitem &0xfff0)==idm_mysysitem);

assert (idm-mysysitem<0xf000);

//get pointer to system menu.

cmenu* psysmenu=getsystemmenu (false);

assert_valid (psysmenu);

//add a separator and our menu item to system menu.

cstring strmenuitem (_t ("new menu item"));

psysmenu->appendmenu (mf_separator);

psysmenu->appendmenu (mf_string, idm_mysysitem, strmenuitem);



}

现在,选择系统菜单项时用户应进行检测。使用classwizard处理

wm_syscommand消息并检测用户菜单的nid参数:

void cmainframe:: onsyscommand (uint nid,lparam lparam)

{

//determine if our system menu item was selected.

if ( (nid & 0xfff0)==idm_mysysitem)

{

//todo-process system menu item

}

else

cmdiframewnd:: onsyscommand (nid, lparam);

}

最后,一个设计良好的ui应用程序应当在系统菜单项加亮时在状态条显示一个帮助信息,这可以通过增加一个包含系统菜单基id的串表的入口来实现。

59、如何确定顶层菜单所占据的菜单行数

这可以通过简单的减法和除法来实现。首先,用户需要计算主框窗口的高度和客户区;其次,从主框窗口的高度中减去客户区、框边界以及标题的高度;最后,除以菜单栏的高度。下例成员函数是一个计算主框菜单所占据的行数的代码实现。

int cmainframe:: getmenurows ()

{

crect rcframe,rcclient;

getwindowrect (rcframe);

getclientrect (rcclient);

return (rcframe.height () -rcclient.height ()-

:: getsystemmetrics (sm_cycaption) -

(:: getsystemmetrics (sm_cyframe) *2)) /

:: getsystemmetrics (sm_cymenu);

}

60、在用户环境中如何确定系统显示元素的颜色

调用sdk函数getsyscolor可以获取一个特定显示元素的颜色。下例说明了如何在mfc函数cmainframewnd:: onncpaint中调用该函数设置窗口标题颜色。

void cminiframewnd:: onncpaint ()

{



dc.settextcolor (:: getsyscolor (m_bactive ?

color_captiontext : color_inactivecaptiontext));



}

61、如何查询和设置系统参数

在windows 3.1 sdk中介绍过sdk函数systemparametersinfo,调用该函数可以查询和设置系统参数,诸如按键的重复速率设置、鼠标双击延迟时间、图标字体以及桌面覆盖位图等等。

//create a font that is used for icon titles.

logfont stfont;

:: systemparametersinfo (spif_geticontitlelogfont,

sizeof (logfont), &stfont, spif_sendwininichange);

m_font.createfontindirect (&stfont);

//change the wallpaper to leaves.bmp.

:: systemparametersinfo (spi_setdeskwallpaper, 0,

_t (" forest.bmp"), spif_updateinifile);

62、如何使用一个预定义的windows光标

调用cwinapp:: loadstandardcursor并传送光标标识符。

bool csampledialog:: onsetcursor (cwnd* pwnd, uint nhittest, uint message)

{

//display wait cursor if busy.

if (m_bbusy)

{

setcursor (afxgetapp () ->loadstandardcursor (idc_wait));

return true;

}

return cdialog:: onsetcursor (pwnd. nhittest,message);

}

63、如何确定当前屏幕分辨率

调用sdk函数getsystemmetrics,该函数可以检索有关windows显示信息,诸如标题大小、边界大小以及滚动条大小等等。

//initialize csize object with screen size.

csize sizescreen (getsystemmetrics (sm_cxscreen),

getsystemmetrics (sm_cyscreen));

64、如何检索原先的task manager应用程序使用的任务列表

原先的task manager应用程序显示顶层窗口的列表。为了显示该列表,窗口

必须可见、包含一个标题以及不能被其他窗口拥有。调用cwnd:: getwindow可以

检索顶层窗口的列表,调用iswindowvisible、getwindowtextlength以及getowner

可以确定窗口是否应该在列表中。下例将把taskmanager窗口的标题填充到列表中。

void gettadklist (clistbox&list)

{

cstring strcaption; //caption of window.

list.resetcontent (); //clear list box.

//get first window in window list.

assert_valid (afxgetmainwnd ());

cwnd* pwnd=afxgetmainwnd () ->getwindow (gw_hwndfirst);

//walk window list.

while (pwnd)

{

// i window visible, has a caption, and does not have an owner?

if (pwnd ->iswindowvisible () &&

pwnd ->getwindowtextlength () &&! pwnd ->getowner ())

{

//add caption o window to list box.

pwnd ->getwindowtext (strcaption);

list.addstring (strcaption);

}

//get next window in window list.

pwnd=pwnd->getwindow (gw_hwndnext);

}

}

65、如何确定windows和windows系统目录

有两个sdk函数可以完成该功能。getwindowsdirectory和getsystemdirectory,下例说明了如何使用这两个函数:

tchar szdir [max_path];

//get the full path of the windows directory.

:: getwindowsdirectory (szdir, max_path);

trace ("windows directory %s\n", szdir);

//get the full path of the windows system directory.

:: getsystemdirectory (szdir, max_path);

trace ("windows system directory %s\n", szdir);

66、在哪儿创建临文件

调用sdk函数gettempath可以确定临时文件的目录,该函数首先为临时路径检测tmp环境变量:如果没有指定tmp,检测tmp环境变量,然后返回到当前目录。下例说明了如何创建一个临时文件。



//get unique temporary file.

cstring strfile;

getuniquetempname (strfile);

try

{

//create file and write data.note that file is closed

//in the destructor of the cfile object.

cfile file (strfile,cfile:: modecreate | cfile:: modewrite);

//write data

}

catch (cfileexception, e)

{

//error opening file

}

end_catch



void getuniquetempname (cstring& strtempname)

{

//get the temporary files directory.

tchar sztemppath [max_path];

dword dwresult=:: gettemppath (max_path, sztemppath);

assert (dwresult);

//create a unique temporary file.

tchar sztempfile [max_path];

uint nresult=gettempfilename (sztemppath, _t ("~ex"),0,sztempfile);

assert (nresult);

strtempname=sztempfile;

}

67、如何访问桌面窗口

静态函数cwnd:: getdesktopwindow 返回桌面窗口的指针。下例说明了mfc函数cframewnd::beginmodalstae是如何使用该函数进入内部窗口列表的。

void cframewnd::beginmodalstate ()

{



//first count all windows that need to be disabled

uint ncount=0;

hwnd hwnd=:: getwindow (:: getdesktopwindow (), gw_child);

while (hwnd!=null)

{

if (:: iswindowenabled (hwnd) &&

cwnd::fromhandlepermanent (hwnd)!=null &&

afxisdescendant (pparent->m_hwnd, hwnd) &&

:: sendmessage (hwnd, wm_disablemodal, 0, 0)==0)

{

++ncount;

}

hwnd=:: getwindow (hwnd, gw_hwndnext);

}



}




欢迎光临 逐梦论坛 (http://temp2023.zhumeng.org/) Powered by Discuz! 7.2