自己看的

Dlg -- 对话窗,一个控件。
根据一个对话窗或一个控件的ID, 返回一个指向这个对话窗或控件的对象的指针。


例如,IDC_EDIT1 是 控件的ID
CEdit* pBoxOne;
pBoxOne = (CEdit*) GetDlgItem(IDC_EDIT1);
用 GetDlgItem(IDC_EDIT1); 返回一个指向这个控件的指针, CEdit* ,存入 pBoxOne。


接下来,就可以用它了,例如:
GotoDlgCtrl(pBoxOne);




 VS2008找不到MFC90d.dll错误解决方法
分类: windows学习 2011-09-21 22:26 2705人阅读 评论(1) 收藏 举报
mfcexe工具


问题是在更新嵌入的清单文件时发生的,由于FAT32的原因而未能更新嵌入的清单文件,于是我们有如下两种解决方法:
 
(1)不启用增量链接。在项目的
“属性|配置属性|链接器|常规”中的“启用增量链接”选择“否”。此方法阻断了问题产生的源头,其每次生成exe文件时都直接嵌入清单文件,而不是默认的根据时戳而决定是否更新清单文件。
 
(2)不嵌入清单文件。在项目的“属性|配置属性|清单工具|输入和输出”中的“嵌入清单”选择“否”,从而在生成exe文件时附随生成一个清单文件(默认情况下,其文件名为exe文件的全名加上“.manifest”),避免了嵌入清单文件可能失败的问题。在程序运行时,会用到该清单文件。显然,这种方式使可执行程
序产生了更多的外部依赖,不推荐。

在VC6.0中,我们想利用web broswer组件开发,方法是project->add to project->components and controls,然后找到本机注册的控件,这里以web broswer为例,点击insert后,VC6.0会自动添加组件相关的类.h和.cpp,然后我们就可以利用该类进行开发了。

但在VISTA中,VC6.0在components and controls时,报“不支持该接口”的错误。所以选择VS2005/VS2008。但是在对话框那里,右键,插入Actives控件,选了web broswer后,只会在工具箱加入web broswer,而并不生成组件相关的类,.h和.cpp文件(还有一种方法,就是在工具箱中右键,选择项,然后“COM组件”,点web broswer)。
试验了好久,才终于找到了,如何弄出组件相关类的方法,给大家分享。
首先,将WEB BROSWER放到文本框中,然后对其右键,选择“添加变量”,完成向导,些时就会在你项目文件内添加,例如ocx1.h,ocx1.cpp及类视图COcx1类。

困扰了好久,终于找到了方法,特分享。。。。。。

 

 

 

像我们这样整天对着电脑,也应该注意一下。所以我就来向大家介绍一下怎样将电脑屏幕由刺眼的白色改为淡绿色,让大家在工作的同时,尽可能的将电脑对我们眼睛的伤害降到最低! 


设置方法:打开控制面板中的"显示"选择外观(appearance)-高级(advanced),然后在项目(items)那栏选窗口(windows),再点颜色(color) 


-其它颜色(others),然后把Hue(色调)设为85,Sat(饱和度)设为90,Lum(亮度)设为205。然后单击添加到自定义颜色(Add tocustom colors),按“确定”...一直确定。 


把窗口设成绿色之后,再来把IE的网页背景也变成养眼的绿色吧:打开IE,点击工具(TOOLS),点INTERNET选项(INTERNETOPTIONS),点右下角的辅助功能(Assessibility),然后勾选不使用网页中指定的颜色(ignore colors specified on web pages),然后点“确定”退出。 


OK,现在你就会发现你的屏幕已经变成淡淡的绿色了

 

 

 

VS2008中如何改变对话框的背景颜色

分类: 技术借鉴2011-06-09 07:41 1906人阅读 评论(0) 收藏 举报

parametersfunctiondialoglistapplicationclass

目录(?)[+]

具体步骤:

1,首先为所要改变颜色的对话框类添加WM_CTLCOLOR消息函数。

2,给你的工程中的对话框类添加一个CBrush变量,如:

CBrush   m_bkBrush; //准备一把背景刷子

3,在对话框的初始化函数OnInitDialogreturn   TRUE的前面添加一行代码:

m_bkBrush.CreateSolidBrush(RGB(255,255,0)); //创建一把黄色的背景刷子

4,最后把你原来添加消息函数的代码改成如下:

HBRUSH   CEX06aDialog::OnCtlColor(CDC*   pDC,   CWnd*   pWnd,   UINT   nCtlColor)

{

         HBRUSH   hbr   =   CDialog::OnCtlColor(pDC,   pWnd,   nCtlColor);  

   

         if(nCtlColor==CTLCOLOR_DLG)

//如果是CTLCOLOR_EDIT edit背景色能改变吗?

         {

              return   m_bkBrush; //返回刚才创建的背景刷子

         }

         //TODO:如果默认的不是所需画笔,则返回另一个画笔

         return   hbr;

}

附加:在MSDN中,关于参数nCtlColor,取以下值:

nCtlColor

Contains one of the following values, specifying the typeof control:

·         CTLCOLOR_BTN    Button control

·         CTLCOLOR_DLG    Dialog box

·         CTLCOLOR_EDIT    Edit control

·         CTLCOLOR_LISTBOX    List-box control

·         CTLCOLOR_MSGBOX    Message box

·         CTLCOLOR_SCROLLBAR    Scroll-bar control

·         CTLCOLOR_STATIC    Static control

 

 

 

 

 

在MFC对话框中点击一个按钮显示出另一个对话框

2009-12-03 11:12363117598 | 分类:VC++ | 浏览2402

MFC对话框中点击一个按钮显示出另一个对话框,在弹出的对话框中可以写入信息,并插入数据库

分享到:

2009-12-03 11:29提问者采纳

另一个对话框做为一个类,按钮函数里创建那个类的对象,然后DoModal();

 

另一种:
加载两张位图:IDB_BITMAP1,IDB_BITMAP2
添加一全按钮,IDC_BUTTON1,属性->样式:选上"所有者绘制"和"位图"。
在对话框类中添加成员变量,类型为CBitmapButton,变量名为m_BitmapBtn,全局变量或局部变量均可。

在对话框类的DoDataExchange函数中添加代码,DDX_Control( pDX, IDC_BUTTON1, m_BitmapBtn );

在对话框类的初始化函数中添加代码,m_BitmapBtn.LoadBitmaps(IDB_BITMAP1,IDB_BITMAP2);

 

 

 

 

让对话框全屏显示的方法

OnInitDialog()中加入:

ModifyStyle(WS_CAPTION,0,0);
SendMessage(WM_SYSCOMMAND,SC_MAXIMIZE,0);

如果不想去掉标题栏,第一句就不用了。

 

 

 

1045-1999-8526-0973-1557-2971
1045-1633-7471-9911-3842-1765
1045-1423-6436-0168-7941-1739
1045-1189-6296-3291-6041-1048
1045-1084-6341-6905-7261-7154
1045-1380-6674-5614-0950-9671
1045-1209-6738-4668-7696-2783
1045-1423-6436-0168-7941-1739
1045-1189-6296-3291-6041-1048
1045-1084-6341-6905-7261-7154
1045-1380-6674-5614-0950-9671

 

 

 

 

MFC取得屏幕大小及设置对话框大小

发表于2年前(2012-06-0609:30)   阅读(2732 | 评论(0 1人收藏此文章, 我要收藏

0

MFC之取得屏幕大小,设置对话框大小

 

要取得屏幕大小,可以用下面几个函数:

 

int cx = GetSystemMetrics(SM_CXFULLSCREEN);

 int cy = GetSystemMetrics(SM_CYFULLSCREEN);

 

通过上边两个函数获取的是 显示屏幕的大小,但不包括任务栏等区域

 

 

  int   cx   =   GetSystemMetrics(  SM_CXSCREEN   );   

  int   cy   =   GetSystemMetrics(  SM_CYSCREEN   );

 

这两个函数获取的是真正屏幕的大小。

要设置对话框的大小,可以如下实现:

 

CRect temprect(0,0,640,480); 

CWnd::SetWindowPos(NULL,0,0,temprect.Width(),temprect.Height(),SWP_NOZORDER|SWP_NOMOVE);

 

 

 

 

1.设置对话框大小:

1 CRect   temprect(0,0,1640,1480);

2     CWnd::SetWindowPos(NULL,0,0,temprect.Width(),temprect.Height(),SWP_NOZORDER|SWP_NOMOVE);

2.使对话框全屏显示:

1//得到显示器大小

2int  cx,cy;

3     cx   =  GetSystemMetrics(SM_CXSCREEN);

4     cy   =  GetSystemMetrics(SM_CYSCREEN);

5//再用MoveWindow

6     CRect   rcTemp;

7     rcTemp.BottomRight()   =  CPoint(cx,   cy);

8     rcTemp.TopLeft()   =  CPoint(0,   0);

9     MoveWindow(&rcTemp);  

 

 

 

 

 

 

 

我用代码创建了一个MFC对话框工程,然后自己用代码写一个按钮,(我知道直接拖控件比较方便,但是我想自己用代码写)
我在OnInitDialog函数中写了如下一段代码
CButton m_btnadd;
m_btnadd.Create(_T("Add"),WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(20,20,20,10),
 this,1);
m_btnadd.ShowWindow(SW_SHOW);

但是运行后按钮没有出现,这是为什么,到底该怎么写,我是初学者.

·         mfc gridctrl上的tooltips问题

对我有用[0] 丢个板砖[0] 引用 举报 管理

回复次数:14

 

关注

sha_jinhao

jimette

等级:

3

#1 得分:5回复于: 2013-02-04 09:32:51

CRect(20,20,20,10)

20,left
20 top
20 right
10 bottom

改写 20,20,60,50);

right
bottom需大于lefttop

 

 

关注

fy_zhu93

fy_zhu93

等级:

#2 得分:0回复于: 2013-02-04 09:41:38

引用

CRect(20,20,20,10)

20,left
20 top
20 right
10 bottom

改写 20,20,60,50);

right
bottom需大于lefttop


还是不行啊

CSDN投诉事项说明

对我有用[0] 丢个板砖[0] 引用 举报 管理

 

关注

hdg3707

hdg3707

等级:

#3 得分:5回复于: 2013-02-04 10:13:38

有可能是位置不对或大小不对,默认的坐标系是原点在左上解,因此从左往右X值是增加的,从左上角往下Y的值是负增长的,就是-1,-2...
你先把数据都改大点(除了X,Y两个起始位置),等显示后再调整大小

对我有用[0] 丢个板砖[0] 引用 举报 管理

 

关注

sha_jinhao

jimette

等级:

3

#4 得分:5回复于: 2013-02-04 10:17:53

CButton myButton1, myButton2, myButton3, myButton4;

// Create a push button.
myButton1.Create(_T("My button"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 
   CRect(10,10,100,30), pParentWnd, 1);

对我有用[0] 丢个板砖[0] 引用 举报 管理

 

关注

zhoujielunzhimi

sumos

等级:

#5 得分:5回复于: 2013-02-04 10:23:34

m_btnadd定义为成员变量

对我有用[0] 丢个板砖[0] 引用 举报 管理

 

关注

fy_zhu93

fy_zhu93

等级:

#6 得分:0回复于: 2013-02-04 10:29:52

引用

m_btnadd定义为成员变量


谢谢,原来是这个原因,问题解决啦

对我有用[0] 丢个板砖[0] 引用 举报 管理

 

关注

michael2988

michael2988

等级:

#7 得分:0回复于: 2013-02-04 10:37:57

嗯,生命周期太短,退出该函数后相应按钮类对象销毁了,与其相关的窗口也销毁,所以不会显示

对我有用[0] 丢个板砖[0] 引用 举报 管理

 

关注

rxguoblp

rxguoblp

等级:

#8 得分:0回复于: 2013-02-04 12:29:40

CButton *m_btnadd = new CButton;
m_btnadd->Create(_T("Add"),WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(0,0,20,20),
this,1);
m_btnadd->ShowWindow(SW_SHOW);

也是可以的。

对我有用[0] 丢个板砖[0] 引用 举报 管理

 

关注

fy_zhu93

fy_zhu93

等级:

#9 得分:0回复于: 2013-02-04 13:34:04

引用

CButton *m_btnadd = new CButton;
m_btnadd->Create(_T("Add"),WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(0,0,20,20),
this,1);
m_btnadd->ShowWindow(SW_SHOW);


为什么我用同样的代码想在一个Dialog上写两个按钮,只出现一个按钮呢。求解

对我有用[0] 丢个板砖[0] 引用 举报 管理

 

关注

zgl7903

zgl7903

等级:

#10 得分:0回复于: 2013-02-04 14:22:37

注意按钮的位置和ID 
多个按钮需要多个按钮变量或指针

对我有用[0] 丢个板砖[0] 引用 举报 管理

 

关注

bsnry

bsnry

等级:

#11 得分:0回复于: 2013-02-04 17:16:21

构造函数进行destroywidnow了。

销毁了按钮。

所以不见了。

成员变量指针或则会类成员对象

对我有用[0] 丢个板砖[0] 引用 举报 管理

 

关注

dcmilan

南京短暂的春天

等级:

#12 得分:0回复于: 2013-02-04 18:41:54

析构了,呵呵
要么定义成CButton m_Button
要么定义成CButton m_pButton
然后在构造函数里new一下

对我有用[0] 丢个板砖[0] 引用 举报 管理

 

关注

rxguoblp

rxguoblp

等级:

#13 得分:0回复于: 2013-02-04 20:44:17

引用 9  fy_zhu93 的回复:

引用
CButton *m_btnadd = new CButton;
m_btnadd->Create(_T("Add"),WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(0,0,20,20),
this,1);
m_btnadd->ShowWindow(SW_SHOW);

为什么我用同样的代码想在一个Dialog上写两个按钮,只出现一个按钮呢。求解……

重复创建多个按钮的位置时,需要调整CRect(0,0,20,20)的坐标参数,例如CRect(20,20,30,50),CRect(90,90,100,120),

对我有用[0] 丢个板砖[0] 引用 举报 管理

 

关注

wu_xiao_xian

小新蜡笔

等级:

#14 得分:0回复于: 2013-02-05 08:13:53

对象没声明出来

 

 

 

 

 

 

 

方法一:windows提供了一套函数,用于加载动态链接库中的符号(函数和变量),调用这些函数去加载:
      1. HINSTANCE LoadLibrary(LPCTSTR lpLibFileName);
      2. FARPROC GetProcAddress( HMODULEhModule, LPCWSTR lpProcName);
      3. BOOL FreeLibrary( HMODULEhLibModule);
      这最直观的一种方法,同时也是最麻烦的一种办法。
方法二:让调用者的工程依赖于动态链接库工程。步骤如下:
      1. 让调用者的工程处于active状态下。
      2. 打依赖设置对话框:Project-->dependencies。
      3. 选择动态链接库工程。
      这种方法比较方便,但要求有DLL的项目文件。
方法三:直接把动态链接库产生的.lib文件加入到调用者的工程中。
方法四:进入Link设置:Project-->settings-->Link,选择Categery中的Input,在object/librarymodules里输入的动态链接库对应的.lib文件名,在Additionallibrary path中输入动态链接库对应的.lib的路径。

方法五:#pragma comment(lib, "filename.lib")

 

 

 

 

 

 

 

 

如何用360文件恢复器恢复已删除的文件呢?我们常常在不经意间把文件误删除了。删除之后想找回文件,等到找回的时候发现撤销操作已经无效了。如果文件被删除到回收站里还好,如果直接完全删除了应该怎么办呢?下面来学习一下如何使用360文件恢复来恢复已删除的文件。

首先来介绍下360文件恢复器,360文件恢复器是360安全中心开发的文件恢复工具,目前位于360安全卫士的功能大全里,它可以帮助您快速从硬盘、U盘、SD卡等磁盘设备中恢复被误删除的文件。

 

工具/原料

·        360文件恢复器

步骤/方法

1.     1

首先打开360安全中心,点击功能大全。

点击功能大全

2.     2

然后点击电脑优化栏目下的文件恢复:

3.     3

点击文件恢复后,如果你先前没有下载过,那么会自动初始化下载,如果你已经下载,那么直接可以打开。

4.     4

选择你要扫描的盘符:这里我以可移动磁盘作说明:

5.     5

之后点击扫描就开始扫描已经被删除的文件了。

6.     6

左边侧栏是已删除文件的类型:

7.     7

点击查看所有文件夹:

8.     8

选择文件之后就可以开始恢复了。

9.     9

这里我选择恢复到桌面。

10.   10

看到这一步就成功了,你可以在桌面上看到已经恢复的文件。

 

END

 

 

 

五、处理对话框  1. 删除对话框  (1)在工作区窗格的“对话框视图”中选中要删除的对话框的ID,再按下键盘上的Delete键即可。例如在

下图所示的工程中删除对话框IDD_BEIJ_DIALOG,操作为:

2) 在“文件视图”中删除其对应的头文件和源文件;(3) 在相应文件夹中物理删除上面删除的头文件和源文件。

2. 删除对话框类  (1)在“文件视图”中删除类的头文件和源文件,如上图; (2) 在相应文件夹中物理删除上面删除的头文件和源文件。

(3) 在相应文件夹中删除“.clw”文件(一个)

如何:使用调用堆栈窗口

本主题适用于:

版本

Visual Basic

C#

F#

C++

Web Developer

学习版

专业版、高级专业版和旗舰版

使用“调用堆栈”窗口可以查看当前堆栈上的函数或过程调用。

“调用堆栈”窗口显示每个函数的名称以及编写它所用的编程语言。 函数或过程名可能包含可选信息,如模块名、行号、字节偏移量以及参数的名称、类型和值。 可以打开或关闭这些可选信息的显示。

一个黄色箭头标识执行指针当前所位于的堆栈帧。 默认情况下,该帧的信息显示在源、“反汇编”“局部变量”“监视”“自动”窗口中。 如果想将上下文更改为堆栈上的另一个帧,可以在“调用堆栈”窗口中执行相应的操作。

当调试符号对部分调用堆栈不可用时,“调用堆栈”窗口也许就不能显示那部分调用堆栈的正确信息。 将出现以下表示法:

[下面的帧可能不正确和/或缺失,没有为 name.dll 加载符号]

默认情况下在托管代码中, “调用堆栈”窗口隐藏非用户代码的信息。 在隐藏信息处出现以下表示法:

[<External Code>]

非用户代码是指除“我的代码”以外的任何代码。有关“我的代码”的更多信息,请参见如何:单步执行“仅我的代码” 使用快捷菜单可以选择显示非用户代码的调用堆栈信息。

可以使用快捷菜单选择查看线程之间的调用。

注意

显示的对话框和菜单命令可能会与“帮助”中的描述不同,具体取决于您的当前设置或版本。 若要更改设置,请在工具”菜单上选择导入和导出设置” 有关更多信息,请参见使用设置

以中断模式或运行模式显示调用堆栈窗口

·        “调试”菜单中选择“窗口”,然后单击“调用堆栈”

更改显示的可选信息

·        右击“调用堆栈”窗口,然后设置或清除“显示 &lt;所需信息&gt;”

调用堆栈窗口中显示非用户代码帧

·        右击“调用堆栈”窗口,然后选择“显示外部代码”

切换到另一个堆栈帧

1.     “调用堆栈”窗口中,右击要查看其代码和数据的帧。

2.     选择“切换到帧”

一个带有卷尾的绿色箭头显示在所选帧旁。 执行指针保留在原始帧中,仍然用黄色箭头标记。 如果从“调试”菜单中选择“单步执行”“继续”,执行将继续在原始帧中进行,而不是在选定的帧中进行。

显示与其他线程之间的来回调用

·        右击“调用堆栈”窗口,然后选择“包括对其他线程和来自其他线程的调用”

查看调用堆栈上的函数的源代码

·        “调用堆栈”窗口中,右击要查看其源代码的函数,然后选择“转到源代码”

查看调用堆栈上的函数的反汇编代码

·        “调用堆栈”窗口中,右击要查看其反汇编代码的函数,然后选择“转到反汇编”

调用堆栈窗口运行到特定函数

·        请参见运行到指定函数

在函数调用的退出点上设置断点

·        请参见如何:从“调用堆栈”窗口针对函数调用设置断点

加载模块符号

·        如果要重新加载模块的符号,请在“调用堆栈”窗口中右击显示该模块的帧,然后选择“加载符号”

加载符号

“调用堆栈”窗口中,可以为当前还未加载符号的代码加载调试符号。 这些符号可以是从 Microsoft 公共符号服务器下载的 .NET Framework 符号或系统符号,也可以是正在调试的计算机上的某个符号路径中的符号。

有关更多信息,请参见如何:使用符号服务器如何:指定符号位置和加载行为

加载符号

1.     “调用堆栈”窗口中,右击尚未为其加载符号的帧。 此帧将显示为灰色。

2.     指向“加载符号”,然后单击“Microsoft 符号服务器”“符号路径”

设置符号路径

1.     “模块”窗口中右击任一模块。

2.     单击“符号设置”

将打开“选项”对话框并显示“符号”页。

3.     “选项”对话框中单击“文件夹”图标。

“符号文件(.pdb)位置”框中将出现一个光标。

4.     键入所调试的计算机上的符号位置的目录路径名。 对于本地调试,此计算机指您的本地计算机。 对于远程调试,此计算机指远程计算机。

5.     单击“确定”关闭“选项”对话框。

请参见

任务

如何:使用符号服务器

如何:指定符号位置和加载行为

参考

如何:更改调试器窗口的数字格式

概念

“调用堆栈”窗口中的混合代码与丢失信息

查看调试器中的数据

本文是否对您有所帮助?

 

 

社区附加资源

© 2014 Microsoft

个人信息中心

·        中文速递邮件

·        |

 

 

 

 

位置:调试 >> 窗口 >> 调用堆栈
说明:
任何一个项目都会对项目进行各种层次和模块的划分,不管新手老手,在调试代码的时候(尤其是维护项目,修改别人的代码)还是经常会因为不知道代码是如何传递执行的而产生苦恼。
如下面跟踪到代码对某个属性进行set操作,但是并不知道这个set操作是由哪里发起的,通过跟踪到的这个set操作仅仅能知道将要set的这个value是什么,但是并不能知道这个value是从哪里来,也不知道究竟怎么来的。


此时,通过查看调试模式下的调用堆栈功能,就能够清晰地知道代码从那里走进来的。

同时,通过条用堆栈窗口,能够清楚地看到层层调用之间传递的参数名、参数值。
还可以右键堆栈信息,选择转到源代码,跳转到源代码所在行。

还可以右键堆栈信息,选择运行到光标处,则直接运行到该代码处。大大提高和增强了调试的快捷和方便性。

 

以前调试代码很少关注调用堆栈信息,今天使用这一功能使我快速的解决了一个问题,特别记录一下。

 

 

 

在计算机科学中,Callstack 是指存放某个程序的正在运行的函数的信息的栈。Call stack 由stack frames 组成,每个stack frame 对应于一个未完成运行的函数。

在当今流行的计算机体系架构中,大部分计算机的参数传递,局部变量的分配和释放都是通过操纵程序栈来实现的。栈用来传递函数参数,存储返回值信息,保存寄存器以供恢复调用前处理机状态。每次调用一个函数,都要为该次调用的函数实例分配栈空间。为单个函数分配的那部分栈空间就叫做 stack frame,也就是说,stack frame 这个说法主要是为了描述函数调用关系的。

Stackframe 组织方式的重要性和作用体现在两个方面:第一,它使调用者和被调用者达成某种约定。这个约定定义了函数调用时函数参数的传递方式,函数返回值的返回方式,寄存器如何在调用者和被调用者之间进行共享;第二,它定义了被调用者如何使用它自己的 stack frame 来完成局部变量的存储和使用。

简单介绍

    调试是程序开发者必备技巧。如果不会调试,自己写的程序一旦出问题,往往无从下手。本人总结10年使用VC经验,对调试技巧做一个粗浅的介绍。希望对大家有所帮助。

   

    今天简单的介绍介绍调用堆栈。调用堆栈在我的专栏的文章VC调试入门提了一下,但是没有详细介绍。

   

    首先介绍一下什么叫调用堆栈:假设我们有几个函数,分别是function1,function2,function3,funtion4,且function1调用function2,function2调用function3,function3调用function4。在function4运行过程中,我们可以从线程当前堆栈中了解到调用他的那几个函数分别是谁。把函数的顺序关系看,function4、function3、function2、function1呈现出一种“堆栈”的特征,最后被调用的函数出现在最上方。因此称呼这种关系为调用堆栈(callstack)。

   

    当故障发生时,如果程序被中断,我们基本上只可以看到最后出错的函数。利用call stack,我们可以知道当出错函数被谁调用的时候出错。这样一层层的看上去,有时可以猜测出错误的原因。常见的这种中断时ASSERT宏导致的中断。

   

    在程序被中断时,debug工具条的右侧倒数第二个按钮一般是callstack按钮,这个按钮被按下后,你就可以看到当前的调用堆栈。

   

    实例一:介绍

    我们首先演示一下调用堆栈。首先我们创建一个名为Debug的对话框工程。工程创建好以后,双击OK按钮创建消息映射函数,并添加如下代码:

   

    void CDebugDlg::OnOK()

    {

   

    // TODO: Addextravalidation here

    ASSERT(FALSE);

   

    }

   

    我们按F5开始调试程序。程序运行后,点击OK按钮,程序就会被中断。这时查看call stack窗口,就会发现内容如下:

   

    CDebugDlg::OnOK()line176 + 34 bytes

   _AfxDispatchCmdMsg(CCmdTarget* 0x0012fe74 {CDebugDlg}, unsigned int 1, int 0,void (void)* 0x5f402a00`vcall'(void), void * 0x00000000, unsigned int 12,AFX_CMDHANDLERINFO *0x00000000) line 88

   CCmdTarget::OnCmdMsg(unsigned int 1, int 0,void * 0x00000000,AFX_CMDHANDLERINFO * 0x00000000) line 302 + 39 bytes

   CDialog::OnCmdMsg(unsignedint 1, int 0, void * 0x00000000, AFX_CMDHANDLERINFO *0x00000000) line 97 + 24bytes

    CWnd::OnCommand(unsignedint1, long 656988) line 2088

   CWnd::OnWndMsg(unsignedint 273, unsigned int 1, long 656988, long * 0x0012f83c)line 1597 + 28 bytes

   CWnd::WindowProc(unsignedint 273, unsigned int 1, long 656988) line 1585 + 30bytes

    AfxCallWndProc(CWnd*0x0012fe74 {CDebugDlg hWnd=???}, HWND__ * 0x001204b0, unsigned int273,unsigned int 1, long 656988) line 215 + 26 bytes

    AfxWndProc(HWND__*0x001204b0, unsigned int 273, unsigned int 1, long 656988) line 368

    AfxWndProcBase(HWND__*0x001204b0, unsigned int 273, unsigned int 1, long 656988) line 220 + 21bytes

    USER32! 77d48709()

    USER32! 77d487eb()

    USER32! 77d4b368()

    USER32! 77d4b3b4()

    NTDLL! 7c90eae3()

    USER32! 77d4b7ab()

    USER32! 77d7fc9d()

    USER32! 77d76530()

    USER32! 77d58386()

    USER32! 77d5887a()

    USER32! 77d48709()

    USER32! 77d487eb()

    USER32! 77d489a5()

    USER32! 77d489e8()

    USER32! 77d6e819()

    USER32! 77d65ce2()

   CWnd::IsDialogMessageA(tagMSG* 0x004167d8 {msg=0x00000202 wp=0x00000000lp=0x000f001c}) line 182

   CWnd::PreTranslateInput(tagMSG* 0x004167d8 {msg=0x00000202 wp=0x00000000lp=0x000f001c}) line 3424

   CDialog::PreTranslateMessage(tagMSG* 0x004167d8 {msg=0x00000202 wp=0x00000000lp=0x000f001c}) line 92

    CWnd::WalkPreTranslateTree(HWND__*0x001204b0, tagMSG * 0x004167d8 {msg=0x00000202 wp=0x00000000lp=0x000f001c})line 2667 + 18 bytes

   CWinThread::PreTranslateMessage(tagMSG* 0x004167d8 {msg=0x00000202wp=0x00000000 lp=0x000f001c}) line 665 + 18 bytes

    CWinThread::PumpMessage()line841 + 30 bytes

   CWnd::RunModalLoop(unsignedlong 4) line 3478 + 19 bytes

    CDialog::DoModal()line536 + 12 bytes

   CDebugApp::InitInstance()line 59 + 8 bytes

   AfxWinMain(HINSTANCE__* 0x00400000, HINSTANCE__ * 0x00000000, char *0x00141f00, int 1) line 39 + 11bytes

    WinMain(HINSTANCE__*0x00400000, HINSTANCE__ * 0x00000000, char * 0x00141f00, int 1) line 30

   WinMainCRTStartup()line 330 + 54 bytes

    KERNEL32! 7c816d4f()

   

    这里,CDebugDialog::OnOK作为整个调用链中最后被调用的函数出现在callstack的最上方,而内核中程序的启动函数Kernel32!7c816d4f()则作为栈底出现在最下方。

   

    实例二:学习处理方法

    微软提供了MDI/SDI模型提供文档处理的建议结构。有些时候,大家希望控制某个环节。例如,我们希望弹出自己的打开文件对话框,但是并不想自己实现整个文档的打开过程,而更愿意MFC完成其他部分的工作。可是,我们并不清楚MFC是怎么处理文档的,也不清楚如何插入自定义代码。

   

    幸运的是,我们知道当一个文档被打开以后,系统会调用CDocument派生类的Serialize函数,我们可以利用这一点来跟踪MFC的处理过程。

   

    我们首先创建一个缺省的SDI工程Test1,并在CTest1Doc::Serialize函数的开头增加一个断点,运行程序,并打开一个文件。这时,我们可以看到调用堆栈是(我只截取了感兴趣的一段):

   

   CTest1Doc::Serialize(CArchive& {...}) line 66

   CDocument::OnOpenDocument(constchar * 0x0012f54c) line 714

   CSingleDocTemplate::OpenDocumentFile(constchar * 0x0012f54c, int 1) line 168 +15 bytes

   CDocManager::OpenDocumentFile(constchar * 0x0042241c) line 953

   CWinApp::OpenDocumentFile(constchar * 0x0042241c) line 93

   CDocManager::OnFileOpen()line 841

   CWinApp::OnFileOpen()line 37

   _AfxDispatchCmdMsg(CCmdTarget* 0x004177f0 class CTest1App theApp, unsigned int57601, int 0, void (void)*0x00402898 CWinApp::OnFileOpen, void * 0x00000000,unsigned int 12,AFX_CMDHANDLERINFO * 0x00000000) line 88

   CCmdTarget::OnCmdMsg(unsignedint 57601, int 0, void * 0x00000000,AFX_CMDHANDLERINFO * 0x00000000) line 302+ 39 bytes

   CFrameWnd::OnCmdMsg(unsignedint 57601, int 0, void * 0x00000000,AFX_CMDHANDLERINFO * 0x00000000) line 899+ 33 bytes

   CWnd::OnCommand(unsignedint 57601, long 132158) line 2088

   CFrameWnd::OnCommand(unsignedint 57601, long 132158) line 317

   

   

    从上面的调用堆栈看,这个过程由一个WM_COMMAND消息触发(因为我们用菜单打开文件),由CWinApp::OnFileOpen最先开始实际处理过程,这个函数调用CDocManager::OnFileOpen打开文档。

   

    我们首先双击CWinApp::OnFileOpen()line 37打开CWinApp::OnFileOpen,它的处理过程是:

   

    ASSERT(m_pDocManager != NULL);

    m_pDocManager->OnFileOpen();

   

    m_pDocManager是一个CDocManager类的实例指针,我们双击CDocManager::OnFileOpen行,看该函数的实现:

   

   voidCDocManager::OnFileOpen()

    {

     // prompt theuser (with all documenttemplates)

     CString newName;

     if(!DoPromptFileName(newName,AFX_IDS_OPENFILE,

     OFN_HIDEREADONLY| OFN_FILEMUSTEXIST, TRUE,NULL))

     return; // opencancelled

    AfxGetApp()->OpenDocumentFile(newName);

     // if returnsNULL, the user has already beenalerted

    }

   

    很显然,该函数首先调用DoPromptFileName函数来获得一个文件名,然后在继续后续的打开过程。

   

    顺这这个线索下去,我们一定能找到插入我们文件打开对话框的位置。由于这不是我们研究的重点,后续的分析我就不再详述。

   

    实例三:内存访问越界

    在Debug版本的VC程序中,程序会给每块new出来的内存,预留几个字节作为越界检测之用。在释放内存时,系统会检查这几个字节,判断是否有内存访问越界的可能。

   

    我们借用前一个实例程序,在CTest1App::InitInstance的开头添加以下几行代码:

   

     char * p = newchar[10];

     memset(p,0,100);

     delete []p;

     return FALSE;

   

    很显然,这段代码申请了10字节内存,但是使用了100字节。我们在memset(p,0,100);这行加一个断点,然后执行程序,断点到达后,我们观察p指向的内存的值(利用Debug工具条的Memory功能),可以发现它的值是:

   

     CD CD CD CD CDCD CD CD

     CD CD FD FD FDFD FD FD

     00 00 00 00 0000 00 00

     ......

   

    根据经验,p实际被分配了16个字节,后6个字节用于保护。我们按F5全速执行程序,会发现如下的错误信息被弹出:

   

     Debug Error!

     Program:c:\temp\test1\Debug\test1.exe

     DAMAGE: afternormal block (#55) at 0x00421AB0

     Press Retry todebug the application

   

    该信息提示,在正常内存块0x00421AB0后的内存被破坏(内存访问越界),我们点击Retry进入调试状态,发现调用堆栈是:

   

    _free_dbg_lk(void*0x00421ab0, int 1) line 1033 + 60 bytes

    _free_dbg(void*0x00421ab0, int 1) line 970 + 13 bytes

    operator delete(void*0x00421ab0) line 351 + 12 bytes

   CTest1App::InitInstance()line 54 + 15 bytes

   

    很显然,这个错误是在调用delete时遇到的,出现在CTest1App::InitInstance()line 54 + 15 bytes之处。我们很容易根据这个信息找到,是在释放哪块内存时出现问题,之后,我们只需要根据这个内存的访问过程确定哪儿出错,这将大大降低调试的难度。

   

    实例四:子类化

    子类化是我们修改一个现有控件实现新功能的常用方法,我们借用实例一中的Debug对话框工程来演示我过去学习子类化的一个故事。我们创建一个缺省的名为Debug的对话框工程,并按照下列步骤进行实例化:

   

    在对话框资源中增加一个Edit控件

    用class wizard为CEdit派生一个类CMyEdit(由于今天不关心子类化的具体细节,因此这个类不作任何修改)

    为Edit控件,增加一个控件类型变量m_edit,其类型为CMyEdit

    在OnInitDialog中增加如下语句:

   

   m_edit.SubclassDlgItem(IDC_EDIT1,this);

   

    我们运行这个程序,会遇到这样的错误:

   

   

    Debug AssertionFailed!

   Application:C:\temp\Debug\Debug\Debug.exe

    File:Wincore.cpp

    Line:311

   

    For information onhowyour program can cause an assertion failure, see Visual C++ documentationonasserts.

   

    (Press Retry todebugthe application)

   

    点击Retry进入调试状态,我们可以看到调用堆栈为:

   

    CWnd::Attach(HWND__*0x000205a8) line 311 + 28 bytes

   CWnd::SubclassWindow(HWND__* 0x000205a8) line 3845 + 12 bytes

   CWnd::SubclassDlgItem(unsignedint 1000, CWnd * 0x0012fe34 {CDebugDlg hWnd=0x001d058a})line 3883 + 12 bytes

   CDebugDlg::OnInitDialog()line 120

   

    可以看出在Attach句柄时出现问题,出问题行的代码为:

   

     ASSERT(m_hWnd ==NULL);

   

    这说明我们在子类化时不应该绑定控件,我们删除CDebugDialog::DoDataExchange中的下面一行:

   

     DDX_Control(pDX,IDC_EDIT1, m_edit);

   

    问题就得到解决

   

    总结

    简而言之,call stack是调试中必须掌握的一个技术,但是程序员需要丰富的经验才能很好的掌握和使用它。你不仅仅需要熟知C++语法,还需要对相关的平台、软件设计思路有一定的了解。我的文章只能算一个粗浅的介绍,毕竟我在这方面也不算高手。希望对新进有一定的帮助。

   

   

    调试之编程准备

   

    对于一个程序员而言,学习一种语言和一种算法是非常容易的(不包括那些上学花很多时间玩,上班说学习没时间的人)。但是,任何程序都可能是有瑕疵的,尤其有过团队协作编程经验的人,对这个感触尤为深刻。

   

   

    在我前面的述及调试的文章里,我侧重于VC集成环境中的一些设置信息和调试所需要的一些基本技巧。但是,仅仅知道这些是不够的。一个成功的调试的开端是编程中的准备。

   

    分离错误

    很多程序员喜欢写下面这样的式子:

   

     CLeftView* pView=

     ((CFrameWnd*)AfxGetApp()->m_pMainWnd)->m_wndSplitterWnd.GetPane(0,0);

   

    如果一切顺利,这样的式子当然是没什么问题。但是作为一个程序员,你应该时刻记得任何一个调用在某些特殊的情况下都可能失败,一旦上面某个式子失败,那么整个级联式就会出问题,而你很难弄清楚到底哪儿出错了。这样的式子的结果往往是:省了2分钟编码的时间,多了几星期的调试时间。

   

    对于上面的式子,应该尽可能的把式子分解成独立的函数调用,这样我们可以随时确定是哪个函数调用出问题,进口缩小需要检查的范围。

   

    检查返回值

    检查返回值对于许多编程者来说似乎是一个很麻烦的事情。但是如果你能在每个可能出错的函数调用处都检查返回值,就可以立刻知道出错的函数。

   

    有些人已经意识到检查返回值的重要性,但是要记住,只检查函数是否失败是不够的,我们需要知道函数失败的确切原因。例如下面的代码:

   

    if(connect(sock,(constsockaddr*)&addr,sizeof(addr)) == SOCKET_ERROR)

    {

    AfxMessageBox("connect failed");

    }

   

    尽管这里已经检查了返回值,实际上没有多少帮助。正如很多在vckbase上提问的人一样,大概这时候只能喊“为什么连接失败啊?”。这种情况下,其实只能猜测失败的原因,即使高手,也无法准确说出失败的原因。

   

    增加诊断信息

    在知道错误的情况下,应该尽可能的告诉测试、使用者更多的信息,这样才能了解导致失败的原因。如果程序员能提供如下错误信息,对于诊断错误是非常有帮助的:

   

    出错的文件:我们可以借助宏THIS_FILE和__FILE__。注意THIS_FILE是在cpp文件手工定义的,而__FILE__是编译器定义的。当记录错误的函数定义在.h中时,有时候用THIS_FILE更好,因为他能说明在哪个cpp中调用并导致失败的。

    出错的行:我们可以借助宏__LINE__

    出错的函数:如果设计的好,有以上两项已经足够。当然我们可以直接打印出出错的函数或者表达式,这样在大堆代码中搜索(尤其是不支持go to line的编辑器中)还是很有用的。

    出错的原因:出错的原因很多只能由程序自己给出。如果出错只会问别人,那么你永远不可能成为一个合格的程序设计人员。很多函数失败时都会设置errno。我们可以用GetLastError获得错误码,并通过FormatMessage打印出具体错误的文字描述。

 

 

 

两种方法:
1
、在Project->Addto Project->Files中将你的LIB文件直接加入到工程中去。

2、在TOOLS->OPTIONS->Directories->Libraryfiles,加入你的LIB文件所在的目录,然后:
      
Project->setting->link->Object/LibraryModules中加入你的LIB文件,如 "you.lib"
      
或者,在代码里面 #pragma comment(lib,"you.lib")
      
注意:如果该 lib 不在 vc 的默认路径(TOOLS->OPTIONS->Directories->Libraryfiles)里,那直接引入文件名还是找不到的。这种情况下,可以在#pragma comment 中,或者是LibraryModules 中显示的引入路径。

 

        要用一个dll(假设这个dll的名字叫**),你手头要有三个文件:"**.h"头文件,"**.dll"动态链接库文件,还有"*.lib"文件.首先把这三个文件都拷贝到你的项目文件夹下,然后在工程->设置选单中,点到右边的"link"选项卡,"link"中有一项"对象/库模块"(object/librarymodule),在这一项中输入"**.lib",然后在要用这个库函数的cpp文件中的开始位置加上一句#include "**.h" 然后就可以在此cpp文件中用这个库中的函数了.

 

 

 

 

 

 

在你工程stdafx.h头文件中加入#pragma comment(lib,"wsock32.lib ") 这句话就可以了,或者project->setting->link  
确保lib文件在工程目录下  
obj/library moudels加入该lib文件名




我现在在VS2008环境下编写MFC程序,现在又想添加动态和惊天链接库怎么添加啊?有.lib.h.dll文件!

分享到:

2012-11-19 14:28提问者采纳

项目》引用,右击添加引用,浏览选项卡,找到你要添加的文件,确定即可

提问者评价

谢谢!

 

 

方法1:在cpp文件中加入 #pragma comment(lib,"XXX.lib")

方法2

步骤1:Tools->options->projects and solutions->VC++directories分别在包含文件,库文件填加了路径(这些路径只告诉编译器怎么找文件,没有说把那里面的文件加入工程,若不设置,编译报错:无法打开***文件)

 步骤2Project->properties->c/c++->general->additionalinclude directories 添加包含文件

 Project->properties->linker->general->additionallibrary directories 告诉计算机查找LIB的附加路径

 Project->properties->linker->input->additionaladditional dependencies添加用到的lib,(若不添加,连接报错:无法解析的外部符号)。

vs2008 express 生成静态链接库lib

1. 静态链接库的创建

        solution new project ->win32 project -> static library 即可创建生成静态链接库的项目。在该项目的properties中可看到:

·        ConfigurationProperties -->General --> Configuration type 中可以看到是lib

·        ConfigurationProperties --> General --?Output Directory 是生成lib的目录

·        Library-->General -->Output File 是生成的文件名字

2. 静态链接库的使用

·        包含头文件

·        引入lib文件

·        调用lib库提供的函数

注意,debug release 模式下生的的lib文件是不一样的,在其他项目引用生成的lib文件时,处于debug模式下必须引用debug模式下生成的lib文件,release模式下必须引用release模式下生成的文件。否则可能会出问题。

 

 

 

http://zhidao.baidu.com/question/248459661.html?oldq=1如果这种不行 另外一种:在解决资源管理器点开你的项目单击引用接着单击右键选择添加引用然后选择选项卡浏览现在你把你的.dll文件选择进来就行了点击确定这样就加在好了

提问者评价

恩,非常感谢

 

在工具箱,单击右键,选择选择项”→ “浏览,然后选择你的DLL文件,点击确定

 

 

 

 

只要源文件中包含相应的头文件,并且在project->option中的编译选项中设置搜索路径既可以在编译后自动包含到include

 

另外搜索路径的设置最好不要用绝对路径,可以使用相对路径

 

将自己编写的头文件和其他头文件放在相同路径下,然后在DSP_Device.h中包含其他头文件的代码内用include包含你自己的头文件,最后编译工程,CCS会自动将你的头文件添加到工程中来。

 

右键点击你的工程,如 try.project
->scan all files dependencies
点击就OK

 

不用加到工程中,只要搜索路径对,就行了。

 

只要源文件中包含相应的头文件,并且在project->option中的编译选项中设置搜索路径既可以在编译后自动包含到include下。

 

 

 

vs2008 添加控件变量关联右击控件添加变量是灰色的原因

(2011-09-28 17:37:53)

转载▼

标签:

杂谈

分类:VisualStudio

原因:1.没有为对话框创建类
           2.创建类了,创建完后又修改了对话框ID,resource.h里面你会发现新老ID被定义为同一个数字,但类里面// 对话框数据
            enum { IDD =IDD_DLG_QSSIM };用的还是老ID,和对话框新ID不一致,
           因此添加变量按钮为灰色

 

 

1C++语言中“_T”是什么意思? Visual C++里边定义字符串的时候,用_T来保证兼容性,VC支持ascii和unicode两种字符类型,用_T可以保证从ascii编码类型转换到unicode编码类型的时候,程序不需要修改。如果将来你不打算升级到unicode,那么也不需要_T, ---------------------------------------------------------_t("hello world")   在ansi的环境下,它是ansi的,如果在unicode下,那么它将自动解释为双字节字符串,既unicode编码。 这样做的好处,不管是ansi环境,还是unicode环境,都适用。 2请问在vc++中的字符串_T("ABC")和一个普通的字符串“ABC”有什么区别。 _T("ABC")   表示如果定义了unicode   它表示 L"ABC",每个字符为16位,宽字符字符串 --------------------------------------------------------- if notUNICODE

它就是ascii的"ABC",每个字符为8位 "ABC"就是指ascii字符串"ABC" ---------------------------------------------------------- 相当于  #ifdef _UNICODE   #define _T("ABC")L"ABC"  #else   #define _T("ABC") "ABC"  #endif

 

_T("ABC")中的一个字符和汉字一样,占两个字节,而在"ABC"中,英文字符占一个字节,汉字占两个字节

UNICODE 使用的字符类型是WCHAR  unsigned short    双字节类型   即每个字符占有两字节

 

 

 

错误C2665:   “AfxMessageBox”:   2   个重载中没有一个可以转换所有参数类型

1,楼主发表于:2007-01-01 03:56:34
同样的语句,到了vc2005(vc8.0)怎么就不行了呢?
错误C2665:   “AfxMessageBox”:  2   个重载中没有一个可以转换所有参数类型

#1楼 回复于:2007-01-0108:57:38
up

#2楼 回复于:2007-01-01 09:13:16
就是这句:AfxMessageBox( "Simple   message   box. ");如果先定义一个CString   变量,再赋值就没问题
CString   sTemp;
sTemp= "Simple   message   box. ";
AfxMessageBox(sTemp);


#3楼 回复于:2007-01-0109:20:39
AfxMessageBox(_T( "Simple   message   box. "));

#4楼 回复于:2007-01-01 10:15:58
记住一点,VC2005中默认的工程选项是UNICODE就可以了。
所以,加上_T或L是需要的。

#5楼 回复于:2007-01-0110:19:32
or   TEXT 

 

 

2,初学.net,编写如下代码运行,竟然提示错误(error C2665: “AfxMessageBox”: 2 个重载中没有一个可以转换所有参数类型)。

   代码:

   1   void CMouseMoveView::OnAppExit()
   2   {
   3     // TODO:
在此添加命令处理程序代码
   4     if(AfxMessageBox("
是否真的要退出当前程序?",MB_YESNO)==IDYES)
   5    AfxGetMainWnd()->SendMessage(WM_CLOSE);
   6    }

办法1 将第4行改为:if(AfxMessageBox(_T("是否真的要退出当前程序?"),MB_YESNO)==IDYES)

办法2选择“项目”菜单->项目属性->配置属性->常规->字符集,改为“未设置”即可。

尽量使用方法2.

 

 

 

关于OnTimer()

 

   OnTimer()函数是响应用SetTimer()函数设定的时钟发送的时钟消息的,你没设定时钟,就不会有时钟消息,OnTimer()里的语句当然也不会被调用。

  为类添加VM_TIMER消息响应,会看到类中多了个OnTimer(UINTnIDEvent) 
   
然后用SetTimer(1,10,NULL)就行了。第一个参数是ID,第二个是间隔时间,单位是毫秒,第3个是响应函数,因为要在OnTimer(UINTnIDEvent)里面做响应操作,所以此处给个NULL就行了

Timer事件,即定时器事件,是在游戏编程中,经常使用的一个事件。借助它可以产生定时执行动作的效果。这篇文章,就和大家一起探讨一下如何使用SetTimer()函数。 
1
SetTimer定义在那里?

SetTimer表示的是定义个定时器。根据定义指定的窗口,在指定的窗口(CWnd)中实现OnTimer事件,这样,就可以相应事件了。

SetTimer有两个函数。一个是全局的函数::SetTimer()

UINTSetTimer( 
HWND hWnd, // handle of window for timer messages 
UINT nIDEvent, // timer identifier 
UINT uElapse, // time-out value 
TIMERPROC lpTimerFunc // address of timer procedure 
);

其中hWnd 是指向CWnd的指针,即处理Timer事件的窗口类。说道窗口类(CWnd),我们有必要来看一下CWnd的继承情况:CWnd有以下子类:CFrameWnd,CDialog,CView,CControlBar等类。这也意味这些类中都可以定义SetTimer事件。

同时,SetTimer()在CWnd中也有定义,即SetTimer()是CWnd的一个成员函数。CWnd的子类可以调用该函数,来设置触发器。

UINTSetTimer( UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT* lpfnTimer)(HWND,UINT, UINT, DWORD) );

参数含义:

nIDEvent:是指设置这个定时器的iD,即身份标志,这样在OnTimer()事件中,才能根据不同的定时器,来做不同的事件响应。这个ID是一个无符号的整型。

nElapse

是指时间延迟。单位是毫秒。这意味着,每隔nElapse毫秒系统调用一次Ontimer()。

void(CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD)

Specifiesthe address of the application-supplied TimerProc callback function thatprocesses the WM_TIMER messages. If this parameter is NULL, the WM_TIMERmessages are placed in the application’s message queue and handled by the CWndobject

意思是,指定应用程序提供的TimerProc回调函数的地址,来处里这个Timer事件。如果是NULL,处理这个Timer事件的定义这个TimerCWnd对象。他将WM_TIMER消息传递给这个对象,通过实现这个对象的OnTimer()事件来处理这个Timer事件。

所以,一般情况下,我们将这个值设为NULL,有设置该定时器的对象中的OnTimer()函数来处理这个事件。

同样的,我们再看看KillTimer()和OnTimer()的定义:

KillTimerSetTimer()一样,他也有两个,一个是全局的::KillTimer(),另一个是CWnd的一个函数。他的声明如下:


//
全局函数

BOOLKillTimer( 
HWND hWnd, // handle of window that installed timer 
UINT uIDEvent // timer identifier 
);

//CWnd函数

BOOLKillTimer( int nIDEvent );

这两个函数表示的意思是将iDnIDEVENT的定时器移走。使其不再作用。其用法如同SetTimer()一样。

再看看OnTimer()

CWnd::OnTimer 
afx_msg void OnTimer( UINT nIDEvent );

ontimer()是响应CWnd对象产生的WM_Timer消息。nIDEvent表示要响应TIMER事件的ID

二、Timer事件的使用:

由以上的分析,我们应该很清楚,如何来使用Timer事件。假定我们在视图上画一个渐变的动画。我们首先在菜单栏上添加一个菜单项,给这个菜单添加命令响应:

pView->SetTimer(1,1000,NULL);//pView是视图类的指针,这里是在视图类当中设置一个定时器。

添加完毕,再给视图类添加一个WM_Timer事件的相应。在OnTimer()函数中编写汉书,进行相应。

如此,就能做出动画。

 

 

VC2008 ERROR C101008A解决方案  

2010-06-0413:39:00|  分类: 编程专栏|举报|字号 订阅

对于VS2005/VS2008IDE,如果想去掉工程的Unicode属性,编译运行时往往会发生这个错误

MFC错误ERROR C101008A解决方案

错误提示如下:

mt.exe : general errorc101008a: Failed to save the updated manifest to the file".\Debug\Draw.exe.embed.manifest". Bpcn

解决方案一:

工程——>属性——>清单工具——>命令行——>附加选项——>"/validate_manifest"

 

解决方案二

这个问题经常出现!其实并不是你的真正出现了什么问题,只是你的编译链接的时候编译器自身的问题而已!也许是VS2005,VS2008 BUG吧,解决的方法:点classview中的工程,选右鍵,再点clean就可以了;或者是build->clean solusion也可以。

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 



 

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值