• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • VC中利用FLASH制作圖聲并茂的動畫程序

    發表于:2007-07-14來源:作者:點擊數: 標簽:
    作者:齊云 前言: FLASH是一種功能強大的矢量動畫,可以制作出各種華麗的電影效果,應用非常廣泛!這也給予我們一個啟迪:如果在VC程序中能夠播放FLASH動畫,將為程序增色不少,而且許多原本不易實現的功能,現在都可以輕松實現! 像金山詞霸的安裝程序主控
    作者:齊云

    前言:
            FLASH是一種功能強大的矢量動畫,可以制作出各種華麗的電影效果,應用非常廣泛!這也給予我們一個啟迪:如果在VC程序中能夠播放FLASH動畫,將為程序增色不少,而且許多原本不易實現的功能,現在都可以輕松實現! 像金山詞霸的安裝程序主控界面就利用了FLASH,效果相當好。本文中筆者將制作一個完整的多媒體軟件,將一些關鍵性技術介紹給大家,并提供全部代碼供大家參考。

    本文使用到的關鍵性技術:
    (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)通過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 dwAclearcase/" target="_blank" >ccess,//存取方式
    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 <ole2.h>
    #include <AgtSvr.h>
    #include <AgtSvr_i.c>
    #include <tchar.h>

    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變量
    }

    下載MS AGENT演示源代碼(VC)11.1K

    5.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  

    (6)后記
    本程序寫于6月份,當時是一個朋友的生日,它是作為一個禮物送給她的。開始的時候,只提供了簡單的窗口界面后來,在看了幾位高手的佳作后,將它改進了一下。并希望和大家一起討論,將它更加完美。 

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>