VC常见问题108三.docx
《VC常见问题108三.docx》由会员分享,可在线阅读,更多相关《VC常见问题108三.docx(14页珍藏版)》请在冰豆网上搜索。
![VC常见问题108三.docx](https://file1.bdocx.com/fileroot1/2023-6/12/b48be190-6c8f-472b-a831-1bb79d19a263/b48be190-6c8f-472b-a831-1bb79d19a2631.gif)
VC常见问题108三
(73)如何访问桌面窗口
静态函数CWnd:
:
GetDesktopWindow返回桌面窗口的指针。
下例说明了MFC函数CFrameWnd:
:
BeginModalStae是如何使用该函数进入内部窗口列表的。
voidCFrameWnd:
:
BeginModalState()
{
…
//firstcountallwindowsthatneedtobedisabled
UINTnCount=0
HWNDhWnd=:
:
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)
}
…
(74)什么是COLORREF?
我该怎样用它?
COLORREF是一个32-bit整型数值,它代表了一种颜色。
你可以使用RGB函数来初始化COLORREF。
例如:
COLORREFcolor=RGB(0,255,0);
RGB函数接收三个0-255数值,一个代表红色,一个代表绿色,一个代表蓝色。
在上面的例子中,红色和蓝色值都为0,所以在该颜色中没有红色和蓝色。
绿色为最大值255。
所以该颜色为绿色。
0,0,0为黑色,255,255,255为白色。
另一种初始化COLORREF的方法如下所示:
CColorDialogcolorDialog;
COLORREFcolor;
if(colorDialog.DoModal()==IDOK)
{
color=colorDialog.GetColor();
}
这段代码使用了MFC中的颜色对话框,它需要文件。
(75)AppWizard所产生的STDAFX文件是干什么用的?
它主要是协助产生预编译头文件的。
通常你是不需要修改它的。
(76)我在我的程序中是了CDWordArray。
我向它添加了约10,000个整数,这使得它变得非常非常慢。
为什么会这么糟?
CDWordArray是很好用的,只是因为你没有指定数组的最大尺寸。
因此,当你添加新元素时,该类会从堆中重新分配空间。
不幸的是,该类会在每次插入新元素时都为数组重新分配空间。
如果你向它添加了很多新元素,所有这些分配和复制数组的操作会就会使它变慢。
解决该问题的方法是,你可以使用SetSize函数的第二个参数来改变这种重新分配的频率。
例如,如果你把该参数设置为500,则每次数组空间超出时它才重新分配并添加500个新空间,而不是1个。
这样一来,你就可以不用重新分配而添加了另外499个元素空间,这也会大大提高程序的运行速度。
(77)我该如何改变MDI框架窗口的子窗口的大小以使在窗口以一定的大小打开?
在视中的OnInitialUpdate函数中调用GetParentFrame函数。
GetParentFrame会返回一指向一保存有该视的框架窗口的指针。
然后调用在框架窗口上调用MoveWindow。
(78)在我的程序的某些部分,我可以调用MessageBox函数来建立一个信息对话框,例如在视类中。
但是,在其它部分我却不能,如文档类中。
为什么?
我怎样才能在我的应用程序类中建立一个信息对话框?
MessageBox函数来自CWnd类,所以你只能在从CWnd继承的类(如CView)中调用它。
但是,MFC也提供了AfxMessageBox函数,你可以在任何地方调用它。
(79)我需要在我的程序中设置全局变量,以使文档中的所有类都能访问。
我应该吧它放到哪儿?
把该变量放到该应用程序类的头文件中的attribute处。
然后,在程序的任何地方,你都可以用下面的方法来访问该变量:
CMyApp*app=(CMyApp*)AfxGetApp();
app->MyGlobalVariable=...
(80)我听说MFC可以发现内存漏洞,我怎样使用该特性?
如果你在Debug菜单中的Go选项(不是Project菜单中的Execute选项)来运行你的应用程序,MFC应该在程序终止时报告内存漏洞。
如果没有,那么试试运行MFCTracer工具程序(在VC++程序组中),并启动跟踪。
然后返回应用程序。
(81)我怎样才能在我的应用程序中循环浏览已经打开的文档?
使用CDocTemplate中未公开的GetFirstDocPosition()和GetNextDoc()函数。
(82)才能在我的应用程序中循环浏览已经打开的视?
使用CDocument中未公开的GetFirstViewPosition()和GetNextView()函数。
(83)数PreCreateWindow是干什么用的?
PreCreateWindow允许你在调用CreateWindow之前来改变窗口属性。
(84)该怎样防止MFC在窗口标题栏上把文档名预置成应用程序名?
在PreCreateWindow函数中删除FWS_PREFIXTITLE标志的窗口样式:
cs.style&=~FWS_PREFIXTITLE;
(85)我应该怎样防止MFC在窗口标题栏上添加文档名?
在PreCreateWindow函数中删除FWS_ADDTOTITLE标志的窗口样式:
cs.style&=~FWS_ADDTOTITLE;
(86)我应该如何改变视窗口的大小?
因为视窗口实际上是框架窗口的子窗口,所以你必须改变框架窗口的大小,而不是改变视窗口。
使用CView类中的GetParentFrame()函数获得指向框架窗口的指针,然后调用MoveWindow()函数来改变框架的大小。
这会使变尺寸的视充满框架窗口。
(87)我有一无模式对话框。
我怎样才能在窗口退出时删除CDialog对象?
把“deletethis”加到PostNcDestroy中。
这主要用在需要自动删除对象的场合。
(88)为什么把“deletethis”放在PostNcDestroy中而不是OnNcDestroy?
OnNcDestroy只被已建立的窗口调用。
如果建立窗口失败(如PreCreateWindow),则没有窗口处来发送WM_NCDESTROY消息。
PostNcDestroy是在对象窗口被完全删除,在OnNcDestroy后,甚至在窗口建立失败之后调用的。
(89)File菜单中的MRU列表是从哪儿来的?
列表中的名字放在哪儿了?
我怎样才能改变列表中项目的最大值?
在应用程序类的InitInstance函数中对LoadStdProfileSettings的调用中。
该调用接受一个参数(在缺省情况下如果没有传递值则为4)。
MRU文件名是从INI文件中调用的。
如果你有带有ID_FILE_MRU_FILE1的ID的菜单选项,它会为调入的MRU列表所替换。
如果你改变传递给LoadStdProfileSettings的数值(最大为16),则你就改变了所装如文件名的最大值。
(90)我在菜单中添加了新的项。
但是,当我选该项时,在状态栏上没有出现任何提示信息。
为什么?
打开资源文件中的菜单模板。
打开新菜单选项的属性对话框。
在对话框的底部的Prompt编辑框中,你可以如下指定状态栏上的提示信息和工具栏上的提示信息(如果你已经建立的工具栏按钮):
Statusbarstring\nFlyingtag
(91)我怎样才能在应用程序的缺省系统菜单中加上一些东西?
系统菜单与其它菜单类似,你可以添加或删除项目,这需要使用CMenu类的成员函数。
下面的代码在你的系统菜单后面添加一个新菜单项:
CMenu*sysmenu;
sysmenu=m_pMainWnd->GetSystemMenu(FALSE);
sysmenu->AppendMenu(MF_STRING,1000,"xxx");
参见MFC帮助文件中的CMenu类。
(92)我建立了一个对话框。
但是当我显示该对话框时,第一个编辑框总是不能获得焦点,我必须单击它来使它获得焦点。
我怎样才能使第一个编辑框在对话框打开时就获得焦点?
打开资源编辑器中的对话框模板。
在Layout菜单中选择TabOrder选项。
按你的需求单击对话框中的控制来重新排列这些控制的tab顺序。
(93)我怎样才能使一个窗口具有“alwaysontop”特性?
在调用OnFileNew后,在你的InitInstance函数中加上下面的代码:
m_pMainWnd->SetWindowPos(&CWnd:
:
wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
(94)我要为我的formview添加文档模板。
我先建立了对话框模板,然后使用ClassWizard建立了基于CFormView的新类,它也是从CDocument继承来的。
我还建立了相应的资源并在InitInstance中添加了新的文档模板。
但是,当我试图运行该程序时,出现了Assertion信息。
为什么?
form的对话框模板需要些特殊设置以便可用于CFromView。
确保这些设置的最简单方法是使用AppWizard来建立CFormView应用程序,并查看AppWizard所建立的对话框模板所选择的StylesProperties。
你会发现该对话框模板具有下列样式:
没有标题栏、不可见和“Child”。
把你的formview的对话框属性变成这样就可以了。
(95)我在一对话框中有一列表框,我需要tabbed列表框中的项目。
但是,当我处理含有tab字符(用AddString添加的)的列表项时,tab被显示成小黑块而没有展开。
哪儿出错了?
在对话框模版中,打开列表框的属性。
确保选择了“UseTabstops”样式。
然后,确保在对话框类中OnInitDialog函数中调用SetTabStops。
(96)我建立了一个应用程序,并使用了CRecordset类。
但是,当我运行该程序时,它试图要访问数据库,并给出“InternalApplicationError”对话框。
我应该怎样做?
通常情况下,当你的程序中向数据库发送信息的SQL语句出现问题时才出现该对话框。
例如,参见下面的例子:
set.m_strFilter="(ZipCode='27111')";
如果ZipCode列被定义为字符串时不会出现问题,如果定义为long,则会出现“InternalApplicationError”对话框,这是由于类型不匹配的缘故。
如果你删除27111的单引号,则不会出现问题。
当你看到“InternalApplicationError”时,最好检查一下试图要发送给数据库的SQL语句。
(97)我用ClassWizard建立了一个类。
但是,我把名字取错了,我想把它从项目中删除,应该如何做?
在ClassWizard对话框关闭后,用文件管理器删除新类的H和CPP文件。
然后打开ClassWizard,它会提示丢失了两个文件,并询问你该如何做。
你可以选择从项目中删除这两个问的按钮。
(98)当我打开应用程序中的窗口时,我要传递该窗口的矩形尺寸。
该矩形指定了窗口的外围大小,但是当我调用GetClientRect时,所得到的尺寸要比所希望的值要小(因为工具栏和窗口边框的缘故)。
有其它方法来计算窗口的尺寸吗?
参见CWnd:
:
CalcWindowRect。
(99)我在文档类中设置了一个整型变量。
但是,当我试图把该变量写入Serialize函数中的archive文件中时,出现了类型错误。
而文档中的其它变量没有问题。
为什么?
archive类只重载某些类型的>>和<<操作符。
“int”类型没有在其中,也许是因为int变量在Windows3.1与WindowsNT/95有所不同的缘故吧。
“long”类型得到了支持,所以你可以把int类型改成long型。
参见MFC帮助文件中CArchive类。
(100)如何控制菜单的大小?
我用MFC的CMenu生成了一个动态菜单(例如File,Edit,View...Help),我想控制这个菜单的大小(长+高).
方法一:
查找WM_MEASUREITEM和MEASUREITEMSTRUCT.
方法二:
查询系统:
:
GetSystemMetric(SM_CXMENUSIZE).
/*你可以通过如下代码来获得文本的大小:
(A)获得被使用的字体*/
NONCLIENTMETRICSncm;
HFONThFontMenu;
SIZEsize;
size.cy=size.cy=0;
memset(&ncm,0,sizeof(NONCLIENTMETRICS));
ncm.cbSize=sizeof(NONCLIENTMETRICS);
if(SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS),&ncm,0))
{
hFontMenu=CreateFontIndirect(&ncm.lfMenuFont);
/*
(B)获得菜单项的文本:
*/
charszText[_MAX_PATH];
pMenu->GetMenuString(0,szText,_MAX_PATH,MF_BYPOSITION);
/*
然后,获得菜单项文本的高度:
*/
HFONThFontOld;
HDChDC;
hDC=:
:
GetDC(NULL);
hFontOld=(HFONT):
:
SelectObject(hDC,hFontMenu);
GetTextExtentPoint32(hDC,szText,lstrlen(szText),&size);
SelectObject(hDC,hFontOld);
:
:
ReleaseDC(NULL,hDC);
}
/*此时,size.cy即为高度,size.cx为宽度,你可以给菜单加上自定义的高度和宽度,通过比较,我发现宽度为4
比较合适。
*/
(101)改变LVIS_SELECTED的状态颜色?
我想将CListCtrl项和CTreeCtrl项在LVIS_SELECTED状态时的颜色变灰.
方法一:
查找函数CustomDraw,它是IE4提供的公共控制,允许有你自己的代码.
方法二:
生成一个draw控件,然后在DrawItem中处理文本颜色.
(102)如何只存储文档的某一部分?
我只想存储文档的某一部分,能否象使用文件一样使用文档?
(也就是有定位函数).将每个CArchive类设置为CFile类的派生类,这样你就能使用Seek等成员函数.
(103)保存工具条菜单有bug吗?
使用浮动菜单条时,SaveBarState和LoadBarState出现了问题.如果菜单是浮动的,重起应用程序时它会出现在左上角,而它固定在屏幕其它位置时,下一次启动就会出现在该位置,这是什么原因?
你试试这个PToolBar->Create(this,...,ID_MYTOOLBAR);
你的工具条需要包括id,而不是象默认的工具条那样.
(104)Tipoftheday的bug
我创建了一个简单的mdi应用程序,使用.BSF(自定义的文档扩展名)作为它的文档我保存一个foo.bsf文档后,可以在资源管理器中双击该文件打开mdi应用程序同时打开foo.bsf文档.但当我给mdi应用程序加上atipoftheday组件之后,从资源管理器中双击foo.bsf后,就会给我一个警告:
ASSERT(:
:
IsWindow(m_hWnd)),然后mdi应用程序就死那了.
当从dde启动应用程序(例如:
双击相关文档)时,"TipoftheDay"是有bug的.你可以看看函数"ShowTipAtStartup",它在"InitInstance"中调用,可以看到tipoftheday作为一个模式对话框显示,在处理其它消息时它一直进行消息循环你可心修改ShowTipAtStartup使其从dde启动时不出现tipoftheday.
voidCTipOfApp:
:
ShowTipAtStartup(void)
{
//CG:
Thisfunctionaddedby'TipoftheDay'component.
CCommandLineInfocmdInfo;
ParseCommandLine(cmdInfo);
if(
cmdInfo.m_bShowSplash&&
cmdInfo.m_nShellCommand!
=CCommandLineInf:
FileDDE
)
{
CTipDlgdlg;
if(dlg.m_bStartup)
dlg.DoModal();
}
}
如果还有其它bug,你可以设定cmdInfo.m_nShellCommand的过滤.
(105)如何可以让我的程序可以显示在其它的窗口上面?
让用户选择"总是在最上面"最好是在系统菜单里加入一个选项.可以通过修改WM_SYSCOMMAND消息来发送用户的选择.菜单的命令标识(id)会作为一个参数传给OnSysCommand().要定义标识(id),将如下代码加入到CMainFrame.CPP中:
#defineWM_ALWAYSONTOPWM_USER+1
将"总在最上面"的菜单项加入到系统菜单中,将如下代码加入到函数CMainFrame:
:
OnCreate()中:
CMenu*pSysMenu=GetSystemMenu(FALSE);
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,WM_ALWAYSONTOP,
"&AlwaysOnTop");
使用ClassWizard,加入对WM_SYSCOMMAND消息的处理,你应该改变消息过滤器,使用系统可以处理这个消息.
voidCMainFrame:
:
OnSysCommand(UINTnID,LPARAMlParam)
{
switch(nID)
{
caseWM_ALWAYSONTOP:
if(GetExStyle()&WS_EX_TOPMOST)
{
SetWindowPos(&wndNoTopMost,0,0,0,0,
SWP_NOSIZE|SWP_NOMOVE);
GetSystemMenu(FALSE)->CheckMenuItem(WM_ALWAYSONTOP,
MF_UNCHECKED);
}
else
{
SetWindowPos(&wndTopMost,0,0,0,0,
SWP_NOSIZE|SWP_NOMOVE);
GetSystemMenu(FALSE)->CheckMenuItem(WM_ALWAYSONTOP,MF_CHECKED);
}
break;
default:
CFrameWnd:
:
OnSysCommand(nID,lParam);
}
}
(106)如何控制窗口框架的最大最小尺寸?
要控制一个框架的的最大最小尺寸,你需要做两件事情.在CFrameWnd的继承类中处理消息WM_GETMINMAXINFO,结构MINMAXINFO设置了整个窗口类的限制,因此记住要考虑工具条,卷动条等等