




文档简介
MFC学习总结 67 个技巧 1 属性页的添加 创建对话框的类 该类要从 CpropertyPage 继承 然后在要添加该对话框为属性 页的类 头文件 里创建 CpropertySheet 类的一 个对象 m tabsheet 和新创建的 对话框类的对象 m skatch 最后 在 cpp 文件里的 OnInitDialog 之类的函数 里实现如下代 码 m tabsheet Create this WS CHILD WS VISIBLE 0 使选项卡的按钮在下面 if m tabsheet m hWnd m tabsheet ShowWindow SW MAXIMIZE 显示选项卡 加入标签 标签名由各个子对话框的标题栏决定 m tabsheet AddPage 用 Create 来创建一个属性页 m tabsheet Create this WS CHILD WS VISIBLE WS EX CONTROLPARENT RECT rect m tabsheet GetWindowRect int width rect right rect left int height rect bottom rect top 调整属性页的大小和位置 m tabsheet SetWindowPos NULL 225 225 width 82 height SWP NOACTIVATE 属性页的添加完成 如果要添加多个属性页 则只需要增加多个对象 如下 m tabsheet AddPage strname 0 Screen Name strname 1 Form ID strname 2 Category Path for int i 0 i 3 i m List InsertColumn i strname i LVCFMT LEFT 130 在这之前也要将 List Control 的 ID 与 ClistCtrl 的对象 m list 在 DoDataExchange CDataExchange pDX 函数里绑定 如下 DDX Control pDX IDC LIST m List 3 ToolBar 和 StatusBar 中控件的添加 方法 只能在 ToolBar 里创建控件 首先 在 ToolBar 中创建一个 Button 其 ID 为 ID TOOL COMBO 我们要将创建的控件放在该 Button 的位置上 其 次 新创建一个类 CMainToolBar 要从 CToolBar 继承 创建过程大概如下 选择工程 增加到工程 新的类 也可以选择工程的根 然后点击 右键 选择新 的类 或者 CTL W 选择增加类 新的类 然后在 class type 里选择 Generic Class 在 Name 栏里输入新类的名字 Base class 里输入 CToolBar 创建成功 后在该类里创建要增加的控件的对象 如 CComboBox m wndMyCombo CStatic m wndCategory m wndCategoryPath CButton m wndOpenButton Cedit m wndEdit 然后在构造函数里初始化如 m wndMyCombo m hWnd NULL m wndCategory m hWnd NULL m wndCategoryPath m hWnd NULL m wndOpenButton m hWnd NULL m wndEdit m hWnd NULL 接着在 CMainframe 的头文件里创建 CMainToolBar 的一个对象 m wndToolBar 最后在 cpp 文件的 OnCreate 函数的最后实现如下 int index 0 CRect rect 可定义在头文件当中 ComboBox 找到指定的工具项 while m wndToolBar GetItemID index ID TOOL COMBO index 设置指定工具项的宽度并获取新的区域 120 是宽度 m wndToolBar SetButtonInfo index ID TOOL COMBO TBBS SEPARATOR 120 m wndToolBar GetItemRect index 设置位置 rect top 1 rect bottom 200 创建并显示控件 if m wndToolBar m wndMyCombo Create WS CHILD WS VISIBLE CBS AUTOHSCROLL CBS DROPDOWNLIST CBS HASSTRINGS rect return FALSE m wndToolBar m wndMyCombo ShowWindow SW SHOW 填充内容 m wndToolBar m wndMyCombo AddString 25 m wndToolBar m wndMyCombo AddString 50 m wndToolBar m wndMyCombo AddString 75 选择默认项 m wndToolBar m wndMyCombo SetCurSel 0 获取到内容并 MSGBOX 显示出来 CString strContent m wndToolBar m wndMyCombo GetWindowText strContent index 0 其他控件都类似创建 只需要注意一下各自的 Create 函数的参数即可 方法 这种方法 创建不太容易控制 直接在 CMainframe 的头文件中创建要增 加的控件的对象 如 CButton 的对象 m wndAboutButton 然后创建 CToolBar 或者 CstatusBar 的对象 如 CstatusBar 的对象 wndStatusBar 再增加几个 函数如下 Protected virtual void RecalcLayout BOOL bNotify TRUE afx msg void CMainFrame OnViewStatusBar 接着在 cpp 文件中将 StatusBar 的 ID 和 OnViewStatusBar 函数绑定在一起 如 下所示 BEGIN MESSAGE MAP CMainFrame CFrameWnd AFX MSG MAP CMainFrame ON COMMAND ID VIEW STATUS BAR OnViewStatusBar ON WM CREATE AFX MSG MAP END MESSAGE MAP 然后 Create 函数的最后 返回值之前 实现如下代码 CRect rc VERIFY m wndAboutButton Create T MyAbout WS VISIBLE rc this ID APP ABOUT TODO Remove this if you don t want tool tips or a resizeable toolbar m wndToolBar SetBarStyle m wndToolBar GetBarStyle CBRS TOOLTIPS CBRS FLYBY CBRS SIZE DYNAMIC 再在 RecalcLayout 函数里实现 CRect rc if m wndStatusBar m hWnd m wndStatusBar GetWindowRect ScreenToClient rc right 50 m wndStatusBar SetWindowPos NULL rc left rc top rc Width rc Heigh t SWP NOZORDER rc left rc right rc right 50 m wndAboutButton SetWindowPos NULL rc left rc top rc Width rc Hei ght SWP NOZORDER 最后在 OnViewStatusBar 里实现 BOOL bShow m wndStatusBar GetStyle m wndAboutButton SetWindowPos NULL 0 0 0 0 SWP NOZORDER SWP NOMOVE SWP NOSIZE SWP NOACTIVATE bShow SWP SHOWWINDOW SWP HIDEWINDOW ToolBar 中的创建与此相同 只需更改一下句柄即可 4 通过 Control 创建的控件 对其属性的动态控制 在对话框类的头文件里创建所要改变属性的控件的对象 如要改变一个 Button 其 ID 为 IDC MyButton 的属性 则需创建 Cbutton 的对象 m button 然后在 cpp 中的 DoDataExchange 函数里将 Button 的 ID 和创建的对象绑定在一 起 AFX DATA MAP CPrintDlg NOTE the ClassWizard will add DDX and DDV calls here DDX Control pDX IDC MyButton m button AFX DATA MAP 然后可以在该函数的最后进行初始化 m button EnableWindow FALSE 到这里已经实现了改变属性 如果要动态改变其属性 可如下实现 通过两个 Button 的点击改变起属性 RadioAll Button 的点击响应函数 void CPrintDlg OnRadioAll TODO Add your control notification handler code here m button EnableWindow TRUE RadioSelect Button 的点击响应函数 void CPrintDlg OnRadioSelect TODO Add your control notification handler code here m button EnableWindow FALSE 也可以通过一个 Check Button 的点击来改变 在其点击响应函数里实现 m button EnableWindow m button IsWindowEnabled 其余控件属性的改变都如此 5 窗口的分割与停靠 一 新建一个类 CMySplitter 基类为 CSplitterWnd 二 重载该类的 OnMouseMove 函数 void CMySplitter OnMouseMove UINT nFlags CPoint point 限制切分条的运动范围 if point x600 CWnd OnMouseMove nFlags point else CSplitterWnd OnMouseMove nFlags point 三 然后就可以跟一般的窗口分割那样去做了 if point x600 这里的范围可以随你去设置了 够简单吧 四 切分窗口 在 MaiFram h 建立切分条对象 protected CMySplitter m wndSplitter 切分窗口对象 在 MaiFram cpp 中实现窗口切分 BOOL CMainFrame OnCreateClient LPCREATESTRUCT lpcs CCreateContext pContext 创建拆分器窗口 if m wndSplitter CreateStatic this 1 2 return FALSE if m wndSplitter CreateView 0 0 RUNTIME CLASS CLeftView CSize 228 100 pContext m wndSplitter CreateView 0 1 RUNTIME CLASS CDataEditView CSize 100 100 pContext m wndSplitter DestroyWindow return FALSE return TRUE 6 怎样在程序开始的时候让它最大化 vc 做出来的 exe 文件在窗体的右上方是没有最大化和最小化按钮的 怎样实 现这一功能 如何在显示窗口时 使最大化按钮变灰 在 App 类里的 C App InitInstance 中把 m pMainWnd ShowWindow SW SHOW 改成 m pMainWnd ShowWindow SW MAXIMIZE 在 CreateWidnow 时用 WS SYSMENU WS MINIMIZEBOX WS MAXIMIZEBOX 风格 第一种方法 BOOL CMainFrame PreCreateWindow CREATESTRUCT TODO Modify the Window class or styles here by modifying the CREATESTRUCT cs disable the maxmini box cs style return TRUE 第二种方法 CMenu pMenu AfxGetApp m pMainWnd GetSystemMenu FALSE int x pMenu GetMenuItemCount UINT pID pMenu GetMenuItemID x 1 pMenu EnableMenuItem pID MF DISABLED 第三种方法 ModifyStyle WS MAXIMIZEBOX 0 这个函数也可以是最大化按钮失效 并且可以在程序中动态的改变窗口的风格 7 更改属性页标题 void CProSheet SetPageTitle int nPage int nImage CString strTitle TC ITEM item item mask TCIF TEXT TCIF IMAGE 设置图标 文字 item mask TCIF IMAGE 只设置图标 item iImage nImage item pszText strTitle GetBuffer 0 设置文字 GetTabControl SetItem nPage 要设置文字时就将上面 2 行有注释符的代码前的注释符去掉 8 创建动态菜单 void CMainFrame OnSelectState NMTOOLBAR pnmtb LRESULT plr CMenu menu if menu CreateMenu return menu AppendMenu MF STRING 0 开始 menu AppendMenu MF STRING 0 结束 CRect rc m wndToolBar SendMessage TB GETRECT pnmtb iItem LPARAM m wndToolBar ClientToScreen menu TrackMenu TPM LEFTALIGN TPM LEFTBUTTON TPM VERTICAL rc left rc bottom this menu DestroyMenu menu detach 9 关于打印 1 要打印哪个视就 CMainFrame AfxGetMainWnd m wndSplitter SetActivePane 要打印的那个视对应的 Pane 2 有一个单文档工程 文档窗口被切分 左视图由 CTreeView 的派生类管理 右视图由 CListView 的派生类 CMyListView 其为风格为 LVS REPORT 管理 我 想为右视图添加打印和打印预览 我在 MyListView cpp 中添加了 ON COMMAND ID FILE PRINT CListView OnFilePrint ON COMMAND ID FILE PRINT PREVIEW CListView OnFilePrintPreview 还 有 BOOL CMyListView OnPreparePrinting CPrintInfo pInfo TODO call DoPreparePrinting to invoke the Print dialog box return CListView OnPreparePrinting pInfo pInfo SetMaxPage 2 BOOL bret DoPreparePrinting pInfo pInfo m nNumPreviewPages 2 return bret 3 下面是从 MSDN 中摘出来的一段 是用来改变消息路由的 用了这段代码之后 CView 中的消息 菜单 控件 子窗口 将先被 CMyShape 类来处理 不知道你 要的是不是这样的效果 This example illustrates extending the framework s standard command route from the view to objects managed by the view This example is from an object oriented drawing application similar to the DRAWCLI sample application which draws and edits shapes BOOL CMyView OnCmdMsg UINT nID int nCode void pExtra AFX CMDHANDLERINFO pHandlerInfo Extend the framework s command route from the view to the application specific CMyShape that is currently selected in the view m pActiveShape is NULL if no shape object is currently selected in the view if m pActiveShape NULL If the object s in the extended command route don t handle the command then let the base class OnCmdMsg handle it return CView OnCmdMsg nID nCode pExtra pHandlerInfo The command handler for ID SHAPE COLOR menu command to change the color of the currently selected shape was added to the message map of CMyShape note not CMyView using ClassWizard The menu item will be automatically enabled or disabled depending on whether a CMyShape is currently selected in the view that is depending on whether CMyView m pActiveView is NULL It is not necessary to implement an ON UPDATE COMMAND UI handler to enable or disable the menu item BEGIN MESSAGE MAP CMyShape CCmdTarget AFX MSG MAP CMyShape ON COMMAND ID SHAPE COLOR OnShapeColor AFX MSG MAP END MESSAGE MAP 如果你只是想调用 OnFilePrint 函数 可以试一试下面的代码 就和调用其 它类中的函数一样 CMDIFrameWnd pFrame CMDIFrameWnd AfxGetApp m pMainWnd Get the active MDI child window CMDIChildWnd pChild CMDIChildWnd pFrame GetActiveFrame or CMDIChildWnd pChild pFrame MDIGetActive Get the active view attached to the active MDI child window CMyView pView CMyView pChild GetActiveView pView OnFilePrint 4 void CMyReportView OnFileOpen char Filter Crystal Report files rpt rpt All files CRect rect CFileDialog OpenDlg TRUE 0 0 OFN HIDEREADONLY OFN FILEMUSTEXIST LPCTSTR Filter N ULL if OpenDlg DoModal IDOK 显示文件对话框 return CString m fName OpenDlg GetPathName 取得文件名 if m CrystalReport m CrystalReport DestroyWindow GetClientRect rect 创建控件 if m CrystalReport Create AfxRegisterWndClass 0 AfxGetApp LoadStandardCursor IDC ARROW WS CHILD WS VISIBLE rect this IDC CRYSTALREPORT1 AfxMessageBox 控件创建失败 return m CrystalReport SetWindowParentHandle long this m hWnd 设置父 窗口 m CrystalReport SetWindowBorderStyle 0 设置为没有边框 m CrystalReport SetWindowLeft 0 左空间 m CrystalReport SetWindowTop 0 顶部空间 m CrystalReport SetWindowControls FALSE 不显示工具条 m CrystalReport SetReportFileName m fName 设置报表文件 m CrystalReport SetWindowWidth rect Width 设置窗口宽度 m CrystalReport SetWindowHeight rect Height 设置窗口高度 m CrystalReport SetFormulas 0 Company VC 知识库 将报表中的 Company 变量的值设置为 VC 知识库 m CrystalReport SetDestination 0 设置输出对象是屏幕 m CrystalReport PrintReport 显示报表 void CMyReportView OnFilePrint if m CrystalReport 设置输出对象是打印机 m CrystalReport PrintReport 打印 10 Scroll 创建一个基于 CScrollview 的 SDI Project 在第 6 步中选 CScrollview 若你已创建了 这步可以省略 然后 改为如 void CTestView OnInitialUpdate CScrollView OnInitialUpdate CSize sizeTotal TODO calculate the total size of this view sizeTotal cx 1024 改这两个 sizeTotal cy 768 SetScrollSizes MM TEXT sizeTotal 11 修改主窗口风格 AppWizard 生成的应用程序框架的主窗口具有缺省的窗口风格 比如在窗口标题 条中自动添加文档名 窗口是叠加型的 可改变窗口大小等 要修改 窗口的缺 省风格 需要重载 CWnd PreCreateWindow CREATESTRUCT 创建窗口的基本参数 HANDLE hInstance 拥有将创建的窗口的模块实例句柄 HMENU hMenu 新窗口的菜单句柄 HWND hwndParent 新窗口的父窗口句柄 int cy 新窗口的高度 int cx 新窗口的宽度 int y 新窗口的左上角 Y 坐标 int x 新窗口的左上角 X 坐标 LONG style 新窗口的风格 LPCSTR lpszName 新窗口的名称 LPCSTR lpszClass 新窗口的窗口类名 DWORD dwExStyle 新窗口的扩展参数 CREATESTRUCT CREATESTRUCT 结构的 style 域定义了窗口的风格 比如 缺省的 MDI 主窗口的 风格中就包括 FWS ADDTOTITLE 在标题条中 显示当前的工作文档名 FWS PREFIXTITLE 把文档名放在程序标题的前面 WS THICKFRAME 窗口具有 可缩放的边框 等风格 由于多种风格参数由逻辑或 组合在一起的 因此添加某种风格 就只需用 把对应的参数加到 CREATESTRUCT 结构的 style 域中 删 除已有的风格 则需用 去除标题条中的文档名 cs style 去除可改变大小的边框 cs style WS DLGFRAME 增加不能改变大小的边框 确定主窗的大小和初始位置 int cxScreen GetSystemMetrics SM CXSCREEN 获得屏幕宽 int cyScreen GetSystemMetrics SM CYSCREEN 获得屏幕高 cs x 0 主窗位于左上角 cs y 0 cs cx cxScreen 2 主窗宽为 1 2 屏幕宽 cs cy cxScreen 2 主窗高为 1 2 屏幕高 return CMDIFrameWnd PreCreateWindow cs 12 控制滚动条 BOOL CDiagramShowView PreTranslateMessage MSG pMsg CFileTreeDoc pDoc CFileTreeDoc GetDocument CPoint point GetScrollPosition if pMsg message WM KEYDOWN switch pMsg wParam case VK LEFT if point x 10 EndPoint x EndPoint x 10 EndPoint y EndPoint y else EndPoint x 0 EndPoint y EndPoint y ScrollToPosition EndPoint InvalidateRect NULL TRUE break case VK RIGHT if point x intDiagramColumnCount pDoc intColumnWidth 10 EndPoint x EndPoint x 10 EndPoint y EndPoint y else EndPoint y pDoc intDiagramColumnCount pDoc intColumnWidth EndPoint x EndPoint x ScrollToPosition EndPoint InvalidateRect NULL TRUE break case VK UP if point y 10 EndPoint y EndPoint y 10 EndPoint x EndPoint x else EndPoint y 0 EndPoint x EndPoint x ScrollToPosition EndPoint InvalidateRect NULL TRUE break case VK DOWN if point y intDiagramRowCount pDoc intRowHeight 10 EndPoint y EndPoint y 10 EndPoint x EndPoint x else EndPoint y pDoc intDiagramRowCount pDoc intRowHeight EndPoint x EndPoint x ScrollToPosition EndPoint InvalidateRect NULL TRUE break default break return FALSE 通过正负号判断是向上还是向下滚动 if zDelta 120 向上滚动 if zDelta 120 向下滚动 BOOL CDiagramShowView OnMouseWheel UINT nFlags short zDelta CPoint pt CFileTreeDoc pDoc CFileTreeDoc GetDocument CPoint point GetScrollPosition if zDelta 120 if point y 20 EndPoint x point x EndPoint y point y EndPoint x EndPoint x EndPoint y EndPoint y 20 else EndPoint x EndPoint x EndPoint y 0 if zDelta 120 if point y intDiagramRowCount pDoc intRowHeight 20 EndPoint x point x EndPoint y point y EndPoint x EndPoint x EndPoint y EndPoint y 20 else EndPoint x EndPoint x EndPoint y EndPoint y ScrollToPosition EndPoint InvalidateRect NULL TRUE return CScrollView OnMouseWheel nFlags zDelta pt 13 属性页处理通知消息 CPropertyPageImpl 有一个消息映射处理 WM NOTIFY 如果通知代码是 PSN 的 值 OnNotify 就会调用相应的通知处理函数 这使用了编译阶段虚函数机制 从而使得派生类可以很容易的重载这些处理函数 由于 WTL 3 和 WTL 7 设计的改变 从而存在两套不同的通知处理机制 在 WTL 3 中通知处理函数返回的值与 PSN 消息的返回值不同 例如 WTL 3 是这样处理 PSN WIZFINISH 的 case PSN WIZFINISH lResult pT OnWizardFinish break OnWizardFinish 期望返回 TRUE 结束向导 FALSE 阻止关闭向导 这个方法很 简陋 但是 IE5 的通用控件对 PSN WIZFINISH 处理的返回值添加了新解释 他返 回需要获得焦点的窗口的句柄 WTL 3 的程序将不能使用这个特性 因为它对所 有非 0 的返回值都做相同的处理 在 WTL 7 中 OnNotify 没有改变 PSN 消息的返回值 处理函数返回任何文 档中规定的合法数值和正确的行为 当然 为了向前兼容 WTL 3 仍然使用当前 默认的工作方式 要使用 WTL 7 的消息处理方式 你必须在中 including atldlgs h 一行之前添加一行定义 define WTL NEW PAGE NOTIFY HANDLERS 编写新的代码没有理由不使用 WTL 7 的消息处理函数 所以这里就不介绍 WTL 3 的消息处理方式 CPropertyPageImpl 为所有消息提供了默认的通知消息处理函数 你可以重载与 你的程序有关的消息处理函数完成特殊的操作 默认的消息处理函数和相应的行 为如下 int OnSetActive 允许页面成为激活状态 BOOL OnKillActive 允许页面成为非激活状态 int OnApply 返回 PSNRET NOERROR 表示应用操作成功完成 void OnReset 无相应的动作 BOOL OnQueryCancel 允许取消操作 int OnWizardBack 返回到前一个页面 int OnWizardNext 进行到下一个页面 INT PTR OnWizardFinish 允许向导结束 void OnHelp 无相应的动作 BOOL OnGetObject LPNMOBJECTNOTIFY lpObjectNotify 无相应的动作 int OnTranslateAccelerator LPMSG lpMsg 返回 PSNRET NOERROR 表示消息 没有被处理 HWND OnQueryInitialFocus HWND hWndFocus 返回 NULL 表示将按 Tab Order 顺序的第一个控件设为焦点状态 14 使工具条上的按钮点击一次为按下 再点击才弹起 bCheck m RtfEditToolBar GetToolBarCtrl IsButtonChecked ID TB BOLD m RtfEditToolBar GetToolBarCtrl CheckButton ID TB BOLD bCheck 15 VC 中基于 Windows 的精确定时 在工业生产控制系统中 有许多需要定时完成的操作 如定时显示当前时间 定 时刷新屏幕上的进度条 上位 机定时向下位机发送命令和传送数据等 特别是 在对控制性能要求较高的实时控制系统和数据采集系统中 就更需要精确定时操 作 众所周知 Windows 是基于消息机制的系统 任何事件的执行都是通过发 送和接收消息来完成的 这样就带来了一些问题 如一旦计算机的 CPU 被某个 进程占用 或系统资源紧张时 发送到消息队列 中的消息就暂时被挂起 得不 到实时处理 因此 不能简单地通过 Windows 消息引发一个对定时要求 严格的 事件 另外 由于在 Windows 中已经封装了计算机底层硬件的访问 所以 要想 通过直接利用 访问硬件来完成精确定时 也比较困难 所以在实际应用时 应 针对具体定时精度的要求 采取相适 应的定时方法 VC 中提供了很多关于时间操作的函数 利用它们控制程序能够精确地完成 定时和计时操作 本文详细介绍了 VC 中基于 Windows 的精确定时的七种方式 方式一 VC 中的 WM TIMER 消息映射能进行简单的时间控制 首先调用函 数 SetTimer 设置定时 间隔 如 SetTimer 0 200 NULL 即为设置 200ms 的时间 间隔 然后在应用程序中增加定时响应函数 OnTimer 并在该函数中添加响应 的处理语句 用来完成到达定时时间的操作 这种定时方法非常 简单 可以实 现一定的定时功能 但其定时功能如同 Sleep 函数的延时功能一样 精度非常 低 最小 计时精度仅为 30ms CPU 占用低 且定时器消息在多任务操作系统中 的优先级很低 不能得到及时响 应 往往不能满足实时控制环境下的应用 只 可以用来实现诸如位图的动态显示等对定时精度要求不高的情况 如示例工程中 的 Timer1 方 式二 VC 中使用 sleep 函数实现延时 它的单位是 ms 如延时 2 秒 用 sleep 2000 精度非常 低 最小计时精度仅为 30ms 用 sleep 函数的不利 处在于延时期间不能处理其他的消息 如果时间太 长 就好象死机一样 CPU 占用率非常高 只能用于要求不高的延时程序中 如示例工程中的 Timer2 方式三 利用 COleDateTime 类和 COleDateTimeSpan 类结合 WINDOWS 的消息 处理过程来实现秒级延时 如示例工程中的 Timer3 和 Timer3 1 以下是实现 2 秒的延时代码 COleDateTime start time COleDateTime GetCurrentTime COleDateTimeSpan end time COleDateTime GetCurrentTime start time while end time GetTotalSeconds 2 实现延时 2 秒 MSG msg GetMessage TranslateMessage DispatchMessage 以上四行是实现在延时或定时期间能处理其他的消息 虽然这样可以降低 CPU 的占有率 但降低了延时或定时精度 实际应用中可以去掉 end time COleDateTime GetCurrentTime start time 这样在延时的时候我们也能够处理其他的消息 方式四 在精度要求较高的情况下 VC 中可以利用 GetTickCount 函数 该函数的返回值是 DWORD 型 表示以 ms 为单位的计算机启动后 经历的时间间 隔 精度比 WM TIMER 消息映射高 在较 短的定时中其计时误差为 15ms 在较 长的定时中其计时误差较低 如果定时时间太长 就好象死机一样 CPU 占用率 非常高 只能用于要求不高的延时程序 中 如示例工程中的 Timer4和 Timer4 1 下列代码可以实现 50ms 的精确定时 DWORD dwStart GetTickCount DWORD dwEnd dwStart do dwEnd GetTickCount dwStart while dwEnd 50 为使 GetTickCount 函数在延时或定时期间能处理其他的消息 可以把代码改 为 DWORD dwStart GetTickCount DWORD dwEnd dwStart do MSG msg GetMessage TranslateMessage DispatchMessage dwEnd GetTickCount dwStart while dwEnd 50 虽然这样可以降低 CPU 的占有率 并在延时或定时期间也能处理其他的消息 但 降低了延时或定时精度 方式五 与 GetTickCount 函数类似的多媒体定时器函数 DWORD timeGetTime void 该函数定时精 度为 ms 级 返回从 Windows 启动开始经过 的毫秒数 微软公司在其多媒体 Windows 中提供了精确定时器的底 层 API 持 利用多媒体定时器可以很精确地读出系统的当前时间 并且能在非常精确的时间 间隔内完成一 个事件 函数或过程的调用 不同之处在于调用 DWORD timeGetTime void 函数之前必须将 Winmm lib 和 Mmsystem h 添加到工程 中 否则在编译时提示 DWORD timeGetTime void 函数未定义 由于使用该 函 数是通过查询的方式进行定时控制的 所以 应该建立定时循环来进行定时事件 的控制 如示例工程中的 Timer5 和 Timer5 1 方式六 使用多媒体定时器 timeSetEvent 函数 该函数定时精度为 ms 级 利用该函数可以实现周期性的函数调用 如示例工程中的 Timer6 和 Timer6 1 函数的原型如下 MMRESULT timeSetEvent UINT uDelay UINT uResolution LPTIMECALLBACK lpTimeProc WORD dwUser UINT fuEvent 该函数设置一个定时回调事件 此事件可以是一个一次性事件或周期性事 件 事件一旦被激活 便调用指定的回调函数 成功后返回事件的标识符代码 否则返回 NULL 函数的参数说明如下 uDelay 以毫秒指定事件的周期 Uresolution 以毫秒指定延时的精度 数值越小定时器事件分辨率越高 缺省值为 1ms LpTimeProc 指向一个回调函数 DwUser 存放用户提供的回调数据 FuEvent 指定定时器事件类型 TIME ONESHOT uDelay 毫秒后只产生一次事件 TIME PERIODIC 每隔 uDelay 毫秒周期性地产生事件 具体应用时 可以通过调用 timeSetEvent 函数 将需要周期性执行的任 务定义在 LpTimeProc 回调函数 中 如 定时采样 控制等 从而完成所需处理 的事件 需要注意的是 任务处理的时间不能大于周期间隔时间 另外 在定时 器使用完毕后 应及时调用 timeKillEvent 将之释放 方式七 对于精确度要求更高的定时操作 则应该使用 QueryPerformanceFrequency 和 QueryPerformanceCounter 函数 这两个函 数是 VC 提供的仅供 Windows 95 及其后续版本使用的精确时间函数 并要求计算 机从硬件上支持精确定时器 如示例工程中的 Timer7 Timer7 1 Timer7 2 Timer7 3 QueryPerformanceFrequency 函数和 QueryPerformanceCounter 函数的原型 如下 BOOL QueryPerformanceFrequency LARGE INTEGER lpFrequency BOOL QueryPerformanceCounter LARGE INTEGER lpCount 数据类型 ARGE INTEGER 既可以是一个 8 字节长的整型数 也可以是两个 4 字节长的整型数的联合结构 其具体用法根据编译器是否支持 64 位而定 该类 型的定义如下 typedef union LARGE INTEGER struct DWORD LowPart 4 字节整型数 LONG HighPart 4 字节整型数 LONGLONG QuadPart 8 字节整型数 LARGE INTEGER 在进行定时之前 先调用 QueryPerformanceFrequency 函数获得机器内 部定时器的时钟频率 然后在需要严格定时的事件发生之前和发生之后分别调 用 QueryPerformanceCounter 函数 利用两次获得的计数之差及时钟频率 计 算 出事件经 历的精确时间 下列代码实现 1ms 的精确定时 LARGE INTEGER litmp LONGLONG QPart1 QPart2 double dfMinus dfFreq dfTim QueryPerformanceFrequency dfFreq double litmp QuadPart 获得计数器的时钟频率 QueryPerformanceCounter QPart1 litmp QuadPart 获得初始值 do QueryPerformanceCounter QPart2 litmp QuadPart 获得中止值 dfMinus double QPart2 QPart1 dfTim dfMinus dfFr
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 摄影色彩基础知识培训课件
- 摄影后期初期课件
- 期货技术考试试题及答案
- 2025合同终止劳动赔偿标准
- 《2025年解除合同协议书范本》
- 2025年物流行业合同法若干关键问题
- 2025设备租赁和维护管理合同协议书
- 公司防洪避险知识培训课件
- 公司金融知识培训大纲课件
- 搬运工培训课件
- 中国信息通信研究院-中国工业互联网发展成效评估报告(2024年)
- DL-T1392-2014直流电源系统绝缘监测装置技术条件
- 彩钢瓦翻新合同范本
- 学情分析案例分析
- 人教版五年级下册音乐影视音乐(作业设计方案)
- 事业单位工作人员调动申报表
- CSR法律法规及其他要求清单(RBA)2024.3
- T-ZJPA 002-2023 注射剂包装密封性检查 微生物挑战:浸入式暴露试验要求
- 语文教师专业发展课件
- 开展绿化知识讲座
- 妇科手术后护理中的术后疼痛管理
评论
0/150
提交评论