内容来至(http://blog.csdn.net/dadaadao/rss/list)
dadaadao的专栏 | ![]() |
[转]Win7x64+VS2012+OpenCV2.4.3+CMake2.8.10+TBB41重编译OpenCV |
PS:请参考最新的《Opencv 完美配置攻略 2014 (Win8.1 + Opencv 2.4.8 + VS 2013)》,绝对给力!由于Opencv版本升级,大多人开始用新版本VS,等等,这篇已经过时了,而且当时没有在文中加入更合适的简介的配置方法,所以有一些东西不再适用。重写一篇,,无论是Win7还是Win8,无论是VS2010, VS2012, 还是VS2013,无论是Opencv 2.x.x,方法都是一样的,只是配置思路和操作流程不同而已。 如果想重新编译Opencv,可以参考本文,不过新版本也许不用配置ttb了吧,没试过。如果有需求再玩玩自己编译的。
posted @ 2013-01-11 19:54 from [FreedomShe]
重编译的好处:可以调试的时候看OpenCV的源代码。 重编译要得到的东西:Debug版本和Release版本的dll,lib,头文件。(dll添加到环境变量里,运行时用,自己编译的dll调试时可以跟踪到Opencv的源码内;lib和头文件配置到编译器里) PS:如果只是使用Opencv而不需要跟踪源码,则使用Opencv自带的库文件即可。跳到5配置Opencv开发环境,对应的文件都在..opencvuild目录下,其中dll(bin目录),lib目录在平台文件夹下如..opencvuild x86vc10。 本机Win7 64位系统,装有VS2012,以编译32位的Opencv库为例,要编译64位库需要注意选择64位的配置。 下载OpenCV2.4.3:http://opencv.org/downloads.html,解压到D:Program Files 下载CMake2.8.10:http://www.cmake.org/cmake/resources/software.html,安装 下载tbb41_20121003oss:http://threadingbuildingblocks.org/download,解压到D:Program Files Path里添加:D:Program Files bb41_20121003ossinia32vc11 bin目录内ia32表示要编译32位工程,intel64表示要编译64位工程,vc11表示VS版本为2012 新建文件夹OpenCVProject:D:Program FilesOpenCVProject(用于存放自己的OpenCV编译工程)。 打开CMake,"Browse Source..."选择Opencv的目录D:/Program Files/opencv(内有CMake的组态档"CMakeLists.txt"),"Browse Build..."选择刚才自己新建的工程存放路径"D:Program FilesOpenCVProject"。点击Configure按钮,在出现的对话框中选择Visual Studio 11(如果编译64位dll注意选择64位VS11配置),默认Use default native compilers,Finish继续。
稍等片刻出现该图 第一轮配置完后往下拉,勾选WITH_TBB,点击Configure进入第二轮。
修改红色部分TBB路径为D:/Program Files/tbb41_20121003oss/include,再次点击Configure;继续点击Configure,直到没有红色标记。
点击Generate生成Opencv工程,退出CMake。 打开生成的Opencv工程,选择CMakeTargets下INSTALL,右键“生成”,生成Debug版dll,lib。
切换编译模式为Release模式,重复上一步生成Release版dll,lib。
上面两步后就能看到最终Debug版和Release版的dll,lib,以及文档目录doc,头文件目录include(bin内为两个版本dll,lib内为两个版本lib)。
目标达成,在D:Program FilesOpenCVProjectinstall内有我们所要的dll,lib,include头文件,有了这些就可以进行Opencv开发与源码跟踪了。跟dll关联的源代码在Opencv安装目录D:Program Filesopencvmodules内。 我习惯将将D:Program FilesOpenCVProjectinstall拷贝到D:Program Filesopencv下,并将install重命名为vc11x86。而此时D:Program FilesOpenCVProject没有用了,但是不能删除,否则无法跟踪源码,占用6G多空间,可以通过VS2012的“清理解决方案”来减到3G多。 在环境变量Path里添加:D:Program Filesopencvvc11x86in。 6.1 打开VS2012,新建控制台应用程序TestOpencv。6.2 配置包含目录和库目录项目->xxx属性->VC++目录->包含目录,添加D:Program Filesopencvvc11x86include 项目->xxx属性->VC++目录->库目录,添加D:Program Filesopencvvc11x86lib
项目->xxx属性->链接器->输入->附加依赖项,添加lib文件名列表如下图。
对于配置方案为Debug的配置,添加: opencv_calib3d243d.libopencv_contrib243d.libopencv_core243d.libopencv_features2d243d.libopencv_flann243d.libopencv_gpu243d.libopencv_highgui243d.libopencv_imgproc243d.libopencv_legacy243d.libopencv_ml243d.libopencv_nonfree243d.libopencv_objdetect243d.libopencv_photo243d.libopencv_stitching243d.libopencv_ts243d.libopencv_video243d.libopencv_videostab243d.lib 对于Release配置,添加 opencv_calib3d243.libopencv_contrib243.libopencv_core243.libopencv_features2d243.libopencv_flann243.libopencv_gpu243.libopencv_highgui243.libopencv_imgproc243.libopencv_legacy243.libopencv_ml243.libopencv_nonfree243.libopencv_objdetect243.libopencv_photo243.libopencv_stitching243.libopencv_ts243.libopencv_video243.libopencv_videostab243.lib
Opencv的dll和lib中,末尾带d的就是Debug版本。 6.3 添加测试代码修改TestOpencv.cpp,代码为: ![]() #include "stdafx.h"#include <opencv2opencv.hpp>using namespace cv;using namespace std;int main(){ Mat img = imread("c:/pp.jpg"); if(img.empty()) { cout<<"error"; return -1; } imshow("pp的靓照",img); waitKey(); return 0;} ![]()
将要显示的图片保存为c:/pp.jpg,编译运行,显示出图片。
通过设置断点发现,能够跟踪进入Opencv内部函数。 作者:dadaadao 发表于2014/11/5 15:52:35 原文链接 阅读:453 评论:1 查看评论 |
[转]Win32 编程入门 |
Win32 程序开发的流程
message based, event drivenWin32程序是message based, event driven。也就是说Win32程序的运行是依靠外部不断发生的事件来驱动的,也就是说,程序不断等待(有一个while循环),等待任何可能的输入,然后做判断,再做适当的处理。因此Win32程序只需要做好如下几件事情就可以了: 1. 定义窗口的外观; 2. 定义当不同的事件发生时,程序做什么样的反应(定义窗口处理函数); 3. 写一个While循环,不断检测新事件的发生,并将其发送给不同的窗口处理函数
程序进入点WinMainmain是一般C程序的进入点:int main( int argc, char *argv[], char *envp[]) Win32程序的进入点是 int CALLBACK WinMain( __in HINSTANCE hInstance, __in HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nCmdShow); 当用户要执行一个程序时,首先是Windows 的Shell(Explorer)调用CreateProcess这个系统调用,CreateProcess为这个进程创建虚拟地址,然后将代码和数据载入,然后系统再创建一个主线程开始执行run time startup函数的代码,run time startup 函数会最终调用入口点函数(main, WinMain)。如果用户执行的是一个Win32程序,那么C startup就会调用WinMain并开始执行程序。 窗口类注册与窗口诞生如果前面所说,Win32的一个重要的责任是定义窗口外观和窗口处理函数。这是通过窗口类注册来完成的。创建窗口可以使用CreateWindow来完成,但在调用CreateWindow时必须先设定窗口的各种属性和行为。设定窗口属性和行为是通过API 函数 RegisterClass 来完成的。RegisterClass需要一个大型数据结构WNDCLASS,窗口的属性和行为就是在这个数据结构中指定的。 ATOM WINAPI RegisterClass( __in const WNDCLASS *lpWndClass); 下面是数据结构WNDCLASS的定义: typedef struct tagWNDCLASS {
消息循环是怎么工作的应用程序可以获得的输入有两种类型:硬件装置产生的消息房子系统队列中、由Windows系统或者其他Windows程序传送过来的消息,放在程序队列中。以应用程序的眼光来看,消息就是消息,来自哪里或放在哪里没有太大区别,程序每次GetMessage就取得一个消息。 每个窗口都应该有一个函数负责处理消息,程序员必须负责设计这个所谓的窗口函数(Window Procedure),如果窗口获得一个消息,则这个窗口必须判断消息的类别,决定处理方式。下面是主消息循环的例子: // Main message loop: GetMessage的原型: BOOL WINAPI GetMessage( __out LPMSG lpMsg, __in_opt HWND hWnd, __in UINT wMsgFilterMin, __in UINT wMsgFilterMax); 从调用线程的消息队列中获取一个消息,这个函数会一直等到有一个可用的Message时才会返回; int WINAPI TranslateAccelerator( __in HWND hWnd, __in HACCEL hAccTable, __in LPMSG lpMsg); 该函数处理菜单命令中的加速键。该函数将一个WM_KEYDOWN或WM_SYSKEYDOWN消息翻译成一个WM_COMMAND或WM_SYSCOMMAND消息(如果在给定的加速键表中有该键的入口),然后将WM_COMMAND或WM_SYSCOMMAND消息直接送到相应的窗口处理过程。 TranslateMessage是用来把虚拟键消息转换为字符消息。由于Windows对所有键盘编码都是采用虚拟键的定义,这样当按键按下时,并不得字符消息,需要键盘映射转换为字符的消息。
windows消息处理机制是这样的: 其实问题的关键在于DispatchMessage到底干了什么 GetMessage: 从线程的消息队列取出一个消息 TranslateMessage是对一些键盘事件做预处理。GetMessage是从系统为每个应用程序自动分配的消息对列的头部得到一个消息。 TranslateMessage是翻译需要翻译的消息 DispatchMessage()则会把翻译好的消息发送到系统的消息处理函数中,而这个函数又会把这个消息传 递到注册窗体时用户指定的消息处理函数中翻译消息不是简单的转换,一个消息被翻译后,可能会产生几个消息。 作者:dadaadao 发表于2014/2/28 10:50:40 原文链接 阅读:294 评论:0 查看评论 |
[转]Activex、OLE、COM、OCX、DLL之间的区别(转 |
熟悉面向对象编程和网络编程的人一定对ActiveX、OLE和COM/DCOM这些概念不会陌生,但是它们之间究竟是什么样的关系,对许多们还是比较模糊的。在具体介绍它们的关系之间,我们还是先明确组件(Component)和对象(Object)之间的区别。 组件是一个可重用的模块,它是由一组处理过程、数据封装和用户接口组成的业务对象(Rules Object)。组件看起来像对象,但不符合对象的学术定义。 它们的主要区别是: 到这里,已经出现了与本文相关的主题COM,而CORBA与本文无关,就不作介绍。 之所以从组件与对象的区别说起,是想让大家明确COM和 CORBA是处在整个体系结构的最底层,如果暂时对此还不能理解,不妨继续往下看,最后在回过头看一看就自然明白了。 现在开始阐述ActiveX、OLE和COM的关系。首先,让大家有一个总体的概念,从时间的角度讲,OLE是最早出现的,然后是COM和ActiveX;从体系结构角度讲,OLE和ActiveX是建立在 COM之上的,所以COM是基础;单从名称角度讲,OLE、ActiveX是两个商标名称,而COM则是一个纯技术名词,这也是大家更多的听说ActiveX和OLE的原因。 既然OLE是最早出现的,那么就从OLE说起,自从Windows操作系统流行以来,“剪贴板”( Clipboard)首先解决了不同程序间的通信问题(由剪贴板作为数据交换中心,进行复制、粘贴的操作),但是剪贴板传递的都是“死”数据,应用程序开发者得自行编写、解析数据格式的代码,于是动态数据交换(Dynamic Data Exchange,DDE)的通信协定应运而生,它可以让应用程序之间自动获取彼此的最新数据,但是,解决彼此之间的“数据格式”转换仍然是程序员沉重的负担。 对象的链接与嵌入(Object Linking and Embedded,OLE)的诞生把原来应用程序的数据交换提高到“对象交换”,这样程序间不但获得数据也同样获得彼此的应用程序对象,并且可以直接使用彼此的数据内容,其实OLE是Microsoft的复合文档技术,它的最初版本只是瞄准复合文档,但在后续版本OLE2中,导入了COM。 由此可见,COM是应OLE的需求而诞生的,所以虽然COM是OLE的基础,但OLE的产生却在COM之前。 COM的基本出发点是,让某个软件通过一个通用的机构为另一个软件提供服务。COM是应OLE 的需求而诞生,但它的第一个使用者却是OLE2,所以COM与复合文档间并没有多大的关系,实际上,后来COM就作为与复合文档完全无关的技术,开始被广泛应用。 这样一来, Microsoft就开始“染指”通用平台技术。但是COM并不是产品,它需要一个商标名称。而那时Microsoft的市场专家们已经选用了OLE作为商标名称,所以使用COM技术的都开始贴上了 OLE的标签。虽然这些技术中的绝大多数与复合文档没有关系。Microsoft的这一做法让人产生这样一个误解OLE是仅指复合文档呢?还是不单单指复合文档?其实OLE是COM的商标名称,自然不仅仅指复合文档。但Microsoft自己恐怕无法解释清楚,这要花费相当的精力和时间。 于是,随着Internet的发展,在1996年春,Microsoft改变了主意,选择ActiveX作为新的商标名称。ActiveX是指宽松定义的、基于COM的技术集合,而OLE仍然仅指复合文档。当然, ActiveX最核心的技术还是COM。 ActiveX和OLE的最大不同在于,OLE针对的是桌面上应用软件和文件之间的集成,而ActiveX则以提供进一步的网络应用与用户交互为主。到这里,大家应该对ActiveX、OLE和COM三者的关系有了一个比较明确的认识,COM才是最根本的核心技术,所以下面的重点介绍COM。 让对象模型完全独立于编程语言,这是一个非常新奇的思想。这一点从C++和Java的对象概念上,我们就能有所了解。但所谓COM对象究竟是什么呢?为了便于理解,可以把COM看作是某种(软件)打包技术,即把它看作是软件的不同部分,按照一定的面向对象的形式,组合成可以交互的过程和以组支持库。 COM对象可以用C++、Java和VB等任意一种语言编写,并可以用DLL或作为不同过程工作的执行文件的形式来实现。使用COM对象的浏览器,无需关心对象是用什么语言写的,也无须关心它是以DLL还是以另外的过程来执行的。从浏览器端看,无任何区别。这样一个通用的处理技巧非常有用。例如,由用户协调运行的两个应用,可以将它们的共同作业部分作为COM对象间的交互来实现(当然,现在的OLE复合文档也能做到)。为在浏览器中执行从Web服务器下载的代码,浏览器可把它看作是COM对象,也就是说,COM技术也是一种打包可下载代码的标准方法(ActiveX控件就是执行这种功能的)。甚至连应用与本机OS进行交互的方法也可以用COM来指定,例如在Windows和Windows NT中用的是新API,多数是作为COM对象来定义的。可见,COM虽然起源于复合文档,但却可有效地适用于许多软件问题,它毕竟是处在底层的基础技术。用一句话来说,COM是独立于语言的组件体系结构,可以让组件间相互通信。 随着计算机网络的发展,COM进一步发展为分布式组件对象模型,这就是DCOM,它类似于CORBA的ORB,本文对此将不再做进一步的阐述。通过上面的讲述相信大家一定对ActiveX、OLE和COM/DCOM的关系有了一个清楚的了解。 使用Windows的人对于ActiveX控制一定不会陌生,它提供了一种类似于DLL动态链接库的调用,不过它与DLL的唯一区别就是ActiveX不注册不能被系统识别并使用。那么,当我们得到一个ActiveX没有被正确安装且不能使用的消息后,又要安装ActiveX怎么办呢? 1.Regsvr32程序法在Windows的System文件夹下有一个regsvr32.exe的程序,它就是Windows自己带的ActiveX注册和反注册工具。利用它也能够非常方便地注册AcitveX控件,它的用法为:regsvr32/u/s/n/idllname,dllname其中dllname为ActiveX控件文件名,建议在安装前拷贝到System文件夹下参数有如下意义: 例如笔者要注册一amovie.ocx控件,则打入 regsvr32 amovie.ocx即可,要反注册它时只需使用regsvr32 /u amovie.ocx就行了。 2.注册表法所谓注册AcitveX,无非是将一些信息记录在Windows的注册表中,如ShockwaveFlashObject控件,我们可以运行Regedit.exe注册表编辑程序,利用关键字进行搜索,然后把搜索得到后的注册表导出为一REG注册表文件,再将其相应的ActiveX文件拷贝到Windows的System文件夹(一般ActiveX的文件名为OCX,安装在Windows的System文件夹内)下,最后在要安装ActiveX的机器上双击导入刚才导出的注册表文件即可完成安装。 |
[转]classView不显示已存在的类向导 |
最近在做一个VC++程序,在做的过程中出现一个问题:视图类明明存在可是在ClassView中竟然没有类的相关信息,这是怎么回事呢,网上查资料,原来是vc++ 6.0的一个非常经典的bug. 解决:打开工程所在项目----->找到一个以.ncb结尾的文件,将其删除----->再次打开工程----->看到完整的类信息了----->解决。 注: NCB是 “No Compile Browser”的缩写,其中存放了供ClassView、WizardBar和Component Gallery使用的信息,由VC开发环境自动生成。无编译浏览文件。当自动完成功能出问题时可以删除此文件。编译工程后会自动生成。 作者:dadaadao 发表于2012/7/13 10:41:43 原文链接 阅读:372 评论:0 查看评论 |
[转]mfc的CDialogBar |
一、创建DialogBar的派生类
首先,创建对话框资源:在对话框资源编辑器内生成一个Dialog资源,并将其风格(Style)属性必须设置为Child,不能设置为Overlapped或Popup,否则运行肯定出错;至于边界属性则随用户自己喜欢,一般都是选择None。其余属性也随用户选择,一般没有特殊要求还是选择默认的好。
其次,创建基于CDialog的派生类:打开ClassWizard,为以上创建的资源添加一个以CDialog为基类的派生类(因为ClassWizard没有将CDialogBar列在基类目录清单中,所以用户只能先以CDialog类派生)。
再次,修改派生类以CDialogBar为基类:通常需要手工修改几处代码,在本例中派生类以CDataStatus命名。(注:以后讲解中凡是手工改动都是以灰背景显示)
1、 在头文件中修改继承关系
将class CDataStatus : public CDialog 改为class CDataStatus : public CDialogBar
2、 在代码文件中修该构造函数继承关系
将CDataStatus::CDataStatus(CWnd* pParent /*=NULL*/)
: CDialog(CDataStatus::IDD, pParent)
{
//{{AFX_DATA_INIT(CDataStatus)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
改为
CDataStatus::CDataStatus(CWnd* pParent /*=NULL*/) { //{{AFX_DATA_INIT(CDataStatus) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT } 3、 将DDX绑定函数中的继承关系去掉 即将void CDataStatus::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CCurrentCheckDlg) ……….. //}}AFX_DATA_MAP } 改为 void CDataStatus::DoDataExchange(CDataExchange* pDX) { //{{AFX_DATA_MAP(CCurrentCheckDlg) …………. //}}AFX_DATA_MAP } 4、 重新初始化函数(这个相当重要,如果不这么做的话,DDX函数形同虚设,当然用户的工具条如果没有用到DDX的话当然可以不加这段代码): 首先在ClassWizard的MessageMap中对消息该CDataStatus类的WM_INITDIALOG消息添加处理函数默认名为OnInitDialog。 其次手工修改代码如下: 1、 添加消息映射函数。由于对话框形式的初始化函数消息并未加载到消息映射内,为此我们需要手工添加,要不然代码无法拦截该工具条的初始化消息,形式如下: 将BEGIN_MESSAGE_MAP(CDataStatus, CDialogBar) //{{AFX_MSG_MAP(CDataStatus) ....... //}}AFX_MSG_MAP END_MESSAGE_MAP() 改为: BEGIN_MESSAGE_MAP(CDataStatus, CDialogBar) //{{AFX_MSG_MAP(CDataStatus) ....... ON_MESSAGE(WM_INITDIALOG,OnInitDialog) //}}AFX_MSG_MAP END_MESSAGE_MAP() 2、 修改OnInitDialog函数,此函数并未传递参数,但是在这里我们需要让它传递参数,代码如下修改(当然头文件中,对声明也要做修改,在这里就不作赘述了) 将BOOL CDataStatus::OnInitDialog() { CDialogBar::OnInitDialog(); // TODO: Add extra initialization here return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } 改为: BOOL CDataStatus::OnInitDialog(UINT wParam,LONG lParam) { //CDialogBar::OnInitDialog(); // TODO: Add extra initialization here BOOL bRet = HandleInitDialog(wParam,lParam); if (!UpdateData(FALSE)) { TRACE("InitCDataStatus Failed!"); } return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } 二、在框架类中实现该派生类的对象化 首先,在框架类的头文件内声明实例对象,本例实例化:CDataStatus m_wndDataStatus;当然头文件中不可避免要包含新派生类的头文件。 其次,在框架类的OnCreate函数内创建对象并将对象绑定对话框资源。形式与创建ToolBar原理一样,本例实例如下: if (!m_wndDataStatus.Create(this,IDD_DATASTATUS,WS_VISIBLE|WS_CHILD |CBRS_SIZE_DYNAMIC|CBRS_BOTTOM,IDD_DATASTATUS)) { TRACE0("Failed to create CDataStatus bar!"); return -1; } 再次,最为关键的一点就是重写框架类的OnCmdMsg虚函数。如果不重写该函数,那么不光DDX功能无法实现,连最基本的OnCommand事件都无法实现。而且还得手工添加代码,形式如下: BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) { // TODO: Add your specialized code here and/or call the base class return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); } 改为: BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) { // TODO: Add your specialized code here and/or call the base class if (m_wndDataStatus.OnCmdMsg(nID,nCode,pExtra,pHandlerInfo)) return TRUE; return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); } 步骤1:添加一个CDialogBar派生类 在资源中添加一个对话框,再采用类向导来添加类,找不到CDialogBar作为基类吧,可以先用CDialog作为基类产生一个,然后把所以的“CDialog”替换为“CDialogBar”,替换完成了。编译一下,^_^有错误吧!!请看步骤2。 步骤2:解决编译错误并完善该类 其实错误就是构着函数调用基类时有问题,: CDialogBar(/*CDlgBar::IDD, pParent*/)象这样注释掉就可以了,添加一个类似OnInitDialog的函数,在CDialogBar中是不存在OnInitDialog的消息的,至少我还不知道,因为初始化是在创建后调用的所以我们就重写virtual BOOL Create(CWnd* pParentWnd,UINT nIDTemplate,UINT nStyle,UINT nID);这个函数。注意哦用向导添加的Create函数的参数是不对的喔,看上面。下面是实现代码(很简单的) BOOL CDlgXXX::Create(CWnd* pParentWnd,UINT nIDTemplate,UINT nStyle,UINT nID) { // TODO: Add your specialized code here and/or call the base class BOOL bRes= CDialogBar::Create(pParentWnd,nIDTemplate,nStyle,nID ); InitDialogBar();//在类中添加一个成员函数就可以了 return bRes; } BOOL CDlgXXX::InitDialogBar() { UpdateData(FALSE);//这个一定要啊,这样就会有和CDialog一样的数据交换效果了 return TRUE; } 步骤3:创建和使用 if (!m_barAttrib.Create(this,IDD_DLG_COM_ATTRIB, CBRS_RIGHT|CBRS_GRIPPER, XXX)) { TRACE0("Failed to create dialogbar "); return -1; } m_barAttrib.SetWindowText("部件属性"); XXX是一个资源id手工直接在资源的.h文件中添加一条,不会,这里就不教了 ![]() 工具条的显示和隐藏代码如下,自己慢慢理解吧: ShowControlBar(&m_barAttrib, (m_barAttrib.GetStyle() & WS_VISIBLE) == 0, FALSE); 上面代码实现后DoDataExchange也是可以用,给控件添加控件就和CDialog一样的方便咯 但是还有一个要注意的是就是控件类对象的添加,我试了一下好像不行,窗口句柄好像 总是0的,不能使用。还是使用GetDlgItem(IDC_DRIVER_LIST)来取得控件指针吧。 其他方面的心得 利用DoDataExchange来控制自定义的输入格式控制这里就举一个文本框的例子 给文本控件添加完变量后就在DoDataExchange会出现如下代码 DDX_Text(pDX, IDC_COM_VAR, m_strVar);//系统产生的 DDV_MaxChars(pDX, m_strVar,VAR_MAX_LEN);//加入长度控制后产生的 DDV_FileNameString(pDX, m_strVar);//自定义的手工添加的实现见下面 void CXXX::DDV_FileNameString(CDataExchange *pDX, CString m_strFileName) { CString strError=_T("\/:*?"<>|"); if(m_strFileName.SpanExcluding(strError) != m_strFileName) { ::AfxMessageBox(_T("文件名中不能包含"+strError+"字符")); pDX->Fail();//关键是这句执行这句后就会抛出异常下面的语句就不执行了 } } 还有几个注意点是 1.只有执行了UpdateData()才会调用DoDataExchange函数若中途 执行了pDX->Fail(); UpdateData()就返回FALSE。 2. DDX_Text(pDX, IDC_COM_VAR, m_strVar);//系统产生的 DDV_MaxChars(pDX, m_strVar,VAR_MAX_LEN);//加入长度控制后产生的 DDV_FileNameString(pDX, m_strVar);//自定义的手工添加的实现见下面 如上面几句都是对一个控件的内容的控制,他们必须放在一块,且DDX_Text要放在第一句,这样在界面上就可以正确的指出那个控件的内容有问题,控件会被设置焦点并选中全部内容。 如果你想实现有工具条的浮动和定位功能,而且可以方便的摆放任何控件上去,那就使用CDialogBar就可以拥有和CDialog一样的方便和快捷。 想在CDialogBar上添加按钮消息还需要修改如下: 这里增加一条关于对话框上响应键盘按键消息,重载 // TODO: Add a menu item that will toggle the visibility of the // TODO: Change the value of CG_ID_VIEW_IMAGESINDB to an appropriate value: CG_IDD_IMAGESINDB为对话框的名字 CListCtrl* pList = (CListCtrl*)m_wndImagesInDB.GetDlgItem(IDC_LIST1); VERIFY(pList); 做一个关联就可以了 作者:dadaadao 发表于2012/7/11 12:49:13 原文链接 阅读:2602 评论:0 查看评论 |
[转]【引用】关于图像特征提取 |
本文引用自yuweiisme《关于图像特征提取》
网上发现一篇不错的文章,是关于图像特征提取的,给自己做的项目有点类似,发出来供大家参考。 特征提取是计算机视觉和图像处理中的一个概念。它指的是使用计算机提取图像信息,决定每个图像的点是否属于一个图像特征。特征提取的结果是把图像上的点分为不同的子集,这些子集往往属于孤立的点、连续的曲线或者连续的区域。 声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
copyright © 2008-2019 亿联网络 版权所有 备案号:粤ICP备14031511号-2
|