RSS 2.0 Feed
.Net Framework
摘要:同自动化浏览器(http://blog.joycode.com/jiangsheng/archive/2005/10/20/65489.aspx)相比,自动化浏览器控件(WebBrowser Control) 在应用程序中更加常用。从Outlook的预览窗格到Maxthon这样的基于IE引擎的浏览器,从无界面的HTML分析器到Norton Antivirusd的主界面,浏览器控件在众多领域被用作各种各样的用途。这也使得有必要根据具体的用户需求自定义浏览器控件的行为。 在应用程序中加入浏览器控件 集成浏览器控件的最简单的方法是找一个支持ActiveX的集成开发环境,在工具箱中加入Microsoft Web Browser这个控件,往表单上拖一个这个控件就可以完成工作。你甚至可以用集成开发环境添加ActiveX的事件处理函数。如果要直接导入ActiveX的话,建议使用mehrcpp的vbMHWB控件(http://www.codeproject.com/atl/vbmhwb.asp)。这个控件在浏览器控件的基础上进行了扩展,暴露了很多底层接口。 通常导入ActiveX就可以满足大部分需求  ,但是有些类库中也集成了浏览器控件,并且提供了更多的功能,例如MFC的CHTMLView和CDHtmlDialog,ATL的HTML Control,以及.Net 2.0中的Windows.Forms.WebBrowser。如果使用Visual C++来进行非托管编程,那么建议使用MFC或者ATL的封装类,或者使用vbMHWB控件。托管编程中当然首选Windows.Forms.WebBrowser。除非这些类的BUG影响到了应用程序的开发,否则建议使用这些功能更加强大的封装类。 在使用浏览器控件及其封装类的时候要注意一些已知问题 最后一个包含浏览器的窗口关闭时会话信息可能会丢失(http://support.microsoft.com/kb/311072) MFC6.0版本的CHTMLView中一些方法没有释放获得的BSTR字符串,造成内存泄漏(http://support.microsoft.com/kb/241750)。 MFC6.0版本的CHTMLView缺少WS_CLIPCHILDREN风格,使得其中的浏览器控件重画不正常(http://support.microsoft.com/kb/220021) Windows.Forms.WebBrowser的WebBrowserSite类不能通过重载来自定义其行为(https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=115198) 常见任务 在集成浏览器控件之后,可以完成基本的网页浏览,但是对于不同的任务,也需要进一步的处理,例如设置控件的属性、为控件添加事件处理、操作HTML文档等等。 修改浏览器控件的属性 这在集成开发环境中可以很容易地设置,也可以自己实现容器来设置,但是CHTMLView这样的封装类没有这个选项(http://support.microsoft.com/kb/197921)。 链接目标解析。对于用浏览器控件来做浏览器的场合来说,需要将浏览器的RegisterAsBrowser属性设置为true。这使得Internet Explorer在解析HTML链接的target属性指定的目标窗口时可以找到这个窗口。 禁用拖放。对于使用浏览器控件来做预览窗格的场合来说,需要将浏览器的RegisterAsDropTarget属性设置为false。这使得窗口不接受拖进来的文件和链接。 禁用消息框。对于用浏览器控件来做HTML分析器的场合来说,有时需要屏蔽脚本产生的消息框以避免阻塞程序运行。这可以通过设置浏览器的Silent属性来实现,或者实现IDocHostShowUI::ShowMessage。 捕获浏览器控件的事件 集成开发环境中可以也很容易地添加浏览器的事件处理函数。比较常用的事件包括 NewWindow2或者NewWindow3事件。默认情况下,浏览器控件中创建的新窗口会是一个Internet Explorer的窗口。这通常不是预期的行为,对于浏览器程序来说更是这样。需要处理浏览器的NewWindow2或者NewWindow3(在Windows XP SP2或者Windows 2003 SP1之后可用)事件来让新的浏览器窗口在应用程序提供的窗口中运行。 WindowClosing事件。浏览器控件需要处理WindowClosing事件来在浏览器控件被脚本关闭时关闭浏览器控件的宿主窗口(http://support.microsoft.com/kb/253219)。 BeforeNavigate2事件。可以在自己的网页中加入自定义的协议,之后在BeforeNavigate2事件中扫描URL来进行网页和应用程序之间的交互(http://www.microsoft.com/msj/0100/c/c0100.aspx)。当然,自定义的网络协议也可以用Asynchronous Pluggable Protocol来处理(参见http://support.microsoft.com/kb/303740),vbMHWB控件就实现了这个功能。但是更加常用的是在弹出广告过滤器程序中用BeforeNavigate2来判断在NewWindow2事件中创建的窗口是否需要关闭。 操作MSHTML文档 通常HTML分析和浏览器自动化程序都需要分析网页的结构,找到需要操作的元素。这需要对网页的结构进行分析,找到目标元素的标识方法。 一些常用的操作包括: 设置HTML元素的属性,例如html、style、value等等。注意有些属性是只读的,甚至是程序无法访问的(例如input元素在类型为文件时其value属性不可访问)。 分析网页的结构来保存网页数据,例如拆取Web 页一文介绍的方案(http://www.microsoft.com/china/msdn/Archives/workshop/scrape.asp) 处理HTML元素的事件。这需要分析浏览器控件中的MSHTML文档对象,定位被操作的元素,以及在元素的连接点上挂接自定义的事件处理程序(http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/mshtml/tutorials/sink.asp)。 添加/删除HTML元素。注意设置有时设置outHtml属性并不能正确创建元素(http://support.microsoft.com/kb/185140),一个的方法是用HTMLDocument对象的CreateElememt方法。 调用HTML元素的方法,这和在脚本中操作HTML类似。可操作的元素/接口可以参考Interfaces and Scripting Objects(http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/mshtml/reference/ifaces/interface.asp),操作方法可以参考Introduction to Dynamic HTML(http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/mshtml/reference/ifaces/interface.asp) 以上的功能都可以通过直接在网页中加入脚本实现(http://support.microsoft.com/kb/185128),而且脚本也可以通过应用程序实现的扩展接口来和应用程序本身交互。另外,脚本还可以被用来自定义一些事件,例如在需要重载自定义的ShowModalDialog的时候就可以用IDispatchEx给window对象添加一个属性,其值为一个自定义的ShowModalDialog函数(http://groups.google.com/group/microsoft.public.inetsdk.programming.webbrowser_ctl/browse_thread/thread/e5eeb4a9111b16af/4bc2709aeb2bb444?lnk=raot),也可以用加入脚本的办法来捕获网页中的错误(http://support.microsoft.com/kb/317024)。  在页面包含框架的时候,可能需要跨框架访问HTML文档。可以通过查询框架元素所支持的IWebBrowser2接口或者IHTMLWindow2接口来访问框架中的文档(http://support.microsoft.com/kb/196340),但是也有可能因为安全设置而无法访问(http://support.microsoft.com/kb/167796)。 在浏览器控件中显示其它类型的文档时,可以用IWebBrowser2的document属性来访问ActiveX文档,例如在显示Microsoft Word时,IWebBrowser2的document属性就是Word的文档对象,在显示文件夹的时候,IWebBrowser2的document属性就是文件夹对象等等。 扩展浏览器的宿主 浏览器控件在创建时会查询ActiveX容器的IOleClientSite的实现的如下接口:IDocHostUIHandler, IDocHostUIHandler2 and IDocHostShowUI。 虽然在无法自定义ActiveX容器的情况下可以用ICustomDoc::SetUIHandler来挂接IDocHostUIHandler到浏览器控件,但是这样也会造成内存泄漏(http://support.microsoft.com/kb/893629)。一些类库,例如MFC、ATL和.Net类库都实现了IDocHostUIHandler接口。 除了专门用于浏览器用途的程序之外,通常都需要自定义浏览器控件的上下文菜单。这需要实现IDocHostUIHandler::ShowContextMenu。通常的实现包括完全禁用上下文菜单、完全替换上下文菜单、以及修改部分上下文菜单。经常被从上下文菜单中移除的菜单项包含查看源代码、刷新和属性。一种替代的方案是在容器中过滤右键消息(http://support.microsoft.com/kb/231578)。 与浏览器相比,一些Internet Explorer的宿主功能在浏览器控件中并不是默认启用。在某些场合,默认启用的宿主功能可能并非预期。这时需要实现IDocHostUIHandler::GetHostInfo。可以通过实现IDocHostUIHandler::GetHostInfo来自定义的功能包括: 自动完成功能。对于用浏览器控件来做浏览器的场合来说,这个功能是有必要启用的。启用的方法是设置DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE位 如果浏览器中的链接网址包含非ASCII的字符,那么需要实现IDocHostUIHandler::GetHostInfo,并且在返回的DOCHOSTUIINFO结构中设置dwFlags成员的DOCHOSTUIFLAG_URL_ENCODING_ENABLE_UTF8位。这使得网址会在发送之前用UTF-8编码。 3D边框、滚动条,禁用文字选择功能和禁用页面上的脚本。 对于使用浏览器控件来做HTML编辑器的场合来说,有时需要修改默认的页面样式。这都需要实现IDocHostUIHandler::GetHostInfo(http://support.microsoft.com/kb/328803)。注意在有些版本的IE中IDocHostUIHandler::GetHostInfo只在MSHTML被初始化的时候被调用,所以如果你需要在MSHTML被初始化之后使你的修改生效,你需要浏览到一个Word之类的非HTML Active document文档,之后再浏览回来。 在使用浏览器控件来做数据录入界面的场合,需要更改浏览器控件默认的Tab键处理使得用户可以使用Tab键切换到容器中的其他控件。这需要实现IDocHostUIHandler::TranslateAccelerator来自定义浏览器控件的快捷键处理。对于MFC这样用消息钩子来做消息预处理的可自定义容器来说,也可以用PreTranslateMessage来过滤F5键盘消息,而不是实现IDocHostUIHandler::TranslateAccelerator。 在脚本中调用应用程序对浏览器控件的扩展,这需要实现IDocHostUIHandler::GetExternal。使用.Net的WebBrowser控件的话设置ObjectForScripting属性就可以了。 对于用浏览器控件来做HTML分析器的场合来说,有时需要屏蔽脚本产生的消息框。这需要实现IDocHostShowUI::ShowMessage,或者设置浏览器的Silent属性。 另外,浏览器也会查询IOleClientSite来获得其它的服务信息,例如 IOleCommandTarget,查询控件的容器是否提供替代的命令处理,见拙作Hook DHTML Commands一文(http://blog.joycode.com/jiangsheng/archive/2005/07/09/58754.aspx) IServiceProvider。此接口被用于查询用户对如下接口的实现: IInternetSecurityManager ,用户可实现此接口来自定义浏览器控件的安全相关选项(http://msdn.microsoft.com/workshop/security/szone/overview/impl_secmanager.asp) IDownloadMamanger ,用户可实现此接口来自定义浏览器控件的下载过程 IAuthenticate,用户可实现此接口来自定义一些登录界面(http://support.microsoft.com/kb/329802) INewWindowManager,用户可实现此接口来重载Windows XP SP2和Windows 2003 SP1中新增的弹出窗口管理器的行为 其他控制 对于用浏览器控件来做HTML分析器的场合来说,有时需要禁用浏览器的脚本、ActiveX或者图片下载。这可以通过在容器中实现IDispatch,处理DISPID_AMBIENT_DLCONTROL来做到(http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/overview/Overview.asp)。 看来离线浏览的控制并不能用这种方法来控制(http://support.microsoft.com/kb/247336)。不过你可以自己编写一个HTTP层传递 BINDF_OFFLINEOPERATION标志 (http://groups-beta.google.com/group/microsoft.public.inetsdk.programming.mshtml_hosting/msg/76bf4910a289d4b3) 在浏览器控件中java小程序可能不能正常运行,如果使用Sun JVM1.4之后的版本,可以用SetEnvironmentVariable 来设置JAVA_PLUGIN_WEBCONTROL_ENABLE为1来启用Sun JVM。 默认情况下在页面载入时会有点击声。屏蔽点击声的一个方法是在程序运行时修改注册表键(http://support.microsoft.com/kb/201901),另一个方法是将浏览器控件隐藏,在调用Navigate2之后再显示,但是这也需要锁定控件的更新区域(LockWindowUpdate)以避免闪烁。在IE7中,也可以调用 CoInternetSetFeatureEnabled函数,传递FEATURE_DISABLE_NAVIGATION_SOUNDS来禁用浏览时的声音。 在需要使用代理服务器时,有可能需要在应用程序中使用非默认的代理服务器设置。这可以通过调用UrlMkSetSessionOption来实现。...[阅读全文]

posted @ | Feedback (2) | Filed Under [ .Net Framework HTML编程(IE Programming) 集成开发环境(IDE) 脚本(Scripting) 类库(Library) 平台SDK(Platform SDK) ]

摘要:在计算亲和数的时候,由于涉及到密集运算,有必要把计算工作转移到背景线程,以避免界面会失去响应。在.Net 1.0中,可以用ManualResetEvent、线程和Delegate的异步调用来实现,但是在.Net 2.0中,可以使用BackgroundWorker对象来简化这个工作。这个对象自动化了进度报告和终止线程的功能。 要使用这个对象来创建工作线程,首先需要加入一个BackgroundWorker对象到表单(Form)或者用户控件(UserControl),然后调用其RunWorkerAsync方法: private: System::Void AmicableNumberView_Load(System::Object^ sender, System::EventArgs^ e) ...{ propertyGrid->SelectedObject = Range; listViewPairs->VirtualListSize=0; timer->Start(); m_rAmicableNumberPairs->Clear(); backgroundWorker->RunWorkerAsync (Range); } 在线程创建之后会自动触发DoWork事件。这个事件中的处理类似于1.1中的线程函数体,可以通过访问DoWorkEventArgs参数的argument属性来访问在用RunWorkerAsync启动线程时传递的参数,以及调用ReportProgress定时报告进度。private: System::Void backgroundWorker_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) ...{ CAmicableNumberRange range=(CAmicableNumberRange)e->Argument; int nNumbers=range.Max-range.Min; int nPercentComplete=0; m_rGenerator->Range=range; m_rGenerator->StartWork(); while(!backgroundWorker->CancellationPending && m_rGenerator->DoWork())...{ nPercentComplete = (int)( ......[阅读全文]

posted @ | Feedback (6) | Filed Under [ 用户界面 .Net Framework 类库(Library) 语言(Language) C++/CLI/Managed C++ Extension ]

摘要: 点此查看本文代码  相亲数(Amicable Pair),又称亲和数、友爱数,指两个正整数中,彼此的全部约数之和(本身除外)与另一方相等。 例如220与284: 220的全部约数(除掉本身)相加是:1+2+4+5+10+11+20+22+44+55+110=284 284的全部约数(除掉284本身)相加的和是:1+2+4+71+142=220 寻找指定范围内的相亲数的一个方法如下:对于范围内的每个数,用试除法获得约数,之后求和: int GetAmicableNumber(int nNumber) ...{ int nSumDivisors = SumDivisors(nNumber); if (nSumDivisors == nNumber) return 0;//perfect number if (nNumber == SumDivisors(nSumDivisors)) return nSumDivisors; return 0; } int SumDivisors(int n) ...{ ......[阅读全文]

posted @ | Feedback (9) | Filed Under [ .Net Framework 语言(Language) C++/CLI/Managed C++ Extension ]

摘要:一个算法的优化的相关代码// Amicable.h #pragma once #include "WinFormThread.h" using namespace System; using namespace System::Collections::Generic; /**//// <summary> /// Amicable Number Generator /// Search a range for amicable pairs. /// </summary> namespace Amicable ...{ /**//// <summary> /// An amicable pair consists of two distinct integers /// for which the sum of proper divisors (the divisors excluding the number itself) ///......[阅读全文]

posted @ | Feedback (1) | Filed Under [ .Net Framework 语言(Language) C++/CLI/Managed C++ Extension ]

摘要:尽管4月份还没到,一篇MSDN杂志4月号的文章已经出来了(http://msdn.microsoft.com/msdnmag/issues/06/04/ManagedSpy)。这篇文章描述了如何使用ManagedSpyLib库来访问其他进程内的托管控件及其属性和事件。尽管这个程序的主要目的是监视,但是也可以用ManagedSpyLib库来控制其他进程内的托管控件。...[阅读全文]

posted @ | Feedback (2) | Filed Under [ .Net Framework 集成开发环境(IDE) 类库(Library) C++/CLI/Managed C++ Extension ]

摘要: 在VC.Net中使用默认设置/clr编译时,一个托管函数会产生两个入口点,一个是托管的,供托管代码调用,另外一个是非托管的,供非托管代码调用。但是函数地址,特别是虚函数指针只能有一个值,所以需要有一个默认的入口。非托管入口点可能是所有调用的默认入口(在 Visual Studio .NET2003 中,编译器总是会选择非托管入口,但是在Visual Studio 2005中,如果参数或者返回值中包含托管类型,那么编译器会选择托管入口),而另外一个只是使用托管C++中的互操作功能对默认入口的调用。在一个托管函数被另一个托管函数调用的时候,这可能会造成不必要的托管/非托管上下文切换和参数/返回值的复制。如果函数不会被非托管代码使用指针调用,那么可以在声明函数时用VC2005新增的__clrcall修饰符阻止编译器生成两个入口。现在用简单的冒泡排序算法来比较一下使用__clrcall之后的性能改善程度。 using namespace System; #define ARRAY_SIZE 1000 struct bubbleBase ...{ int value; }; class bubble1:public bubbleBase ...{ public: virtual int getvalue()...{return value;} virtual void setvalue(int newvalue)...{value=newvalue;} }; class bubble2:public bubbleBase ...{ public: virtual int __clrcall getvalue()...{return value;} virtual void __clrcall setvalue(int newvalue)...{value=newvalue;} }; template<class T> void bubbleSort(int length) ...{ TimeSpan ts; T* array1=new T[ARRAY_SIZE]; for (int i=0;i<ARRAY_SIZE ;i++) ...{ array1[i].setvalue(ARRAY_SIZE-i-1); } ......[阅读全文]

posted @ | Feedback (1) | Filed Under [ 随笔 .Net Framework 编译(CodeGen) 类库(Library) 语言(Language) C++/CLI/Managed C++ Extension ]

摘要:目前版本的VC2005测试版中,default关键字不仅用于指定类级别的索引器,而且也用于访问默认属性。但是奇怪的是,默认属性的原名不能访问了,也就是说,如果要把下面的代码段从托管C++移植到VC2005附带的C++/CLI,不仅需要更改指针的类型,而且要把属性的名称更改为default: //[System::Reflection::DefaultMemberAttribute("Fields")] interface _Recordset//托管C++语法//extern _Recordset* results;Fields* ResultFields=results->Fields;//C++/CLI语法//extern _Recordset^ results;Fields^ ResultFields=results->default; 如果继续使用原来名字来访问属性的话,会报告编译错误: Fields^ ResultFields=results->Fields;//C3293: 'Fields': use 'default' to access the default property (indexer)。 这是一个Breaking Change。在语言规范中,默认索引属性只使用一个名字“default”,而且只有这一个实现。更进一步,默认索引属性只能用如下方式访问: obj[index] obj->default[index] obj->default::get(index) obj->default::set(index, value) 顺便说一下,在C++/CLI中也可以使用类似C#里面的for each语句了( http://msdn2.microsoft.com/library/ms177202(en-us,vs.80).aspx),而且对于非托管的STL容器也有效,不过看起来真不习惯。 参考 New C++ Language Features (http://msdn2.microsoft.com/library/xey702bw(en-us,vs.80).aspx) Breaking Changes in the Visual C++ 2005 Compiler(http://msdn2.microsoft.com/library/ms177253(en-us,vs.80).aspx)...[阅读全文]

posted @ | Feedback (0) | Filed Under [ .Net Framework 编译(CodeGen) C++/CLI/Managed C++ Extension ]

摘要:个人觉得这次MVP峰会最大的进步就是技术相关的Session数量大大增加,按照MVP专长来分类;而不像上次那样按主题分类。我只需要在VC产品组的日程里面选择就可以了,而不是像上回那样不得不去听移动开发。当然这回也有MVP不去参加VC的Session,跑去听IE和移动开发。内容方面也比上次活泼很多,Don Box还是那么幽默,比尔·盖茨也有搞笑的演出,不过他看起来比去年七月份在北京的时候老多了。 一些可能有人会感兴趣的技术信息 新的产品开发合作网站http://connect.microsoft.com/。在这里可以申请参与新产品的测试。软件开发者可以使用Windows错误报告机制(Windows Error Reporting,简称WER,https://winqual.microsoft.com/parentorgs.asp)来获得反馈。 有人正在开发把VC项目转化成MSBuild的XML格式的工具 (http://blogs.msdn.com/clichten/archive/2005/06/07/Building_VC_projects_with_msbuild_and_not_using_vcbuild.aspx)。关于MSBuild的概述可以看看Christophe Nasarre的文章Overview of MSBuild (http://msdn.microsoft.com/library/en-us/dnlong/html/msbuildpart1.asp)和MSBuild Team Blog (http://blogs.msdn.com/msbuild)。还不知道这个工具是否支持VS.Net中其他语言的项目。新的代号为Phoenix的统一编译器平台也在计划中。可以加入插件来实现自定义语言的编译器 (http://blogs.msdn.com/kangsu/archive/2005/08/11/450481.aspx)。 在MFC8.0中使用Windows Forms会更加简单,加速键和Tab键的处理现在可以扔给MFC来做了 (http://blogs.msdn.com/yvesdolc/archive/2005/04/26/WindowsForms_In_MFC.aspx)。VC8.0中也会有一些新的向导,例如单元测试工程向导 (http://msdn.microsoft.com/library/en-us/dnvs05/html/vs05security.asp)。 一些建议 停止开发新的面向Win9x的程序和静态链接MFC的程序。使用新的MFC版本编译旧的程序来增加应用程序的安全性。 在新的程序中使用Unicode编码,同时尽可能将现有程序移植到Unicode。 移植到Visual C++ 2005来使用强大的编译器和调试器。 尽管限于保密协议我不能说得更多,但是微软在11月7号就会正式发布Visual Studio 2005、SQL Server 2005和BizTalk Server 2006了。新的Visual Studio版本(代号Orca和Hawaii)也正在规划中。...[阅读全文]

posted @ | Feedback (8) | Filed Under [ 用户界面 .Net Framework 集成开发环境(IDE) 类库(Library) 平台SDK(Platform SDK) 文档(Documentation) 语言(Language) ]

摘要:?MFC提供了许多十分有用的类和对象,在很多时候在Office插件、BHO、常规DLL这样的工程中加入MFC支持是一个不错的选择。但是,MFC中的很多功能,例如资源查找,消息预处理等等都依赖于在进程或者线程创建时被初始化的MFC内部数据;而对于需要添加MFC支持的工程,这些数据并不会被自动地初始化。这时候使用一些MFC的功能,例如使用CString从字符串表加载一个字符串,或者使用CDialog::DoModal()创建一个模态对话框,都会有断言错误,用ATL向导创建的支持MFC的程序也没有多少改善,在CWinApp的DLL版本中没有初始化线程数据,所以调用AfxGetThread会返回空指针。解决这个问题的一个办法是使用AfxBeginThread来启动一个MFC线程,这样MFC会初始化线程相关的数据。在下面的示例中,我在线程初始化时建立了一个模态对话框,以避免直接创建模态对话框会触发的断言失败信息。为了模拟模态对话框的效果,在CDialogThread::WaitForDoModal()这个函数中创建了一个消息循环来等待线程结束,同时用MsgWaitForMultipleObjects来避免死锁。因为MFC中和进程相关的数据并不总是被正确初始化,在调用模态对话框之前也需要手动设置一下。 //如果这段代码可以工作,那么它的作者是Jiangsheng //否则我不知道它的作者 void __stdcall CFrontPageAddin::OnClickButtonExportCHM(IDispatch* /*Office::_CommandBarButton* */ Ctrl,VARIANT_BOOL * CancelDefault) { AtlTrace(_T(" CFPAnt::OnClickButtonExportCHM\n")); //create a thread to avoid assert failure CDialogThread* pDialogThread= (CDialogThread*)AfxBeginThread(RUNTIME_CLASS(CDialogThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED,NULL); if(pDialogThread) { pDialogThread->m_prc=RUNTIME_CLASS(CExportCHMSheet); pDialogThread->ResumeThread(); pDialogThread->WaitForDoModal(); ......[阅读全文]

posted @ | Feedback (1) | Filed Under [ 用户界面 .Net Framework 类库(Library) ]

摘要:使用WinDbg调试VC程序 虽然在VC6.0中可以通过安装Visual C++ Toolkit(网站:http://msdn.microsoft.com/visualc/vctoolkit2003/)来编写基于最新版本的平台SDK、DirectX SDK的程序以及托管代码,但是VC6附带的调试器并不支持新版本的调试信息,所以实际上是不能用VC6来调试新版本编译器生成的程序的。一个替代的解决方案是使用新版本的Windows调试工具Windbg(网站:http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx)。Windbg的调试功能基本和Visual C++中的相同,但是需要手动设定源文件和调试符号文件的搜索路径(可以参考VC6.0中的对应设置)。一些代码,例如MFC的代码比较难于定位,这时可以双击调用堆栈中的函数名称来打开文件并定位到函数所在位置。Windbg可以进行有限的托管代码调试,但是调试过程比较麻烦。在没有安装Visual Studio的计算机上调试,例如进行远程调试的时候可能还需要部署调试符号(Generating and Deploying Debug Symbols With Visual C++ 6.0)。 调试Visual Studio .Net 的程序需要用户是管理员或者"Debug User"用户组成员。如果登录用户不是该组成员,那么也可以用WinDbg来调试程序。...[阅读全文]

posted @ | Feedback (2) | Filed Under [ 随笔 .Net Framework 安全和管理(Security and Management) 调试技巧(Debugging) 工具(Tools) 集成开发环境(IDE) 类库(Library) 平台SDK(Platform SDK) 文档(Documentation) 语言(Language) C++/CLI/Managed C++ Extension ]

Full .Net Framework Archive