|   
 | 
| 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);
 
 }
 
 …
 
 }
 | 
 |