现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

vc常用技巧总结(5)

2012-08-02 14:18 工业·编程 ⁄ 共 7320字 ⁄ 字号 暂无评论

(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 类 只 重 载 某 些 类 型 的 >> 和 << 操 作 符。“int”类 型 没 有 在 其 中,也 许 是 因 为 int 变 量 在 Windows 3.1 与 Windows NT/95 有 所 不 同 的 缘 故 吧。“long”类 型 得 到 了 支 持,所 以 你 可 以 把 int 类 型 改 成 long 型。参 见 MFC 帮 助 文 件 中 CArchive 类。
(100) 如何控制菜单的大小?
我用MFC的CMenu生成了一个动态菜单(例如File,Edit,View...Help), 我想控制这个菜单的大小(长+高).
方法一:查找 WM_MEASUREITEM 和 MEASUREITEMSTRUCT.
方法二:查询系统::GetSystemMetric(SM_CXMENUSIZE).
/* 你可以通过如下代码来获得文本的大小:
(A)获得被使用的字体 */
NONCLIENTMETRICS ncm;
HFONT hFontMenu;
SIZE size;
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) 获得菜单项的文本: */
char szText[_MAX_PATH];
pMenu->GetMenuString(0, szText, _MAX_PATH, MF_BYPOSITION);
/*
然后,获得菜单项文本的高度: */
HFONT hFontOld;
HDC hDC;
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) Tip of the day的bug
我创建了一个简单的mdi应用程序,使用.BSF(自定义的文档扩展名)作为它的文档我保存一个foo.bsf文档后,可以在资源管理器中双击该文件打开 mdi应用程序同时打开foo.bsf文档.但当我给mdi应用程序加上a tip of the day组件之后,从资源管理器中双击foo.bsf后,就会给我一个警告:ASSERT(::IsWindow(m_hWnd)),然后mdi应用程序就 死那了.
当从dde启动应用程序(例如:双击相关文档)时,"Tip of the Day"是有bug的.你可以看看函数"ShowTipAtStartup",它在"InitInstance"中调用,可以看到tip of the day作为一个模式对话框显示,在处理其它消息时它一直进行消息循环你可心修改ShowTipAtStartup使其从dde启动时不出现tip of the day.
void CTipOfApp::ShowTipAtStartup(void)
{
// CG: This function added by 'Tip of the Day' component.
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
if (
cmdInfo.m_bShowSplash &&
cmdInfo.m_nShellCommand != CCommandLineInf:FileDDE
)
{
CTipDlg dlg;
if (dlg.m_bStartup)
dlg.DoModal();
}
}
如果还有其它bug,你可以设定cmdInfo.m_nShellCommand的过滤.
(105) 如何可以让我的程序可以显示在其它的窗口上面?
让用户选择"总是在最上面"最好是在系统菜单里加入一个选项.可以通过修改WM_SYSCOMMAND消息来发送用户的选择.菜单的命令标识(id)会作为一个参数传给OnSysCommand().要定义标识(id),将如下代码加入到CMainFrame.CPP中:
#define WM_ALWAYSONTOP WM_USER + 1
将"总在最上面"的菜单项加入到系统菜单中,将如下代码加入到函数CMainFrame::OnCreate()中:
CMenu* pSysMenu = GetSystemMenu(FALSE);
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, WM_ALWAYSONTOP,
"&Always On Top");
使用ClassWizard,加入对WM_SYSCOMMAND消息的处理,你应该改变消息过滤器,使用系统可以处理这个消息.
void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
{
switch ( nID )
{
case WM_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设置了整个窗口类的限制,因此记住要考虑工具条,卷动条等等的大小.
// 最大最小尺寸的象素点 - 示例
#define MINX 200
#define MINY 300
#define MAXX 300
#define MAXY 400
void CMyFrameWnd::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
CRect rectWindow;
GetWindowRect(&rectWindow);
CRect rectClient;
GetClientRect(&rectClient);
// get offset of toolbars, scrollbars, etc.
int nWidthOffset = rectWindow.Width() - rectClient.Width();
int nHeightOffset = rectWindow.Height() - rectClient.Height();
lpMMI->ptMinTrackSize.x = MINX + nWidthOffset;
lpMMI->ptMinTrackSize.y = MINY + nHeightOffset;
lpMMI->ptMaxTrackSize.x = MAXX + nWidthOffset;
lpMMI->ptMaxTrackSize.y = MAXY + nHeightOffset;
}
第二步,在CFrameWnd的继承类的PreCreateWindow函数中去掉WS_MAXIMIZEBOX消息,否则在最大化时你将得不到预料的结果.
BOOL CMyFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style &= ~WS_MAXIMIZEBOX;
return CFrameWnd::PreCreateWindow(cs);
}
(107) 如何改变窗口框架的颜色?
MDI框架的客户区被另一个窗口的框架所覆盖.为了改变客户区的背景色,你需要重画这个客户窗口.为了做到这点,你要处理消息WM_ERASEBKND产生一个新类,从CWnd继承,姑且称之为CMDIClient.给它加上一个成员变量,
#include "MDIClient.h"
class CMainFrame : public CMDIFrameWnd
{
...
protected:
CMDIClient m_wndMDIClient;
}
在CMainFrame中重载CMDIFrameWnd::OnCreateClient
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
if ( CMDIFrameWnd::OnCreateClient(lpcs, pContext) )
{
m_wndMDIClient.SubclassWindow(m_hWndMDIClient);
return TRUE;
}
else
return FALSE;
}
然后就可以加入对消息WM_ERASEBKGND的处理了.
(108) 如何将应用程序窗口置于屏幕正中?
要将你的应用程序窗口放置在屏幕正中央,只须在MainFrame的OnCreate函数中加入:
CenterWindow( GetDesktopWindow() );

给我留言

留言无头像?