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