📄 vc常用技巧.txt
字号:
CRect rcFrame,rcClient
GetWindowRect (rcFrame)
GetClientRect (rcClient)
return (rcFrame.Height () -rcClient.Height () - :: GetSystemMetrics(SM_CYCAPTION) - (:: getSystemMetrics(SM_CYFRAME) *2)) / :: GetSystemMetrics(SM_CYMENU)
}
(64) 在用户环境中如何确定系统显示元素的颜色
调用SDK函数GetSysColor可以获取一个特定显示元素的颜色。下例说明了如何在MFC函数CMainFrameWnd:: OnNcPaint中调用该函数设置窗口标题颜色。
void CMiniFrameWnd:: OnNcPaint ()
{
…
dc.SetTextColor (:: GetSysColor (m_bActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT))
…
(65) 如何查询和设置系统参数
在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)
(66) 如何确定当前屏幕分辨率
调用SDK函数GetSystemMetrics,该函数可以检索有关windows显示信息,诸如标题大小、边界大小以及滚动条大小等等。
//Initialize CSize object with screen size.
CSize sizeScreen (GetSystemMetrics (SM_CXSCREEN),
GetSystemMetrics (SM_CYSCREEN))
(67) 如何使用一个预定义的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)
}
(68) 如何检索原先的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)
}
}
(69) 如何确定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)
(70) 在哪儿创建临文件
调用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
}
(71) 我怎样才能建立一个等待光标?
调 用 BeginWaitCursor 函 数 来 启 动 等 待 光 标,调 用 EndWaitCursor 函 数 来 结 束 等 待 光 标。要 注 意,二 者 都 要 调 用 app 的 成 员 函 数,如 下 所 示:
AfxGetApp()->BeginWaitCursor();
// 要做的事
AfxGetApp()->EndWaitCursor();
(72) 我在MDI框架中有个 form 视窗。它有个取消按钮,我需要当用户按取消按钮时可关闭form视窗。我应该如何关闭该文档?
调 用 OnCloseDocument 函 数。
(73) 如何访问桌面窗口
静态函数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)
}
…
(74) 什么是COLORREF? 我该怎样用它?
COLORREF 是 一 个 32-bit 整 型 数 值,它 代 表 了 一 种 颜 色。你 可 以 使 用 RGB 函 数 来 初 始 化 COLORREF。例 如:
COLORREF color = RGB(0, 255, 0);
RGB 函 数 接 收 三 个 0-255 数 值,一 个 代 表 红 色, 一 个 代 表 绿 色, 一 个 代 表 蓝 色。在 上 面的 例 子 中, 红 色 和 蓝 色 值 都 为 0,所 以 在 该 颜 色 中 没 有 红 色 和 蓝 色。绿 色 为 最 大 值 255。所 以 该 颜 色 为 绿 色。0,0,0 为 黑 色,255,255,255 为 白 色。
另 一 种 初 始 化 COLORREF 的 方 法 如 下 所 示:
CColorDialog colorDialog;
COLORREF color;
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 应 该 在 程 序 终 止 时 报 告 内 存 漏 洞。如 果 没 有,那 么 试 试 运 行 MFC Tracer 工 具 程 序 ( 在 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对象?
把“delete this”加 到 PostNcDestroy 中。这 主 要 用 在 需 要 自 动 删 除 对 象 的 场 合。
(88) 为什么把“delete this”放在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 编 辑 框 中 ,你 可 以 如 下 指 定 状 态 栏 上 的 提 示 信 息 和 工 具 栏 上 的 提 示 信 息 ( 如 果 你 已 经 建 立 的 工 具 栏 按 钮 ):
Status bar string\nFlying tag
(91) 我怎样才能在应用程序的缺省系统菜单中加上一些东西?
系 统 菜 单 与 其 它 菜 单 类 似,你 可 以 添 加 或 删 除 项 目,这 需 要 使 用 CMenu 类 的 成 员 函 数。下 面 的 代 码 在 你 的 系 统 菜 单 后 面 添 加 一 个 新 菜 单 项:
CMenu *sysmenu;
sysmenu = m_pMainWnd->GetSystemMenu(FALSE);
sysmenu->AppendMenu(MF_STRING, 1000, "xxx");
参 见 MFC 帮 助 文 件 中 的 CMenu 类。
(92) 我建立了一个对话框。但是当我显示该对话框时,第一个编辑框总是不能获得焦点,我必须单击它来使它获得焦点。我怎样才能使第一个编辑框在对话框打开时就获得焦点?
打 开 资 源 编 辑 器 中 的 对 话 框 模 板。在 Layout 菜单 中 选 择 Tab Order 选 项。按 你 的 需 求 单 击 对 话 框 中 的 控 制 来 重 新 排 列 这 些 控 制 的 tab 顺 序。
(93) 我怎样才能使一个窗口具有“always on top”特性?
在 调 用 OnFileNew 后,在 你 的 InitInstance 函 数 中 加 上 下 面 的 代 码:
m_pMainWnd->SetWindowPos(&CWnd::wndTopMost,0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
(94) 我要为我的form view添加文档模板。我先建立了对话框模板,然后使用ClassWizard建立了基于CFormView的新类,它也是从CDocument继承来的。我还建立了相应的资源并在InitInstance中添加了新的文档模板。但是,当我试图运行该程序时,出现了Assertion信息。为什么?
form 的 对 话 框 模 板 需 要 些 特 殊 设 置 以 便 可 用 于 CFromView。确 保 这 些 设 置 的 最 简 单 方 法 是 使 用 AppWizard 来 建 立 CFormView 应 用 程 序,并 查 看 AppWizard 所 建 立 的 对 话 框 模 板 所 选 择 的Styles Properties。你 会 发 现 该 对 话 框 模 板 具 有 下 列 样 式:没 有 标 题 栏、不 可 见 和“Child”。把 你 的 form view 的 对 话 框 属 性 变 成 这 样 就 可 以 了。
(95) 我在一对话框中有一列表框,我需要tabbed列表框中的项目。但是,当我处理含有tab字符(用AddString添加的)的列表项时,tab被显示成小黑块而没有展开。哪儿出错了?
在 对 话 框 模 版 中,打 开 列 表 框 的 属 性。确 保 选 择 了“Use Tabstops” 样 式。然 后,确 保 在 对 话 框 类 中 OnInitDialog 函 数 中 调 用 SetTabStops。
(96) 我建立了一个应用程序,并使用了CRecordset类。但是,当我运行该程序时,它试图要访问数据库,并给出“Internal Application Error”对话框。我应该怎样做?
通 常 情 况 下,当 你 的 程 序 中 向 数 据 库 发 送 信 息 的 SQL 语 句 出 现 问 题 时 才 出 现 该 对 话 框。例 如,参 见 下 面 的 例 子:
set.m_strFilter = "(ZipCode = '27111')";
如 果 ZipCode 列 被 定 义 为 字 符 串 时 不 会 出 现 问 题,如 果 定 义 为 long,则 会 出 现“Internal Application Error”对 话 框,这 是 由 于 类 型 不 匹 配 的 缘 故。如 果 你 删 除 27111 的 单 引 号,则 不 会 出 现 问 题。当 你 看 到“Internal Application Error”时,最 好 检 查 一 下 试 图 要 发 送 给 数 据 库 的 SQL 语 句。
(97) 我用ClassWizard建立了一个类。但是,我把名字取错了,我想把它从项目中删除,应该如何做?
在 ClassWizard 对 话 框 关 闭 后,用 文 件 管 理 器 删 除 新 类 的 H 和 CPP 文 件。然 后 打 开 ClassWizard,它 会 提 示 丢 失 了 两 个 文 件,并 询 问 你 该 如 何 做。你 可 以 选 择 从 项 目 中 删 除 这 两 个 问 的 按 钮。
(98) 当我打开应用程序中的窗口时,我要传递该窗口的矩形尺寸。该矩形指定了窗口的外围大小,但是当我调用GetClientRect时,所得到的尺寸要比所希望的值要小(因为工具栏和窗口边框的缘故)。有其它方法来计算窗口的尺寸吗?
参 见 CWnd::CalcWindowRect。
(99) 我在文档类中设置了一个整型变量。但是,当我试图把该变量写入Serialize函数中的archive文件中时,出现了类型错误。而文档中的其它变量没有问题。为什么?
archive 类 只 重 载
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -