'2009/06'에 해당되는 글 2건


플래시는 UI 측면에서 강력한  디스플레이 객체 중의 하나입니다.

플래시와 어플 웹 브라우저의 통신 방법으로 주로 이용되는 방법이 fscommand 입니다.

최근에는 external interface 라는 새로운 방법이 추가되기도 하였지만 여전히 상당수가 사용하는 방법이 fscommand 입니다.

 플래시에서 어플리케이션에 어떤 명령을 요청하는 경우 fscommand 의 command 와 argument 를 이용하며 어플리케이션에서 플래시를 호출할 경우는 명령어와 xml 경로를 전달해 주는 방식을 주로 사용합니다.

 플래시의 제작사인 Adobe 에서도 관련하여 많은 샘플코드를 제공하고는 있지만 주로 브라우저 즉 웹 어플리케이션 연동이나 C# 쪽 예제 중심이지 Visual C++ 용 예제는 별로 제공이 되지 않습니다.

 제 경험을 토대로 Visual C++ 과 Flash 의 연동방법에 대해 정리해 보았습니다.

 다이얼로그 베이스 프로그램에 플래시 오브젝트를 추가하여 연동하는 방법입니다.

 

1> 플래시 오브젝트를  불러옵니다.

Tools -> Choose ToolBox Items 메뉴를 선택합니다. (로딩되는데 시간이 좀 걸립니다)

Com Components Tab 으로 이동 후 Shockwave Flash Object 를 선택하고 OK 버튼을 클릭합니다,

 

 

2>다이얼로그에 플래시 오브젝트를 올립니다.

이름은 IDC_FLASH_MAIN 로 합니다.

 

3>플래시 wrapper Class 용 파일(flash_main.cpp, flash_main.h)을 프로젝트에 추가합니다.

 

4>fscommand 연동 관련 작업을 진행합니다.

 

*참고로 저는 CMobileShellDlg  라는 다이얼로그를 만들어 작업을 했습니다.

 

다이얼로그 헤더 파일에  아래와 같이 추가해줍니다.

#include "UI/flash_main.h"

#pragma once


// CMobileShellDlg dialog
class CMobileShellDlg : public CDialog
{
// Construction
public:
    CMobileShellDlg(CWnd* pParent = NULL); // standard constructor
    virtual ~CMobileShellDlg();

// Dialog Data
    enum { IDD = IDD_MOBILESHELL_DIALOG };

protected:
    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support


// Implementation
protected:
// Generated message map functions
    virtual BOOL OnInitDialog();
DECLARE_MESSAGE_MAP()


public:
    CFlash_main m_Flash_Main; //플래시 오브젝트
    CStringArray m_CommandArray; //플래시와 통신하기 위해 명령어들이 저장되는 Array

public: // Flash
DECLARE_EVENTSINK_MAP()
    void FSCommandFlashMain(LPCTSTR command, LPCTSTR args); //플래시에서 쉘로 보내는 명령

    void Send_FlashFunction(); //쉘에서 플래시로 명령을 보내는 부분

public:
    virtual BOOL DestroyWindow();
};

 

다이얼로그 cpp 파일을 아래와 같이 작업해 줍니다.

 

// MobileShellDlg.cpp : implementation file
//

#include "stdafx.h"
#include "MobileShell.h"
#include "MobileShellDlg.h"
#include <afxmt.h>

CCriticalSection g_csFlashCallFunction;

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
 CAboutDlg();

// Dialog Data
 enum { IDD = IDD_ABOUTBOX };

 protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
 DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CMobileShellDlg dialog

 


CMobileShellDlg::CMobileShellDlg(CWnd* pParent /*=NULL*/)
 : CDialog(CMobileShellDlg::IDD, pParent)
 , m_bLoadMainFlash(false)
{
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
 m_bLoadMainFlash = FALSE;
}

CMobileShellDlg::~CMobileShellDlg()
{
 m_CommandArray.RemoveAll();
}

void CMobileShellDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 DDX_Control(pDX, IDC_FLASH_MAIN, m_Flash_Main); //IDC_FLASH_MAIN 와 m_Flash_Main 을 연결

BEGIN_MESSAGE_MAP(CMobileShellDlg, CDialog)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()


// CMobileShellDlg message handlers

//플래시 메시지 핸들러 부분
BEGIN_EVENTSINK_MAP(CMobileShellDlg, CDialog)
 ON_EVENT(CMobileShellDlg, IDC_FLASH_MAIN, 150, CMobileShellDlg::FSCommandFlashMain, VTS_BSTR VTS_BSTR)
END_EVENTSINK_MAP()


BOOL CMobileShellDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // Add "About..." menu item to system menu.

 // IDM_ABOUTBOX must be in the system command range.
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 

 //메인 플래시 파일을 로딩하는 부분
 
TCHAR Buffer[BUFSIZE];
 GetCurrentDirectory(BUFSIZE, Buffer);
 
 wcscat_s(Buffer,BUFSIZE,_T("\\sample.swf"));
 m_Flash_Main.LoadMovie(0, Buffer); //현재 디렉토리에 있는 sample.swf 파일을 로딩합니다

 return TRUE;  // return TRUE  unless you set the focus to a control
}

 

//실제 플래시에서 쉘로 보내는 메시지를 받는 부분입니다
void CMobileShellDlg::FSCommandFlashMain(LPCTSTR command, LPCTSTR args)

{
 

 CString sCmd, sArgs; //fscommand 로 날라오는 command 와 argument
 sCmd.Format(_T("%s"), command);
 sArgs.Format(_T("%s"), args);
 
 CString sFilePath;
 TCHAR Buffer[BUFSIZE];
 GetCurrentDirectory(BUFSIZE, Buffer);


 if( sCmd.CompareNoCase(_T("command1")) == 0 ) //command 명이 command1 일때 아래 코드를 실행합니다. 
 { 
  sFilePath.Format(_T("%s"),Buffer);
  sFilePath =  sFilePath + _T("\\test.xml");

 

 CString sRequest; //실제 플래시에 있는 명령을 호출하기 위해 작업하는 부분입니다.
 sRequest.Format(_T("<invoke name=\"responseall\"><arguments><string><![CDATA[%s]]></string></arguments></invoke>"), sFilePath);

//어플리케이션에서 호출할 플래시함수명이 responseall 이며 참조할 xml 파일이 test.xml 이라는 의미입니다.

//플래시에 responseall 이라는 외부함수가 존재하지 않는다면  exception에 의해 memory leak  이 발생합니다.

 

//플래시에 리턴할 명령을 commandArray 객체에 넣습니다.

 m_CommandArray.Add(sRequest);

Send_FlashFunction(); //실제 플래시메 명령을 전송합니다.

 }
}

 

//실제로 플래시에 명령을 보내는 부분

void CMobileShellDlg::Send_FlashFunction()
{
  CString sReturn;
  sReturn.Empty();
  try
  {
   if( m_Flash_Main.GetSafeHwnd() != NULL )
    sReturn = m_Flash_Main.CallFunction(sRrequest);

    //실제로 플래시에 명령을 보내는 부분입니다.

    //flash_main.h 파일의 callFunction 부분을 참조하시면 됩니다                

   }
  catch(...) //호출하는 함수명이 플래시내부에 존재하지 않는 경우 이부분에서 예외가 발생합니다
  {
  }

 }
 while(FALSE);
}

 

대략적인 방법을 설명드렸습니다.

완전한 소스 원하시는 분들은 메일 주시면 보내 드리겠습니다.


fscommand 에 대해 좀더 자세히 아시고 싶으신 분들은 아래 URL 을 참조하시기 바랍니다.

http://livedocs.adobe.com/flex/3/html/help.html?content=19_External_Interface_01.html





저작자 표시 비영리 변경 금지
신고
블로그 이미지

꽃중년

불만있으면 떠나라...

Tag mfc
출처: http://blog.naver.com/yi002910?Redirect=Log&logNo=60028589432


[강좌 / 고급] MFC + Flash 연동

야웅커뮤니티에 올린 본인의 강좌입니다.

이 강좌는 VC++6.0에서 MFC 어플리케이션과 Flash와의 상호 연동을 위한 것입니다.
따라서 MFC에 대한 지식을 동시에 요구합니다.

MFC 와 Flash를 서로 상호 연동한다는 것은 두 프로그램간의 변수를 서로 주고 받는 다는 것을 의미합니다. Flash에서는 어떤 작업이 완료 되었으니 다음 작업지시를 해달라고 MFC쪽에 변수를 하나 날리는겁니다. 그럼 MFC에서는 알았다고 다음 작업지시를 다시 Flash로 내려줍니다.
이때 MFC와 Flash간에 사용될 변수들은 미리 정의되어 있어져야 합니다.

일단 작업은 두 파트로 나누어 진행합니다.
MFC파트와 Flash 파트 둘로 말이죠....

<1: Flash Part>
플래시에서 해주어야 할 것은 MFC쪽에서 주는 변수를 받을때 사용할 변수가 하나 선언되어 있어야 합니다.
그러면 MFC에서 데이터를 Flash쪽으로 날려줄때 해당 변수로 값이 들어가게 됩니다.
그러면 플래시에서는 이 값을 받은 즉시 어떤 작업을 하기 위해서 onEnterFrame 으로 잡아내던지
watch 함수를 이용해서 잡아내던지 하면 되는 것입니다.

<2: MFC Part>
꼭 MFC를 고집하는 이유가 있습니다. 쉽기 때문이죠. MFC가 싫다고 하시면 C++ API로 MFC 다이얼로그를 직접 구현해서 ActiveX를 띄워야 합니다. 불가능 한건 아니지만 정말 어렵습니다. 플래시 자체가 원래 MFC로 만들어진 것이기 때문에 MFC를 빼고서는 서로 얘기가 되지 않는 것입니다.
그래서 다들 MFC나 C#을 사용할 것을 권하는 것입니다.

일단 MFC 어플리케이션 응용프로그램에서 ActiveX를 붙이면 됩니다. 아주 간단합니다.
File -> New 메뉴에서 MFC Application (EXE) 를 선택한뒤에 MFC응용프로그램 프로젝트를 만듭니다.
VC++6 을 기준으로 Project -> Add To Project -> Components and Controls 를 선택해서
"Shockwave Flash Object" 를 선택합니다.
Class Wizard 가 정상적으로 작동하는 프로젝트라면 CShockwaveFlash 라는 클래스를 생성하는 창이 뜰것입니다. 이 창이 뜨지 않으면 안됍니다.

그러면 ShockwaveFlash 클래스를 생성하고 나면 리소스 편집기에서 도구상자에서 맨 아래에 빨간색 X자 표시가 되어 있는 문서모양의 아이콘이 보일것입니다. 이것이 플래시를 보여주기 위한 것입니다.
그리고 다이얼로그박스에 이 플래시를 넣어줍니다.

그리고 Member Variables 를 추가해주기 위해 Class Wizard 를 띄웁니다.
Member Variables 탭으로 이동한뒤 보시면 Control ID에 IDC_SHOCKWAVEFLASH 라는 상수가 있을겁니다. 이것을 선택하고 옆의 Add Variables 버튼을 클릭하면 이제 Member Variable 을 추가하는 창이 뜹니다.
m_ 하고 옆에다가 이름을 적으면 됩니다. 여기에 적은 이름은 나중에 이 플래시를 컨트롤 하는 인스턴스네임으로 쓰여집니다.

자... 이제 준비는 다 끝났습니다.
이제 코딩만 남았습니다.
플래시를 띄울 다이얼로그의 사이즈와 플래시의 사이즈를 조절하기 위해 다이얼로그 클래스(기본적으로 Dlg 라는 글자가 포함되어 있습니다.)의 OnInitDialog() 함수로 이동하시기 바랍니다.
다이얼로그 초기화가 이루어질때 호출되는 함수입니다.
그리고 아래처럼 코딩을 합니다.

RECT rc;
rc.left = 0;
rc.top = 0;
rc.right = 640+4;
rc.bottom = 480+23;
MoveWindow(rc.left,rc.top,rc.right,rc.bottom);
ShowWindow(SW_SHOW);

다이얼로그의 크기를 조정하는 것입니다.
높이부분인 bottom 에 23을 더한 이유는 타이틀바가 크기가 23픽셀이기 때문이고 마찬가지로 좌우 4픽셀씩 더 나오기 때문입니다.
다이얼로그의 크기를 조절했으면 이제 플래시의 크기를 조절할 때입니다.

RECT rc2;
rc2.left = 0;
rc2.top = 0;
rc2.right = 640;
rc2.bottom = 480;
m_flash.MoveWindow(&rc2);

아래처럼 MoveWindow 함수를 씁니다.
플래시의 경우는 저렇게 해주면 됩니다.
m_flash는 플래시의 멤버변수입니다. 아까 말했죠? 인스턴스네임처럼 쓴다구요.
자 이제 플래시 컨텐츠를 넣을 시간입니다.

char buffer[_MAX_PATH];
char filename[] = "\\bmsp.dat";
_getcwd( buffer, _MAX_PATH );
strcat(buffer,filename);
m_flash.SetMovie(buffer);

_getcwd 함수로 현재 경로를 얻어와서 같은 폴더내에 있는 플래시파일을 실행하는 것입니다.
SetMovie 가 플래시 컨텐츠를 넣는 함수인데 이게 절대경로만 먹힙니다.
따라서 상대경로를 쓰려면 위에처럼 현재 디렉토리의 경로명을 _getcwd 함수로 받아온 다음에 strcat 함수로 끝에다 플래시파일명을 갖다 붙여서 넣어야 합니다.
\ 이문자는 경로구분으로 쓸때는 반드시 두개를 붙여야 합니다. 위에처럼 말이죠....

그럼 플래시가 작동되는 모습을 보실수 있을겁니다.
그럼 이제 연동을 구현할 시간입니다.

먼저 다시 Class Wizard 를 띄웁니다.
Message Maps 탭에서
IDC_SHOCKWAVEFLASH 라는 Object ID가 보일겁니다.
옆에 Message란에 보시면 FSCommand 라는것이 보입니다. 이 FSCommand 를 추가합니다.
이것은 플래시에서 fscommand로 넘어오는 값들을 catch 하는 함수입니다.
자동으로 값이 넘어오면 호출되는 콜백함수이므로 실시간으로 메세지를 캐치하도록 따로 구현할 필요는 없습니다. 수동으로 넣으신다면 당연히 구현해야 하지만 Class Wizard 를 통해서 넣으면 그런 과정까지 다 되어집니다.
그럼 아래와 같은 함수가 다이얼로그멤버에 추가됩니다.

void CBmspDlg::OnFSCommandShockwaveflash(LPCTSTR command, LPCTSTR args)
{
getmsg = command;
MessageBox(getmsg);
MessageBox(args);
m_flash.SetVariable("msg_variable","send from mfc");
}

플래시에서 fscommand 로 넘어오는 값을 체크할땐 이 함수를 통해서 체크를 합니다.
다만 command로 넘어오는 앞자리 변수는 if 구문으로 비교가 안됍니다.
따라서 미리 변수를 만들어 놓은 다음에 여기에 들어있는 값과 서로 비교해서 맞는지 여부를 체크해야 합니다.
다시 플래시로 값을 넘길때는 위의 예제처럼 SetVariable 함수를 사용합니다.
앞자리가 변수명이고 뒷자리가 변수에 들어갈 값입니다.
반대로도 가능한데 플래시에서 쓰이는 변수를 가져올때는 GetVariable 을 사용하시면 됩니다.

이것으로 강좌를 마치겠습니다.
 

저작자 표시 비영리 변경 금지
신고
블로그 이미지

꽃중년

불만있으면 떠나라...

Tag mfc

티스토리 툴바