Error

C++博客 首页 新随笔 联系 聚合 管理
  217 Posts :: 61 Stories :: 32 Comments :: 0 Trackbacks

#

// boost_singal_solt.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <boost/signals2.hpp>
class CTarget /*: public boost::signals2::trackable*/
{
public:
    virtual ~CTarget()
    {
        std::cout << __FUNCTION__ << std::endl;
    }
    CTarget()
    {
        m_strMsg = "1343rwkjdfkjdfasdklf";
    }
    void SomeHandle()
    {
        std::cout << __FUNCTION__ << std::endl;
        std::cout << m_strMsg << std::endl;
    }
    void SomeHandle1()
    {
        std::cout << __FUNCTION__ << std::endl;
    }
private:
    std::string m_strMsg;
};
class CSource
{
public:
    boost::signals2::connection Connect(const boost::signals2::signal<void(void)>::slot_type &sub)
    {
        return m_sig.connect(sub);
    }
    void OnSig()
    {
        m_sig();
    }
private:
    boost::signals2::signal<void(void)> m_sig;
};
int _tmain(int argc, _TCHAR* argv[])
{
    CSource source;
    boost::signals2::connection conn;
    {
        CTarget target;
        
        /*conn = */source.Connect(boost::bind(&CTarget::SomeHandle, &target));
        source.Connect(boost::bind(&CTarget::SomeHandle1, &target));
        source.OnSig();
    }
    source.OnSig();
return 0;
}


在继承boost::signals2::trackable的情况下,Target析构以后不会调用,但是不继承是会调用的。也就是说,这是一个危险操作,不知道内部怎么管理的,会不会出现内存泄漏?
/////////////////////////////////////////////////////////////////////////////


// boost_singal_solt.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <boost/signals2.hpp>
class CSource
{
public:
    boost::signals2::connection Connect(const boost::signals2::signal<void(void)>::slot_type &sub)
    {
        return m_sig.connect(sub);
    }
    void OnSig()
    {
        m_sig();
    }
private:
    boost::signals2::signal<void(void)> m_sig;
};
class CTarget : public boost::signals2::trackable
{
public:
    virtual ~CTarget()
    {
        std::cout << __FUNCTION__ << std::endl;
        m_con.disconnect();
    }
    CTarget()
    {
        m_strMsg = "1343rwkjdfkjdfasdklf";
    }
    void RegisterSolts(CSource& source)
    {
        m_con = source.Connect(boost::bind(&CTarget::SomeHandle, this));
    }
    void SomeHandle()
    {
        std::cout << __FUNCTION__ << std::endl;
        std::cout << m_strMsg << std::endl;
    }
    void SomeHandle1()
    {
        std::cout << __FUNCTION__ << std::endl;
    }
private:
    std::string m_strMsg;
    boost::signals2::connection m_con;
};
int _tmain(int argc, _TCHAR* argv[])
{
    CSource source;
    boost::signals2::connection conn;
    {
        CTarget target;
        
        target.RegisterSolts(source);
        //source.OnSig();
    }
    source.OnSig();
return 0;
}
确认只要维护好connection在对象target析构以后一定是disconnect应该就OK没事,,,





///////////////////////////////////////////


整体上看来是这样:
问题:target的成员函数和this指针打包注册到source上以后,如果target析构,source无法感知到,可能会调用已经成为野指针的target地址。
解决:signals2库的解决办法是,用一个connection来维护打包的target成员函数和source上的signal的连接关系。target持有这个connection,当自身析构的时候必须调用disscontion解除这个关系。

如果要抄袭,也是要设计一种机制,在target析构的时候,想办法清除它在别处注册的函数指针。
1.可以建立target到source的关系,target析构以后通知source,souce清理自身保留的target相关打包函数。这种方式在使用boost bind的时候可能就有问题了,应为之依靠target指针去判断bind出来的function有难度。
2.建立关系的时候就将解除关系的函数打包到一个新的对象中,然后由target负责在自己析构的时候去调用它。

!!!如果source先于target析构,就悲剧了。但是实际情况是,如果source已经析构了,也无法触发target绑定的函数了。但问题是,target析构的时候还是去触发source绑定到target的解除关系的函数。悲催。但是实际测试这个问题不存在,估计是用类似weak_ptr的技术。
在完全理解之前,务必保证source生命周期大于target
// boost_singal_solt.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <boost/signals2.hpp>
class CSource
{
public:
    boost::signals2::connection Connect(const boost::signals2::signal<void(void)>::slot_type &sub)
    {
        return m_sig.connect(sub);
    }
    void OnSig()
    {
        m_sig();
    }
private:
    boost::signals2::signal<void(void)> m_sig;
};
class CTarget : public boost::signals2::trackable
{
public:
    virtual ~CTarget()
    {
        //std::cout << __FUNCTION__ << std::endl;
        m_con.disconnect();
    }
    CTarget()
    {
        m_strMsg = "1343rwkjdfkjdfasdklf";
    }
    void RegisterSolts(CSource& source)
    {
        m_con = source.Connect(boost::bind(&CTarget::SomeHandle, this));
    }
    void SomeHandle()
    {
        std::cout << __FUNCTION__ << std::endl;
        std::cout << m_strMsg << std::endl;
    }
    void SomeHandle1()
    {
        std::cout << __FUNCTION__ << std::endl;
    }
private:
    std::string m_strMsg;
    boost::signals2::connection m_con;
};
int _tmain(int argc, _TCHAR* argv[])
{
    for (;;)
    {
        CSource* pSource = new CSource;
        boost::signals2::connection conn;
        CTarget* pTarget = new CTarget;
        pTarget->RegisterSolts(*pSource);
        delete pSource;
        delete pTarget;
    }
    //source.OnSig();
return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

没有完全读明白之前,在需要7×24运行的环境还是慎重使用。不过客户端貌似无所谓,,,囧。
posted @ 2014-05-30 01:09 Enic 阅读(776) | 评论 (0)编辑 收藏

外部lib
add_library(baz STATIC IMPORTED) set_target_properties(baz PROPERTIES IMPORTED_LOCATION_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/libbaz.a IMPORTED_LOCATION_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/libbazd.a) add_library(bar STATIC IMPORTED) set_target_properties(bar PROPERTIES IMPORTED_LOCATION_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/libbar.a IMPORTED_LOCATION_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/libbard.a IMPORTED_LINK_INTERFACE_LIBRARIES baz) # <-- dependency is here

注意动态库和静态库稍有区别:
 add_library(bar SHARED IMPORTED)
 set_property(TARGET bar PROPERTY IMPORTED_LOCATION c:/path/to/bar.dll)
 set_property(TARGET bar PROPERTY IMPORTED_IMPLIB c:/path/to/bar.lib)
 add_executable(myexe src1.c src2.c)
 target_link_libraries(myexe bar)


内部lib直接写target name就OK,但是必须在同一个proj下

还有一种方式
TARGET_LINK_LIBRARIES(skiaSampleCode 
debug skiaCored.lib
        optimized skiaCore.lib)



PROJECT_SOURCE_DIR  CMAKE_CURRENT_SOURCE_DIR  CMAKE_SOURCE_DIR 注意这三者的区别
posted @ 2014-05-15 23:40 Enic 阅读(8344) | 评论 (0)编辑 收藏

实际起作用的是WS_EX_TOPMOST属性,添加这个属性的方式有三种:
1.在Create阶段的Ex参数添加
2.在创建完成后通过SetWindowLongPtr添加(SetWindowLong已经不建议使用)。但是我用的时候发现加不上,好像ModifyWindowStyle这个MFC的函数可以,,,
3.通过
::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);添加

::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
//SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, 
// GetWindowLongPtr(m_hWnd, GWL_EXSTYLE) | WS_EX_TOPMOST);
posted @ 2014-04-24 15:42 Enic 阅读(292) | 评论 (0)编辑 收藏

Q1:什么是 DOM?
DOM 是 W3C(万维网联盟)的标准。
DOM 定义了访问 HTML 和 XML 文档的标准:
W3C DOM 标准被分为 3 个不同的部分:
核心 DOM - 针对任何结构化文档的标准模型
XML DOM - 针对 XML 文档的标准模型
HTML DOM - 针对 HTML 文档的标准模型
Q2:什么是 XML DOM?
XML DOM 定义了所有 XML 元素的对象和属性,以及访问它们的方法。
Q3:什么是 HTML DOM?
HTML DOM 是:
HTML 的标准对象模型
HTML 的标准编程接口
HTML DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。
换言之,HTML DOM 是关于如何获取、修改、添加或删除 HTML 元素的标准。
Q4:DOM标准与IE的html事件模型区别
先有事件,事件是在浏览器内部自动产生的,当有时间发生时,html元素会向外界发出各种事件。
DOM事件流,当一个html元素产生一个事件时,该事件会在元素借点与根节点之间的路径传播,路径所经过的节点都会收到该事件,这个传播过程可称为DOM事件流。
主流浏览器的事件模型:
1)冒泡型事件
从DOM树型结构上理解,就是事件由叶子结点沿祖先结点一直向上传递直到根结点;从浏览器界面视图HTML元素排列层次上理解就是事件由具有从属关系的最确定的目标元素一直传递到最不确定的目标元素.
2)捕获型事件
由DOM树最顶层元素一直到最精确的元素
3)DOM标准事件模型
DOM标准支持捕获型与冒泡型,可以说是它们两者的结合体。它可以在一个DOM元素上绑定多个事件处理器,并且在处理函数内部,this关键字仍然指向被绑定的DOM元素,另外处理函数参数列表的第一个位置传递事件event对象。
首先是捕获式传递事件,接着是冒泡式传递,所以,如果一个处理函数既注册了捕获型事件的监听,又注册冒泡型事件监听,那么在DOM事件模型中它就会被调用两次。
Q5:DOM事件响应绑定
1)绑定单个监听
element.attachEvent("OnClick", observer)
element.detachEvent("OnClick", observer)
2)绑定多个监听
element.AddEventListener("Click", observer, useCapture)
element.RemoveEventListener("Click", observer, useCapture)
第三个参赛是指定在冒泡节点还是控制阶段调用
posted @ 2014-04-18 15:44 Enic 阅读(388) | 评论 (0)编辑 收藏

之前一直很抗拒使用gyp等待chrominu,喜欢cmake。但是不使用chromium工具链去编译,分析chromium确实非常痛苦啊,,,
好在这几天网络环境好,成功按照http://www.chromium.org/developers/how-tos/build-instructions-windows#TOC-Building-Chromium创建了编译环境。
不多大部分细节都不知道,没办法的事情。最终还是要自己理解整个工程才OK啊

gyp工具用法
例子:tools\gyp\gyp.bat --depth . -D component=shared_library --no-circular-check -G msvs_version=2008 -Ibuild/common.gypi build_add/all.gyp
添加参数用-D
Building in Visual Studio
You can use:
    set GYP_GENERATORS=msvs-ninja,ninja
and then
        gclient runhooks
gclient sync --force
Usage: gyp-script.py [options ...] [build_file ...]
Options:
  -h, --help            show this help message and exit
  --build=CONFIGS       configuration for build after project generation
  --check               check format of gyp files
  --config-dir=CONFIG_DIR
                        The location for configuration files like
                        include.gypi.
  -d DEBUGMODE, --debug=DEBUGMODE
                        turn on a debugging mode for debugging GYP.  Supported
                        modes are "variables", "includes" and "general" or
                        "all" for all of them.
  -D VAR=VAL            sets variable VAR to value VAL
  --depth=PATH          set DEPTH gyp variable to a relative path to PATH
  -f FORMATS, --format=FORMATS
                        output formats to generate
  -G FLAG=VAL           sets generator flag FLAG to VAL
  --generator-output=DIR
                        puts generated build files under DIR
  --ignore-environment  do not read options from environment variables
  -I INCLUDE, --include=INCLUDE
                        files to include in all loaded .gyp files
  --msvs-version=MSVS_VERSION
                        Deprecated; use -G msvs_version=MSVS_VERSION instead
  --no-circular-check   don't check for circular relationships between files
  --parallel            Use multiprocessing for speed (experimental)
  -S SUFFIX, --suffix=SUFFIX
                        suffix to add to generated files
  --toplevel-dir=DIR    directory to use as the root of the source tree
posted @ 2014-04-08 23:44 Enic 阅读(333) | 评论 (0)编辑 收藏

问题:我在视图画的图象或者文字,当窗口改变后为什么不见了?OnDraw()OnPaint()两个都是解决上面的问题,有什么不同?

答:OnDraw()OnPaint()好象兄弟俩,因为它们的工作类似。
至于不见了的问题简单,因为当你的窗口改变后,会产生无效区域,这个无效的区域需要重画。一般Windows会发送两个消息WM_PAINT(通知客户区 有变化)和WM_NCPAINT(通知非客户区有变化)。非客户区的重画系统自己搞定了,而客户区的重画需要我们自己来完成。这就需要OnDraw() OnPaint()来重画窗口。

OnDraw()
OnPaint()有什么区别呢?首先:我们先要明确CView类派生自CWnd类。而OnPaint()CWnd的类成员,同时负责响应WM_PAINT消息。OnDraw()CVIEW的成员函数,并且没有响应消息的功能。这就是为什么你用VC成的程序代码时,在视图类只有 OnDraw没有OnPaint的原因。

其次,要想在屏幕上绘图或显示图形,首先需要建立设备环境DC。其实DC是一个数据结构,它包含输 出设备(不单指你17寸的纯屏显示器,还包括打印机之类的输出设备)的绘图属性的描述。MFC提供了CPaintDC类和CWindwoDC类来实时的响 应,而CPaintDC支持重画。

当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows WM_PAINT 消息发送给它。该视图的 OnPaint 处理函数通过创建 CPaintDC 类的DC对象来响应该消息并调用视图的 OnDraw 成员函数。通常我们不必编写重写的 OnPaint 处理成员函数。

///CView
默认的标准的重画函数

void CView::OnPaint()
{
    CPaintDC dc(this);
    OnPreparDC(&dc);
    OnDraw(&dc); //调用了OnDraw
}


既然OnPaint最后也要调用OnDraw,因此我们一般会在OnDraw函数中进行绘制。下面是一个典型的程序

///视图中的绘图代码首先检索指向文档的指针,然后通过DC进行绘图调用。
void CMyView::OnDraw( CDC* pDC )

    CMyDoc* pDoc = GetDocument(); 
    CString s = pDoc->GetData(); // Returns a CString
    CRect rect;
    GetClientRect( &rect ); 
    pDC->SetTextAlign( TA_BASELINE | TA_CENTER ); 
    pDC->TextOut( rect.right / 2, rect.bottom / 2, s, s.GetLength() );
}

最后:现在大家明白这哥俩之间的关系了吧。因此我们一般用OnPaint维护窗口的客户区(例如我们的窗口客户区加一个背景图片),用OnDraw维护视图的客户区(例如我们通过鼠标在视图中画图)。当然你也可以不按照上面规律来,只要达到目的并且没有问题,怎么干都成。

补充:我们还可以利用Invalidate(),ValidateRgn(),ValidateRect()函数强制的重画窗口

 

posted @ 2014-03-10 18:12 Enic 阅读(229) | 评论 (0)编辑 收藏

如果使用了脚本,那么最终的事件应该是由:CCLuaEngine::executeEvent分发出去的,他应该是利用lua的一些机制绑定了对象和处理函数。


在脚本侧,用类似:
menuPopupItem:registerScriptHandler(menuCallbackExit)

menuLayer:setTouchEnabled(true)
    menuLayer:registerScriptTouchHandler(onTouch)

        layerFarm:registerScriptTouchHandler(onTouch)
        layerFarm:setTouchEnabled(true)
这样的代码来设定事件响应处理函数


猜测一下,当以脚本模式运行的时候如果事件发生了,首先检测发生事件的对象相应的处理脚本函数时候存在,如果存在就直接调用脚本函数
具体的各种事件类型,和个事件的各种参数以后在来分析吧
posted @ 2014-03-08 20:47 Enic 阅读(187) | 评论 (0)编辑 收藏

int comput(int tmpn)
  int tmpc=0;
   while(tmpn>0)
   {
     tmpc++;
     tmpn=tmpn&(tmpn-1)
    }
  return tmpc;
}




x=x&(x-1)
==============
以前没有见过这样的表达式,分析一下发现发明这个表达式的人是个高手。
表达式的意思就是把x的二进制表示从最低位直到遇到第一个1的比特置0。
例如:
e1:
x     = 01001000
x-1   = 01000111
x&(x-1)=01000000
e2:
x     = 01001001
x-1   = 01001000
x&(x-1)=01001000

位运算里有学问呀,
例如众所周知的交换算法:
void swap(int i1, int i2)
{
    i1 ^= i2;
    i2 ^= i1;
    i1 ^= i2;
}
还有,我今天看了Minix操作系统作者写的《操作系统 设计与实现》(写的比William Stalling的《操作系统 内核与设计原理》有条理而且清晰紧凑得多,后者内容芜杂)中的页面替换算法之一矩阵法,就是用位运算实现的:
假设内存分为n页,那么高速缓存一个n x n的比特矩阵,开始时全置0,如下(假设n=4):
  0 1 2 3
0 0 0 0 0
1 0 0 0 0
2 0 0 0 0
3 0 0 0 0
每次内存访问时,如果访问的是i页,那么先把矩阵的第i行置1,然后把矩阵的第i列置0,这样i行的二进制的值越小就表示i页最长时间最近没有被访问。例如假设访问的次序为0-2-3-1,那么该矩阵的变化过程为:
  0 1 2 3
0 0 1 1 1    0 1 0 1    0 1 1 0    0 0 1 0
1 0 0 0 0    0 0 0 0    0 0 0 0    1 0 1 1
2 0 0 0 0    1 1 0 1    1 1 0 0    1 0 0 0
3 0 0 0 0    0 0 0 0    1 1 1 0    1 0 1 0
第三个例子是Windows GDI的二元和三元光栅操作的编码。比较复杂,就不讲了。

x=x&(x-1); 可以用来求出x是否为2幂次方数;当&的结果为0时,x原值是2幂次方数,否则就不是2幂次方数;
如x=4时   4: 0000 0100
        & 3:0000 0011
得出结果为0 ,是2幂次方数;
x=5时,  0000 0101
         0000 0100
得出结果为1,即非2幂次方数;

posted @ 2014-02-26 16:55 Enic 阅读(655) | 评论 (0)编辑 收藏

GetTextMetrics与GetTextExtent的区别
GetTextMetrics:获取当前字体的信息

GetTextExtent:获取特定的字符串在屏幕上所占的宽度和高度

对于这两个函数的作用,我在编程的时候,也有一定的困惑。因此,我也想,其他人在编程的时候也肯定有 同样的困惑。所以我把他们解释一下。不足之处,还请大家多多的添加 批评~~其实,我们对什么困惑呢?函数的调用方法,还是在返回值上?

CDC::GetTextMetrics

作用:

返回当强设备描述表中的当前所用的字体的信息

函数原型:

BOOL GetTextMetrics(
   LPTEXTMETRIC lpMetrics 
) const;

参数: 
lpMetrics (是一个指针)
返回指向TEXTMETRIC 结构的一个数据。

返回值:
非零值成功

要求: 
包含头文件: afxwin.h




CDC::GetTextExtent
Call this member function to compute the width and height of a line of text using the current font to determine the dimensions.
调用这个函数,返回用当前字体写下的一行字符串的高度和宽度

函数原型:
CSize GetTextExtent(
   LPCTSTR lpszString,
   int nCount 
) const;

CSize GetTextExtent(
   const CString& str 
) const;

参数 
lpszString

指向一个字符串指针,也可以传递一个字符串对象。
nCount

指定字符在字符串中的数目
str

一个字符串对象,包含指定的字符。
返回值:

以逻辑单位返回字符串的尺寸,保存在一个CSize对象中
posted @ 2014-02-26 13:57 Enic 阅读(167) | 评论 (0)编辑 收藏

主要是这个参数起作用说: -mno-cygwin

尝试编译lua的时候发现机器上的mingw32-xy一直傻逼:make: Interrupt/Exception caught (code = 0xc0000005, addr = 0x0x75f843f9)
感觉上是要重新安装一下,不过咱机器上有cygwin,,,呵呵

CC= mingw32-gcc.exe
CFLAGS= -mno-cygwin -O2 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS)
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
LIBS= -lm $(SYSLIBS) $(MYLIBS)


后面编译glew的时候没看明白自带的make,所以就自己修改了下,,,
mingw32-gcc -mno-cygwin -DGLEW_NO_GLU -O2 -Wall -W -Iinclude -DGLEW_BUILD -o src/glew.o -c src/glew.c
mingw32-gcc -mno-cygwin -shared -Wl,-soname,libglew32.dll -Wl,--out-implib,lib/libglew32.a -o lib/glew32.dll src/glew.o -L/mingw/lib -lglu32 -lopengl32 -lgdi32 -luser32 -lkernel32


原文:
关于ejoy2d应该有不少人关注
最近看到想编下看看demo,感觉编译对于用惯ide来说确实有些麻烦,不过嘛
这样也好,简单,方便,不用配置那么多东西,一个make就可以做完,如果调试呢?
lua写嘛,网上弄个就可以了,但是如果要写lua导出函数呢?gdb吧,命令行蛮实在的。
废话不多少,下面编译过程
readme 需要
* Install Lua 5.2.3
* Copy lua52.dll to /usr/local/bin
* Install glew 1.9
* make or make mingw
* ej2d examples/ex01.lua to test
这个当然是先下载需要的库了
 glew 1.9 我这里直接用的1.10了 http://glew.sourceforge.net/
 
由于我电脑用使用codeblock,所以直接使用他
自带的mingw吧
1. 直接命令行下运行codeblock/mingw/mingwvars.bat目录,设置mingw运行需要的环境
2. 进
入lua-5.2.3目录 mingw32-make mingw 编译lua
3. 进入glew-1.10.0目录
gcc -DGLEW_NO_GLU -O2 -Wall -W -Iinclude -DGLEW_BUILD -o src/glew.o -c src/glew.c
gcc -shared -Wl,-soname,libglew32.dll -Wl,--out-implib,lib/libglew32.a -o lib/glew32.dll src/glew.o -L/mingw/lib -lglu32 -lopengl32 -lgdi32 -luser32 -lkernel32
4. 把lua-5.2.3/src/lua52.dll拷贝到CodeBlocks/MinGW/bin目录下
    把lua-5.2.3/src/liblua.a拷贝到CodeBlocks/MinGW/lib目录下,并改名为liblua52.a
    把lua-5.2.3/src/lua.h, lauxlib.h, luaconf.h, lualib.h 拷贝到CodeBlocks/MinGW/include目录下
    把glew-1.10.0/lib/glew32.dll拷贝到CodeBlocks/MinGW/bin目录下
    把glew-1.10.0/lib/libglew32.a拷贝到CodeBlocks/MinGW/lib目录下
    把glew-1.10.0/include/GL/glew.h,glxew.h, wglew.h 拷贝到CodeBlocks/MinGW/include/GL目录下
5. 命令行进入ejoy2d目录 mingw32-make mingw 编译ejoy2d 一些搞定
 6. 命令行输入ej2d examples/ex01.lua这样就可以看到窗口了.
posted @ 2014-02-25 10:04 Enic 阅读(978) | 评论 (0)编辑 收藏

仅列出标题
共22页: First 7 8 9 10 11 12 13 14 15 Last