现在在做毕业设计,遇到了这么一个问题,具体的步骤是:
在做好的界面上,点一下"播放"按钮控件,就弹出一窗口播放Flash.(flash已做好)
请问这怎么去实现呢?
有没有相关的学习这方面的网站,不胜感谢!

解决方案 »

  1.   

    http://www.vckbase.com/document/viewdoc/?id=285
      

  2.   

    VC中利用FLASH制作图声并茂的动画程序 
    作者:通信指挥学院三十一队 罗少波
    前言:
    FLASH是一种功能强大的矢量动画,可以制作出各种华丽的电影效果,应用非常广泛!这也给予我们一个启迪:如果在VC程序中能够播放FLASH动画,将为程序增色不少,而且许多原本不易实现的功能,现在都可以轻松实现! 像金山词霸的安装程序主控界面就利用了FLASH,效果相当好。本文中笔者将制作一个完整的多媒体软件,将一些关键性技术介绍给大家,并提供全部代码供大家参考。
    下载本文的演示程序happy.exe 大小:2212K下载本文的全部源代码 happyflash.zip 大小:1240K下载MS AGENT演示源代码(VC) 大小:11.1K 
    本文使用到的关键性技术:
    (1)利用VB制作MS AGENT播放模块。
    (2)将该播放模块、FLASH动画文件SWF与其它必要资源打包到程序中,并在运行时自动释放。
    (3)通过VC和VB的通信实现多个不同模块的顺序执行。
    (4)FLASH的播放,并实现避免右键菜单的弹出。下面介绍具体的实现:
    (1)利用VB制作MS AGENT播放模块。
    这里先插入MS AGENT模块。然后在Form_Load里进行Agent控件的初始化;
    Private Sub Form_Load()
         Agent1.Characters.Load ("dot")
         下面就可进行动画操作了.
         Agent1.Characters.Character("dot").Show
         我们可用如下语句执行一些动作
         Agent1.Characters.Character("dot").Play "Congratulate"
         Agent1.Characters.Character("dot").Speak "你好!"
         Agent1.Characters.Character("dot").moveto  x,y ‘x,y 位屏幕坐标。
    ......由于我们用的是dot.acs,我们不能假定别人的机子上有这个文件。所以我将这个文件复制到winnt(windows)\msagent\chars目录下, 用于复制的VC代码如下:
    char *a = new char [255]; 
    char *b = new char [255];
    GetCurrentDirectory(255,a);
    CString *str = new CString(a);
    CString *sou = new CString;
    ////////////////////////////////////////
    (*sou)=*str+CString("\\DOT.ACS");
    GetWindowsDirectory (b,255);
    CString  *des =new CString(b) ;
    (*des)+=CString ("\\msagent\\chars");
    CreateDirectory (des->GetBuffer (10),NULL);
    *des+=CString ("\\DOT.ACS");
    //AfxMessageBox (*des);
    //AfxMessageBox (*sou);
    CopyFile (sou->GetBuffer (10),des->GetBuffer (10),false);
    //这个是为了避免在Load中用全路径。(2)实现了文件打包,将过多的模块整合到一起,避免文件的繁杂
    首先我们将各个模块作为资源加入资源中。定义整数标识和类型。这些资源文件打包将在程序运行的时候解出。 以下是从资源释放到文件的函数:
    int res2file(LPCTSTR lpName,LPCTSTR lpType,LPCTSTR filename)
    {
    //输入:lpName 为资源名,可用MAKEINTRESOURCE()宏将整型变为字符串。
    //LpType  为串类型名
    //Filename  为释放出的文件名。
    //输出:成功1,失败0
    HRSRC myres = FindResource (NULL,lpName,lpType);
    HGLOBAL gl = LoadResource (NULL,myres);
    LPVOID lp = LockResource(gl);//返回指向资源内存的地址的指针。
    // CREATE_ALWAYS为不管文件存不存在都产生新文件。
    HANDLE fp = CreateFile(filename ,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);if (!fp)
    return false;
    DWORD a;
    //sizeofResource 得到资源文件的大小
    if(!WriteFile (fp,lp,SizeofResource(NULL,myres),&a,NULL)) 
    return false;
    CloseHandle(fp);
    FreeResource(gl);
    return true;
    }
    以下是调用的方法:
    res2file (MAKEINTRESOURCE(IDR_ZF),"swf","zf.swf");
    res2file (MAKEINTRESOURCE(IDR_ZG),"swf","zg.swf");
    res2file (MAKEINTRESOURCE(IDR_DOT),"acs","DOT.ACS");
    res2file (MAKEINTRESOURCE(IDR_SHARE),"dll","share.dll");
    res2file (MAKEINTRESOURCE(IDR_TALK),"dll","talk.dll");
    res2file (MAKEINTRESOURCE(IDR_SWFLASH),"ocx","swflash.ocx"); 
      

  3.   

    (3)通过VC和VB的通信实现多个不同模块的顺序执行
    在程序中我们需要调用VB模块并等待它执行完毕再继续我们的VC程序,这就涉及到VC与VB之间的通讯问题,在这里我使用事件来解决这个问题,请看如下代码:
    CreateEvent(NULL,false,false,"lsbeven");
    然后,调用ms agent 动画
    PROCESS_INFORMATION pi;
    STARTUPINFO si={0};
    si.cb=sizeof(si);
    char *a =new char [255]; 
    GetCurrentDirectory (255,a);
    CString *str=new CString(a);
    //AfxMessageBox (*des);
    //AfxMessageBox (*sou);
    *str+=CString("\\talk.e\0"); 
    BOOL fRet=CreateProcess(NULL,
          str->GetBuffer (5),
          NULL,
          NULL,
          FALSE,
          0,
          NULL,
          NULL,
          &si,
          &pi); 
    最后,用WaitForSingleObject (heven,40000)等待事件被触发。(40s超时) 接下来的问题便是如何在VB中完成执行后触发这个事件。由于在vb中使用API很复杂,为了提供简单起见我用vc做了share.dll实现setvalue,然后在VB中进行调用来激活事件。 在setvalue中调用如下两个函数来激活事件。
    OpenEvent(DWORD dwAccess,//存取方式
    BOOL bInheritHandle,//是否能被继承
    LPCTSTR lpName)//名字
    SetEvent (HANDLE hEvent); 
    Vb中用变量锁方法实现在未出来提示“点我呀!”前对左键点击的无效,在显示完提示后,当用户点击就调用setvalue来激活事件。
    Agent1_Click(ByVal CharacterID As String, ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Integer, ByVal y As Integer)
    If  b ==ture 
         Then  setvalue
    Endif (4)FLASH的播放,并实现避免右键菜单的弹出
    1. 控键注册: HMODULE   hmod=LoadLibrary ("swflash.ocx");
    FARPROC   p=GetProcAddress (hmod,"DllRegisterServer");
    (*p)();2.在工程中插入 flash 控件。由于在不规则窗口中在进行flash控件的支持会使程序过于不清晰。于是另开独立的窗口来显示flash。 void TransparentWnd::OnTimer(UINT nIDEvent) 
    {
      switch (nIDEvent)
      {
    case 1:
    {
    KillTimer (nIDEvent);
    DoChange(MAKEINTRESOURCE(IDB_MAIN2)); 
    //创建视,作为默认视
    if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
    CRect(260, 30,630, 370), this, AFX_IDW_PANE_FIRST, NULL))
           TRACE0("Failed to create view window\n");
    CenterWindow ();
    ShowWindow (SW_SHOW);
    }
    break;
    default: break;
      }
    }BOOL TransparentWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) 
    {
    if(m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
    return TRUE;//如果是command消息则视类先处理。
    return CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
    }void TransparentWnd::OnSetFocus(CWnd* pOldWnd)
    {
    //如果有视类则视类获得焦点。
    if(m_wndView.m_hWnd !=NULL)
    m_wndView.SetFocus();
    }下面在CchildView中定义CShockwaveFlash  myflash;///改变窗口特征
    BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) 
    {
       if (!CWnd::PreCreateWindow(cs))
           return FALSE;
       cs.dwExStyle |= WS_EX_CLIENTEDGE;
       cs.style &= ~WS_BORDER;
       cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, 
           ::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOWTEXT), NULL);
       return TRUE;
    } BOOL CChildView::OnEraseBkgnd(CDC* pDC) 

       return TRUE;//不让window自动刷屏
    }//下面进入控制部分
    int CChildView ::OnCreate (LPCREATESTRUCT lpCreateStruct)
    {
        if(CWnd::OnCreate(lpCreateStruct)==-1)
            return -1;
        myflash.Create(NULL,WS_CHILD|WS_VISIBLE,CRect(0,0,0,0), this, 1024);
        SetTimer (1,0,NULL);
        SetTimer (2,12000,NULL);
        CRect m_rect;
        GetClientRect (&m_rect );
        myflash.MoveWindow (&m_rect);//使flash 控件占满整个视区域
        return 0;
    }char *a = new char [512];
    GetCurrentDirectory (100,a);
    CString  *s=new CString(a);
    myflash.LoadMovie (0,*s+CString("\\zf.swf"));//这里一定要为全路径
    myflash.Play();//播放FLASH动画
    (5)两个高级话题 
    5.1 在VC中用COM接口对ms agent 进行操作 #include "stdafx.h"
    #include 
    #include 
    #include 
    #include const LPWSTR kpwszCharacter =L"dot.acs";
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
    IAgent *pAgent;
    if (FAILED(OleInitialize(NULL)))
         return -1;
    HRESULT hRes=CoCreateInstance (CLSID_AgentServer,
                         NULL,
                         CLSCTX_LOCAL_SERVER,
                         IID_IAgent,
                         (LPVOID*)&pAgent);
    //下面的代码调用IAgent::Load()方法来装入一个动画人物的数据
    //由于Agent服务器在自己的内存空间中运行,所以传送的字符串变量需要用SysAllocString()来分配内存VARIANTARG  vPath;
    VariantInit(&vPath);//初始化OLE变量 
    vPath.vt = VT_BSTR;//指明变量类型为Unicode的字符串
    vPath.bstrVal=SysAllocString(lpCharacter);//lpCharacter 为动画人物数据的存放路径long __RPC_FAR   lCharID,lRequestID;
    hRes=pAgent->Load(vPath,&lCharID,&lRequestID);//装入数据人物ID在lCharID中返回IDispatch  *pdCharacter;
    hRes=pAgent->GetCharacter(lCharID,&pdCharacter);
    //获取 lCharID的IDispatch接口指针调用IDispatch::QueryInterface()方法//可以得到IAgentCharacter的接口指针:
    IAgentCharacter  *pCharacter;
    hRes=pdCharacter->QueryInterface(IID_IAgentCharacter,
                                 (LPVOID*)&pCharacter);pdCharacter->Release();//释放IDispath 通过IAgentCharacter接口就可以调用动画人物支持的各种方法了: hRes = pCharacter->Show(FALSE,&lRequestID); //显示动画人物 
    hRes = pCharacter->MoveTo(320,240,100,&lRequestID);//移动动画人物到屏幕中央
    BSTR bszSpeak = SysAllocString(L"Hello World!");//分配字符串 
    hRes = pCharacter->Speak(bszSpeak,NULL,&lRequestID);//让动画人物说话 SysFreeString(bszSpeak);//释放字符串所占内存 // 程序在退出之前需要把创建的Agent对象释放: if(pCharacter){
        pCharacter->Release();//释放IAgentCharacter接口 
        pAgent->Unload(lCharID); //卸载动画人物数据 

    pAgent->Release(); //释放Agent对象 
    VariantClear(&vPath); //清除OLE变量 OleUnInitialize();
    }下载MS AGENT演示源代码(VC)11.1K5.2 同步问题还可用信号灯来实现
    在vc 中进行启动时第一步就创建信号量,值为0。在启动vb创建的程序,然后vc中进行p操作. vb创建的程序中 在退出时使用v操作。实现同步。 P (s):
    S - -
     If s<0
    Then 挂起当前进程
    对应:win32 API :WaitForSingleObject  V(s):
        S++
    If s<=0
    Then 在s的等待队列中唤醒一进程
    对应:win32 API :ReleaseSemaphore