`
hereson
  • 浏览: 1454262 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

VC++ 项目中使用 FLEX

    博客分类:
  • flex
阅读更多

1, http://hi.baidu.com/qinpc/blog/item/58253df3f9a04654352acc36.html

复杂的界面有多层窗口组成,当windows在窗口改变大小的时候是先重画父窗口,然后重画子窗口,子父窗口重画的过程一般无法在一个刷新周期内完成,所以会呈现闪烁。我们知道父窗口上被子窗口挡住的部分其实没必要重画的。

 

解决方法:给窗口加个风格 WS_CLIPCHILDREN ,这样父窗口上被子窗口挡住的部分就不会重画了。如果同级窗口之间有重叠,那么需要再加上 WS_CLIPSIBLINGS 风格

 

我赶紧到项目中把Flash对话框的窗口风格加上WS_CLIPCHILDREN,编译后运行,成功了!感谢作者,让我终于睡了一个安稳觉。
四、DEBUG状态是总是报Assertion失败。
这个问题困扰了我一整天。我的系统上安装了Flex SDK,因此,注册的Flash控件是调试版。不知什么原因,在每次关闭对话框之后,系统总是报cmdtarget.cpp文件中的控件引用值不为1错误,从而造成断言失败。
我以为是代码的问题,重建了一个项目,什么代码都没写。运行,关闭,断言错误。因为之前的VC出现了一个奇怪的问题:打开对话框命令总是出现非法操作。反复重装VC都不能解决,最后在网上看到可能是安装的visio 2003冲突,卸载visio 2003后问题解决。我开始怀疑是不是我之前的折腾把系统搞乱掉了。我又重装了一次VC,再次编译运行,问题再次出现。我都快疯了。
在没疯之前,我决定到同事的电脑上试一下。生成的程序运行没有问题。把我生成的代码拷贝过去运行,没有问题。我突然意识到,是不是Flash控件的问题。卸载重装后,问题解决。我的天!
(待续。。。)

 

 

 

同大多数的ActiveX控件一样,VC为Flash实现了一个CWnd的包装:CShockwaveFlash,该类实现了Flash ActiveX控件的所有功能。在AS3问世之前,Flash同宿主之间的通讯只有FSCommand一种方式,而且是异步的,更没有返回值可言。因为项目中需要VC为Flash提供大量的数据库查询,返回结果通过XML进行传递。因此,FSCommand无疑是不方便的。
AS3推出的外部API调用方式:ExternalInterface,极大的简化了编程方式。ExternaleInterface是同步的调用,并可以返回调用结果。需要说明的是,同步调用是以牺牲性能为代价的,因为这涉及到大量的CPU周期占用)。我曾经在Flex项目中,利用ExternalInterface实现了IFrame在Flash的嵌入调用,从而达到在Flash中显示HTML的问题。
CShockwaveFlash为ExternalInterface提供了一个事件接收器(event sink):FlashCall。FlashCall事件只有一个参数:request,而且我们会发现,在Flash中通过ExternalInterface的调用,是通过XML的方式进行封装,然后传递到request中的。为了获得调用的方法名和参数,你必须解析request封装的XML包。
不过奇怪的是,处理FlashCall事件的是一个void方法。要返回数据,你需要调用SetReturnValue方法。返回的数据也必须是XML格式,且必须符合Flash的规范。如果要返回XML结果集,把XML封装到<string></string>中,然后在Flash中通过new XML(str)的方式动态生成。
二、屏蔽Flash的右键菜单
这是个恼人的问题,我不希望用户在软件界面中弹出Flash右键菜单。在VC中,虽然Flash控件提供了SetMenu方法,通过传入FALSE屏蔽大部分的菜单项,但遗憾的是,“关于”和“设置”菜单无法去掉。
为了实现这个功能,我查阅了大量的资料。按照一般的想法,右键菜单的生成应该经过某种消息处理的流程。我先是重载了CShockwaveFlash类的WndProc方法,并在其中跟踪消息流,结果造成IDE死机。我做出了一个错误的决定,我认为这个消息一定可以在其它地方截获,于是我又费了很大的周折,特意实现了自己的CControlSite类,结果依然让人失望。
后来下载了一个Delphi下的TShockwaveFlashEx组件,才发现该组件是通过截获组件的WM_RBUTTONDOWN消息实现的菜单屏蔽。这就是说,让用户的右键消息干脆不传到Flash控件中去。简单而直接的方法。
VC中实现起来更简单些。直接从CShockwaveFlash派生自己的类(不建议直接修改CShowwaveFlash类),然后捕获WM_RBUTTONDOWN消息,直接在消息处理函数中注释掉父类的方法调用。然后修改Flash对象的类型为你的派生类即可。
甚至可以更简单些。直接在对话框中响应WM_MOUSEACTIVATE消息,然后在处理函数中判断message参数的值,如果是WM_RBUTTONDOWN,则返回MA_ACTIVATEANDEAT(激活控件,吃掉消息。http://msdn2.microsoft.com/en-us/library/ms645612.aspx)。
三、调整窗口大小时防止Flash控件闪烁
在Dialog的WM_SIZE响应中,把Flash控件布满整个窗口。可是这个简单的实现却造成了Flash界面的频繁闪烁。在Delphi的TShockwaveFlashEx组件中,作者是通过覆盖组件的CreateWnd方法实现的,在对话框Resize事件中,调用这个重载的CreateWnd方法。
可是,在VC中如何实现呢?为此,我在google上苦苦搜索了好几天。关于ActiveX控件闪烁的问题,网上有很多的解决方案。很多方案都是建议同时重载控件和对话框擦除背景事件,然后写一些代码防止控件重绘自身。也有一些方法是通过GDI的思路,在内存中通过bitblt的方式避免闪烁。看到最后很伤心,怎么会这么麻烦呢。
Ely Greenfield's Flex Ajax Bridge is a beautiful piece of work. It impressed me so much that I translated the javascript part of it to C++. Just like FABridge for javascript, the Flex C++ bridge allows you to do most of the things you can do with actionscript via C++. Of course, the syntax is not as pretty as it would be in javascript but it does let you develop C++ applications with a Flex UI.

What?

Nothing explains it like code. Take a look at the following C++ snippet1:

//addeventlistener to call a cpp function
oRootObj.Call("getbutton1").Call("addEventListener", "click", SampleCallback); 

//where SampleCallback is:
void SampleCallback(CASObject& obj, CFlexBridge* pBridge)
{
    CASObject oRootObj;
    pBridge->Root(oRootObj);
    oRootObj.Call("getpanel1").Call("settitle", "Title from CPP"); 
} 

//c++ way of saying Alert.show("StaticClassCalled")
pBridge->ClassRef("mx.controls.Alert").Call("show", "StaticClassCalled");

//create a datagrid and add it to the flex app
CASObject oDGrid = pBridge->Create("mx.controls.DataGrid");
oRootObj.Call("addChild", oDGrid);

Flex C++ Bridge is a C++ library that lets you communicate with Flex in a manner more suited for the normal C++ programmer, i.e, you can communicate to flex from c++ by writing code like shown above.

Once you put the Flex Ajax bridge into a Flex application, it is exposed to scripting in the browser. You can use a slightly modified version of the same FABridge.as2 (or even the same one) on the actionscript side and the flex application is exposed to the Flex C++ Bridge.

Flex is for the web, AIR is for the desktop. What is this for?

This is for C++ applications that need an awesome UI but do not want to re-write their existing c++ code and libraries to actionscript / javascript. It's a normal desktop application, you can interact with all your favorite C++ libraries and APIs and still have all the rich expressiveness that flex can deliver.

You could do all this before as well, but the bridge makes it really easy to use Flex from C++. A lot of the reasons for FABridge applies to this as well, but this is outside the browser realm so those reasons have to be filtered to suit that particular fact.

Where can I get it from?

The project is licensed under MPL 1.1 and both the C++ and actionscript source code is available atcode.google.com.

It's open source, so feel free to participate and contribute to it.

Sample Applications

Note: The source (both flex and cpp) is available for all the examples.

AdvancedDataGrid that supports Excel formulae computation:

Computing Excel formulae in ADG.

Here, each individual cells in the ADG are editable. You can type in any Excel formula into it and hit the "Compute" button. The application invokes Excel using COM, computes the results and populates the result into the ADG.

Scan images right into flexbook:

Scan images using TWAIN into Flexbook.

When the Scan button is clicked, a TWAIN dialog pops up letting you use your scanner to scan images directly into the pages of the flexbook component.

Sample app showing two flash player instances each with a flex application:

Multiple flash player instances.

The bridge supports multiple flash player instances. It can talk to each instance in a different manner. If you look at the screenshot, both the instances are loading the same swf file. But the C++ code for one instance adds a datagrid and removes an element shown in the pie chart.

How does it work?

The flash player ActiveX control is added to a MFC dialog. Now the content in the flash player can talk to the C++ application via ExternalInterface. ExternalInterface.call("fnname") will dispatch a FlashCall message on the C++ side which will have the arguments passed to call() in XML. This XML has to be parsed to understand what the message was from the actionscript side.

All this complexity is hidden by the bridge. The bridge talks with the actionscript side of Ely's FABridge and facilitates calling and referencing to actionscript objects, classes and methods.

There are multiple worker threads waiting to process incoming or outgoing flash requests so that the main MFC thread does not block. The bridge can even support multiple flash player instances each with it's own bridge back to the C++ application.

Also, Actionscript exceptions are serialized and thrown on the C++ side.

C++ Syntax Rules

To start off, you need the root object which is the main application object of your flex application. Now you can access the public methods and properties of your application.

Getters and setters are treated differently: A property "width" will be translated to "getwidth" for retrieving the value and "setwidth" for setting the value. Ely's FABridge had camel casing here, but that has been removed so that constants like MOUSE_DOWN don't confuse the bridge.

The "Call" method shown in the snippets above take a string as the first argument that is the name of the method or property (suitably modified using above defined rules) and the arguments for it. Common types like string, int, reference to an AS object, custom anonymous AS object etc are converted internally to an ASObject thanks to copy constructors and operator overloads.

For more examples of the syntax, take a look at the Worker() method in ASWorkSample.cpp.

FABridge did not originally have support for accessing methods and variables of static classes. This was added by Devin Garner and I have incorporated his code into FABridge.as along with some of my changes.

Fine Print

Currently, it supports only Windows since it embeds the internet explorer flash ActiveX control in a MFC dialog.

But it's an open source project and I hope I'll get contributors to help me make it more platform agnostic.

I'd love to know what you guys think about this and how it's being used.

CategoryFlexCPPBridge Comment(s)

 


[1] Now, this is a better way to communicate rather than saying m_Shockwave.CallFunction("asfnname") where asfnname has to be exposed by using ExternalInterface.addCallback on the actionscript side.
[2] Minor changes to support passing of primitives from me and additional support for accessing static classes, variables and methods thanks to Devin Garner)

 

3.

Flex与Win32通信实例之ExternalInterface

关键字: flex win32 vc++ vc externalinterface
项目中要实现Flex打开文件夹选择框(Flex做为桌面程序的UI),没办法,如果不用AIR只能在下面加一层Container了。网上搜来搜去差不多都是讲FSCommand怎样与VC++交互,可是FSCommand不能及时返回值呀。经过一番摸索,终于调通了ExternalInterface在VC++中的处理流程,看代码。 
 
Cpp代码 
void CMyBicapDlg::OnFlashCallShockwaveflash1(LPCTSTR request)   
 
    // TODO: Add your control notification handler code here  
    // "<invoke name='%s' returntype='xml'><arguments><string>%s</string></arguments></invoke>"  
      
    // parse request  
    TiXmlDocument request_xml;  
    request_xml.Parse(request);  
    const char* request_name = request_xml.RootElement()->Attribute("name");  
      
    if (strcmp(request_name,"savedVideosDirectory") == 0 || strcmp(request_name,"bufferDirectory") == 0 || strcmp(request_name,"preferredExportDirectory") == 0)  
    {  
        // choose path  
        CoInitialize(NULL);  
        BROWSEINFO bi;  
        bi.hwndOwner = this->GetSafeHwnd();  
        bi.pidlRoot = NULL;  
        bi.pszDisplayName = NULL;  
        bi.lpszTitle = NULL;  
        bi.ulFlags = BIF_BROWSEFORCOMPUTER|BIF_RETURNONLYFSDIRS|BIF_STATUSTEXT;  
        bi.lpfn = NULL;  
        LPCITEMIDLIST pidl = SHBrowseForFolder(&bi);  
        if(pidl != NULL)  
        {  
            TCHAR tpath[MAX_PATH] = _T("");  
            BOOL bresult = SHGetPathFromIDList(pidl, tpath);  
            if (bresult)  
            {  
                std::string re_value = "<string>";  
                re_value = re_value+tpath+"</string>";  
                m_FlashPlayer.SetReturnValue(re_value.c_str());  
            }  
        }  
  
        CoUninitialize();  
    }  
      
 
 
首先,需要在项目中嵌入Flash player插件,网上有很多例子。另外Flex也要写好代码,这里略掉。
添加一个ExternalInterface的事件处理函数,对于Flash player来讲就是FlashCall事件(跟FSCommand不同的),这里的事件处理函数是void CMyBicapDlg::OnFlashCallShockwaveflash1(LPCTSTR request)。没有返回值(下面会讲到),参数是一个XML格式的字符串。格式是"<invoke name='%s' returntype='xml'><arguments><string>%s</string></arguments></invoke>",去查查帮助就知道了。
处理request:标准C++没有处理XML的库,我去下载了tinyxml,小巧好用。下面就是按照个人需要处理request了,我这里是,打开一个文件夹选择对话框然后选择一个路径。
返回值。事件处理函数是没有返回值的,但是flash player提供了一个方法:m_FlashPlayer.SetReturnValue(re_value.c_str());,专门传递返回值,格式是<string>%s</string>(也可以是别的AS结构,具体看帮助)。
需要提醒的是,在处理期间要block掉Flex,ExternalInterface.call是有返回值的,如果不阻塞Flex,可能返回就是NULL,呵呵,不知道深层原因。另外,反过来调用格式也是一样的。
调试环境:win xp, VC++6.0, Flex builder 2.0

分享到:
评论

相关推荐

    编译原理lex词法分析 parser generator vc++

    例如,在VC++环境中,你可以创建一个lex源文件(通常扩展名为.l或.flex),编写正则表达式规则来定义不同类型的词素,然后使用flex工具将其转换为C++代码。 **解析器生成器(Parser Generator)** 解析器生成器,如...

    vs2008下使用Flex、Bison工具1

    通过上述详细的步骤,初学者可以轻松地在VS2008环境中使用Flex和Bison工具。正确地配置这些工具不仅可以提高开发效率,还能帮助理解词法分析器和语法分析器的工作原理。希望本指南能帮助大家顺利地完成学习任务。

    aa.rar_flex_语法分析flex

    "vc运行环境"指的是Visual C++的开发环境,因为Flex通常与C或C++一起使用,且在Windows环境下可能需要VC++的编译器和支持库来编译和运行生成的代码。 "Flex.exe"很可能是Flex工具本身,这是一个命令行工具,可以...

    在MFC嵌入Flex并且相互通信

    例如,当Flex中的按钮被点击时,可以触发一个事件,MFC接收到事件后执行相应的操作。 8. **调试与优化**:在开发过程中,要确保MFC和Flex的交互无误,可能需要使用Flex的调试器和MFC的调试工具进行联合调试,找出并...

    编译原理编译器 VC++MFC

    在VC++环境中,我们可以创建一个新的MFC应用程序项目,然后在该项目中集成编译器的不同组件。例如,我们可以创建一个文本编辑器窗口供用户输入源代码,使用MFC的消息处理机制来捕获用户的编译请求,接着调用自定义...

    词法分析器(用VC++6.0写的)

    C++标准库中并没有内置的正则表达式支持,但在VC++6.0环境下,开发者可能会选择第三方库如Flex和Bison,或者自定义的算法来实现这个功能。 词法分析器的工作流程如下: 1. 读取源代码文件:从指定的输入文件中读取...

    vc++词法分析器(编译原理)

    词法分析器通过识别输入流中的模式来完成这个过程,这个过程通常基于正则表达式或者使用自动生成的工具,如lex或flex。 在VC++环境中实现词法分析器,开发者需要对C++语言有深入的理解,同时熟悉编译原理中的词法...

    java、c、c++、vc、vc++、vb的区别和联系.doc

    VC 和 VC++ 的区别是,VC 是一个开发工具,VC++ 是使用 C++ 语言的工具。 VB(Visual Basic)是一种桌面程序开发技术,微软研发的。Basic 是比尔盖兹发家致富的一大工具。主要用来做桌面程序,C/S 系统。现在有了 ...

    java、c、c++、vc、vc++、vb的区别和联系.docx

    Java、C、C++、VC、VC++、VB 是编程领域的六种重要语言或开发工具,它们各有特点,适用于不同的应用场景。...学习编程还需要关注相关平台、框架和库,如.NET中的C#,或是Web开发中的Flex和Ruby等。

    java、c、c++、vc、vc++、vb的区别和联系.pdf

    - VC++ 使用了Microsoft的MFC库,简化了Windows应用程序开发。 5. VB(Visual Basic): - VB 是微软开发的基于Basic语言的可视化编程工具,曾经流行于桌面应用开发。 - VB 提供了直观的拖放界面设计,适合快速...

    编译原理课程设计VC实现源码

    在VC++环境中,可以使用自定义的词法分析器来实现这一过程。词法分析器通常通过正则表达式或者有限状态自动机(FSA)来识别和分类输入中的不同元素。 语法分析紧接着词法分析,它负责验证由词法分析器生成的token...

    VC++写的C编译器源代码附设计文档

    同时,对于想要提升MFC应用开发能力的程序员,这份源码同样有价值,因为它展示了如何在实际项目中运用MFC框架。 总的来说,通过研读这份VC++编写的C编译器源代码和设计文档,我们可以增强对编译原理的理解,提升C++...

    vc代码合集

    2012-06-11 09:50 3,412,722 内部文件非内部程序员禁止访问谢谢1234567890123456789能够实现文件的多选,统一上传,从而实现文件的批量上传Flex多文件上传源码VS2005.rar 2012-06-11 10:08 1,481,225 几个C语言小...

    编译词法分析

    7. **工具支持**:在VC++环境中,开发者可以使用如Flex(词法分析器生成器)和Bison(语法分析器生成器)等工具,它们能够根据给定的规则文件自动生成词法分析器和语法分析器的源代码。 8. **源代码文件管理**:在...

    VC知识库1-12期

    6. **预编译头文件(stdafx.h)**:VC++项目中常见的预编译头文件,用于包含常用库和常量定义,减少编译时间。 7. **调试技巧**:VC++的IDE提供了强大的调试工具,如断点、单步执行、查看变量值、调用堆栈分析等,...

    CPP_flash.rar_FlashMX/Flex源码_Visual_C++_

    标题中的"CPP_flash.rar"表明这是一个使用C++编程语言编写的程序,而"FlashMX/Flex源码"则表示该程序涉及到Adobe Flash MX或Flex的相关技术。"Visual C++"是指开发环境,即使用了微软的Visual Studio IDE,特别是...

    cifafenxiqi.rar_cifafenxiqi

    总之,"cifafenxiqi.rar_cifafenxiqi" 实验提供了一个实践性的平台,让我们深入理解编译原理中的语法分析过程,结合VC++的使用,能够加深对编译器构造的理论知识与实践经验的结合。无论是对于学术研究还是工程实践,...

    各种编程语言的区别与联系.doc

    需要注意的是,C++ 是语言,VC++ 是工具,是一门使用 C++ 语言的工具。 VB VB(Visual Basic)是一种桌面程序开发技术,由微软研发。VB 的主要用途是做桌面程序、C/S 系统。然而,由于 Delphi 的冲击,VB 被强占了...

Global site tag (gtag.js) - Google Analytics