ActiveX 권한..1

Program Visual C++ 2012. 1. 12. 17:40 Posted by HisPark

사내에서 Vista 지원때문에 새로 입사한 이지화씨를 통해 Vista지원여부와 방법들의 확인을 요

청하여 결과물로 나온 1차본이다.

여러가지 자료들도 잘 정리되어 있고 많은 정보를 링크하여 놓은 좋은 정보이다.

1. Windows Vista 표준사용자의 File Save & Open

(0) Administrator 계정으로 로그인해도 프로그램은 표준 사용자 권한으로 실행됩니다.

(1) CFileDialog를 이용해서 파일을 Save, Open 하는 프로그램을 만들어서 파일을 생성해

보았습니다.

C:\ => Root Directory에서는 경고 메시지가 나타납니다.

(Root 대신 \My Documents에 저장할 것인지를 묻습니다.)

C:\TEMP\ => 이와 같이 '쓰기 권한'이 사용자에게 부여된 폴더에는 자유롭게 저장이

가능합니다.

C:\Program Files\ => '읽기/실행 권한' 이 주어져 있습니다. 파일을 쓰는 시도를 하면

에러 없이 파일을 자유롭게 쓸 수 있는 것처럼 보이지만, 실제로 이 폴더에 쓰는 것이

아니라 C:\Users\<사용자 이름>\AppData\Local\VirtualStore\Program Files\

이 곳에 따로 저장이 됩니다. 작업 시 사용자가 C:\Program Files\ 에 저장을 지시하

면, 성공적으로 파일이 저장된 것처럼 보이지만, 물리적으로는

C:\Users\...\VirtualStore\Program Files\ 에 파일이 저장됩니다.

(그러므로 C:\Program Files\ 에 찾아가보면 파일이 없습니다.)

C:\Windows\ => \Program Files\ 폴더와 동일하게 작동합니다.

C:\Users\<사용자 이름>\AppData\Local\VirualStore\Windows\ 로 Redirection

시킵니다.

이렇게 Vista에서 자체 Redirection 시키는 디렉토리는 C:\Windows\ 와 C:\Program

Files\ 두 Folder만이 확인 되었습니다. C:\Users\...\VirtualStore\ 의 하위 Folder가

\Windows\ 와 \Program Files\ 밖에 없기 때문에, 현재로서는 이 두 Folder가 전부인

듯 합니다.

(2) 역시 CFileDialog를 이용해서 C:\Windows\ 와 C:\Program Files의 파일을 읽어보면,

먼저 C:\Users\...\VirtualStore\Windows\ 와 C:\Users\...\VirtualStore\

Program Files\ 에 그 파일이 있는지를 확인해 본 후, 있으면 그 VirtualStore에 있는 파

일을 읽어오고, 없으면 C:\Windows\ 와 C:\Program Files\ 에 그 파일이 있는지 확

인해서 읽어옵니다. 두 폴더에 같은 이름의 파일이 모두 존재할 때, 어떤 파일이 열릴 것인

가에 대한 정리입니다.

\VirtualStore\Program Files\ C:\Program Files\ 어느 쪽의 파일이 열리는가?

X X 파일 없음
X O C:\Program Files\
O X \VirtualStore\Program Files\
O O \VirtualStore\Program Files\
즉, 항상 VirtualStore가 우선적으로 검토되고, 만일 적절한 파일을 발견하지 못한 경우에

한해서만, 물리적인 저장 위치인 C:\Program Files를 access한다고 정리하시면 됩니다.

(3) 김명신의 즐거운 하루 블로그에서 잘 정리된 정보를 얻을 수 있습니다.

- Vista Note #1. 환경설정 파일 저장, http://himskim.egloos.com/1471216

- Vista Note #2. Virtualization, http://himskim.egloos.com/1473911

(4) Registry에 대한 저장은 아직 직접 실행해보지 않았습니다.

위에 소개된 블로그에 나타나있는 텍스트를 그대로 붙여넣기 합니다.

Registry의 경우는 어떨까요? 핵심적인 메커니즘은 파일과 유사합니다. Registry

Virtualization은 HKEY_LOCAL_MACHINE\Software 이하만을 가상화 합니다. 즉

HKEY_LOCAL_MACHINE\Software\AppKey1 에 접근을 시도하면 실제로는

HKEY_USERS\<User SID>_Classes\VirtualStore\Machine\Software\AppKey1

에 접근하게 됩니다.

Registry Virtualization에 대한 보다 자세한 내용은 Registry Virtualization 를 참고하십시

오.

마지막으로 이러한 virtualization 기능은 다음 version의 windows 출시나 혹은 그 이전

에라도 제거될 수 있다는 것입니다. 실제로 64bit Vista에서는 이러한 virtualization 기

능이 전혀 동작하지 않습니다. 따라서 virtualization 기능에 대해서 전혀 기억하지 못하

더라도 다음 한가지만은 기억해야 합니다.

Program Files나 windows 혹은 windows/system 폴더 그리고

HKEY_LOCAL_MACHINE\Software 등에는 파일 혹은 정보를 수정,삭제,저장할 수 없으

므로 프로그램을 수정해서 다른 위치에 이러한 정보를 저장하도록 고쳐야 한다는 것입니

다.
(5) '관리자 권한으로 실행' 하면 물리적으로 C:\Program Files\ 혹은 C:\Windows\ 에도

파일을 저장할 수 있습니다.

(관리자 권한으로 C:\Users\...\VirtualStore\Program Files\ 에 저장하려면, 직접

찾아가야 됩니다!)

(6) 프로그램을 Install 하거나 Uninstall 할 때는 VirtualStore 저장하지 않고,

C:\Program Files\ 에 접근할 수 있도록 권한을 줍니다.

이에 대한 편의를 위해 Microsoft에서는 'MSI(Microsoft Windows Installer) 3.1 및 4.0을

사용하는 것' 을 권장하고 있습니다.

p.s. 파일명에 Setup이나 Install이 있으면 Vista에서 자동으로 권한을 상승시켜 준다고

합니다.

이전에 쓰던 프로그램들을 모두 재패키징해서 재배포해야 하는 수고를 덜어주기 위해

MS에서 지원하는 레거시 지원이라고 합니다.

http://aromi.tistory.com/29 에서 관련된 내용을 찾아보실 수 있습니다.

(7) http://www.microsoft.com/korea/windows/ie/ie7/technology/default.mspx 에서

Microsoft가 제공하는 GuideLine을 다운 받을 수 있습니다.

최소권한부여 환경에서 어플리케이션 개발자를 위한 모범사례 및 지침(Word 문서, 720KB)

2. Windows Vista 표준사용자의 ActiveX

(1) 위의 File Write 하는 프로그램을 ActiveX로 바꾸어서 같은 방법으로 실행을 하였습니다.

Local Resource로 실행 시, 보호모드로 작동하지 않기 때문에 IIS server를 열어서 접속

하는 방법으로 테스트를 진행하였습니다.

(2) Regsvr32 으로 등록 해줄 때, '관리자 권한' 이 필요합니다.

cmd.exe 를 '관리자 권한으로 실행' 하거나, 아예 regsvr32.exe 의 실행 권한을 바꾸어 버

리는 수가 있습니다.

(Administrator가 아닌 사용자가 '관리자 권한으로 실행' 을 시도하면 관리자 권한이 있는

계정의 비밀번호를 묻습니다.)

(3) Regsvr32 등록이 잘 이루어졌다면 VC6 에서 작성한 ocx가 보호모드에서 정상적으로 작

동합니다. 앞서 진행한 것과 동일한 테스트를 진행하였고, File Save & Open은 (기대한

바와 같이) 위와 동일한 결과가 나타납니다.

IE7.0을 '관리자 권한으로 실행' 하면 IE7.0 내의 ActiveX 프로그램에서도 VirtualStore 말

고, C:\Windows\ 와 C:\Program Files\ 에 저장할 수 있습니다.

(4) SNAIPER의 조그마한 블로그 에 가보시면 Windows Vista 를 위한 ActiveX 마이그레이션

작업 절차 정리 문서 1 (http://snaiper.tistory.com/206)

문서를 참고하시면 VC6 에서 작성된 ActiveX를 Vista용으로 Migration 하는 경험담이 잘

정리되어 있습니다. (PDF 파일이 Adobe Reader 구버젼에서는 열리지 않는 듯 합니다.)

(5) 기타 ActiveX 에 관해 참고할만한 게시물들을 링크시켜 두겠습니다.

MS Windows Vista와 ActiveX에 대한 오해 http://aromi.tistory.com/29

(위에서 이미 링크한 그 블로그 입니다.)

Vista 와 ActiveX 그리고 보안

- (1) http://blog.naver.com/p4ssion/50013835648

(사실 이 글보다는 이 다음 글에 원하는 내용이 들어 있을 것 같습니다.)

비스타에서 강제로 액티브X 설치

- http://itviewpoint.com/tt/index.php?pl=2445

비스타와 보안 (Vista & ActiveX) 관련하여

- http://blog.naver.com/simonsayz?Redirect=Log&logNo=120034059886

Vista에서 ActiveX 사용 팁 한가지

- http://www.delmadang.com/cwb-bin/CrazyWWWBoard.exe?mode=read&num=4136&page=2&db=dmdlec3&backdepth=3

이어지는 답글 Code Sign 생략하기

- http://www.delmadang.com/cwb-bin/CrazyWWWBoard.exe?backdepth=1&db=dmdlec3&mode=read&num=4139

(6) http://www.microsoft.com/korea/windows/ie/ie7/technology/default.mspx 에서

Microsoft가 제공하는 GuideLine을 다운 받을 수 있습니다.

Internet Explorer 7 보호 모드의 이해 및 작업 (Word 문서, 366KB)

Internet Explorer 7 기술 개요 읽기 (Word 문서, 2.09MB)

(Internet Explorer 7에서는 웹 및 응용 프로그램 개발자를 위해 최종 사용자 환경, 보안,

개인 정보 보호, 플랫폼이 대폭적으로 향상되었습니다. 이 놀라운 새 버전의 기능에 대해

알아보려면 이 문서를 읽어보십시오.)

Internet Explorer 7.0 호환성 백서 (Word 문서, 1.92MB)

(이 문서에서는, 변화된 IE 7.0으로 인해 발생할 수 있는 전형적인 문제 및 현재 다양한 사

이트에서 보고되는 사례들을 알아보고 그에 대한 대처 방법을 소개합니다.)

위의 자료를 보면 Vista의 권한에 대한 대처 방안을 미약하게나마 생각할 수 있을 거 같다.

[출처] Windows Vista - VirtualStore, ActiveX (1차)|작성자 자유인

 

레지스트리 함수 사용시 winreg.h을 인클루드하고, advapi32.lib을 Library에 등록해야 된다. 대부분 windows.h에 포함되어 있다.

레지스트리 등록
BOOL SHRegWriteString(HKEY hKey, LPCTSTR lpKey, LPCTSTR lpValue, LPCTSTR lpData)
{
HKEY key;

if (RegCreateKeyEx( // 레지스트리키를 새로 만들어주는 함수이다. 만약 생성하려는 키가 존재하는 경우 해당 키를 오픈.

hKey, // 생성할 키의 루트키

lpKey, // 생성할 서브키(문자열)

0, // 반드시 0

NULL, // 키의 지정된 클래스명(문자열), (보통 NULL 입력)

REG_OPTION_NON_VOLATILE, // 정보를 파일에 기록한다. ( 보통 이 옵션을 사용 ), REG_OPTION_VOLATILE - 정보를 메모리에 기록합니다. ( 시스템종료시 기록이 지워진다. )


KEY_WRITE, // 쓰기와 관련된 모든 권한, KEY_ALL_ACCESS - 모든 권한, KEY_READ - 읽기와 관련된 모든 권한, KEY_EXECUTE - KEY_READ와 동일

NULL, // SECURITY_ATTRIBUTES 구조체의 포인터. (보통 NULL 입력)


&key, // 생성된 키의 핸들포인터

NULL // DWORD의 포인터, 생성된 키의 상태, (보통 NULL 입력)

)!=ERROR_SUCCESS) // 성공시 ERROR_SUCCESS, 실패시 0이 아닌값이 리턴됨

return FALSE;


if (RegSetValueEx( // 레지스트리키를 저장 하는 함수

key, // RegCreateKeyEx에서 얻은 핸들값

lpValue, // 값 이름

0, // 반드시 0

REG_SZ, //문자열 데이타 타입

(LPBYTE)lpData, // 값 데이터

lstrlen(lpData)+1 //값의 타입이(REG_SZ, REG_EXPAND_SZ, REG_MULTI_SZ) 일 경우 문자열의 크기

)!=ERROR_SUCCESS) // 성공시 ERROR_SUCCESS, 실패시 0이 아닌값이 리턴됨
return FALSE;

RegCloseKey(key); // RegCreateKeyEx에서 얻은 핸들을 닫는 함수
return TRUE;
}

ROOT KEY
HKEY_CLASSES_ROOT - 윈도우에 사용하는 프로그램과 각 프로그램에 연결된 확장명에 대한 정보, 단축키, 드래그 앤 드롭, 윈도우의 OLE에 관련된 정보가 저장
HKEY_CURRENT_USER - 사용자가 설정한 윈도우 환경에 대한 정보가 저장
HKEY_LOCAL_MACHINE - 컴퓨터에 설치된 하드웨어와 소프트웨어에 관련된 모든 설정 내용이 저장. 특히 하드웨어와 하드웨어를 구동시키는 드라이버와 설정 사항에 대한 정보가 저장
HKEY_USERS - HKEY_CURRENT_USER 에 저장된 정보 전체와 데스크탑 설정, 네트워크 연결등의 정보가 저장
HKEY_CURRENT_CONFIG - HKEY_LOCAL_MACHINE 키의 하위키인 Config 키의 내용만 담고 있슴.

데이터 형식
문자열 값(REG_SG) - 문자열 값을 가지는 데이터 형식
이진 값(REG_BINARY) - 0과1로 표현되는 2진수 값을 가지는 데이터 형식
DWORD 값(REG_DWORD) - DWORD는 더블워드(Double Word)를 의미하는 것
다중 문자열 값(REG_MULTI_SZ) - 여러 유니코드 문자열의 묶음
확장 가능한 문자열 값(REG_EXPAND_SZ) - 윈도우 XP는 여러 개의 시스템 정의 변수를 사용한다. 이러한 변수들은 BAT 파일이나 제어판의 ‘시스템’ 환경 변수에서 설정

레지스트리 삭제
BOOL SHRegDelValue(HKEY hKey, LPCTSTR lpKey, LPCTSTR lpValue)
{
HKEY Key;
LONG lRet = 0;

if(RegOpenKey( // 레지스트리를 오픈하는 함수

hKey, // 생성할 키의 루트키

lpKey, // 생성할 서브키(문자열)

&Key // 생성된 키의 핸들포인터

) != ERROR_SUCCESS) // 성공시 ERROR_SUCCESS, 실패시 0이 아닌값이 리턴됨
return FALSE;

lRet = RegDeleteValue( // 레지스트리를 삭제하는 함수

key, // RegOpenKey에서 얻은 핸들값

lpValue, // 값 이름

);

RegCloseKey(key); // RegCreateKeyEx에서 얻은 핸들을 닫는 함수
return ((lRet == ERROR_SUCCESS)? TRUE : FALSE); // 성공시 ERROR_SUCCESS, 실패시 0이 아닌값이 리턴됨
}

윈도우 시작에 등록 및 삭제

ex>

#include <windows.h>

// 등록

SHRegWriteString(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run","ProgramName", szPath);

// 삭제

SHRegDelValue(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run","ProgramName");

=========================================================================================================

레지스트리 등록

TCHAR value[1028] = "C:\\Program Files\\abc\\abc.exe -as";

HKEY hk;

RegCreateKey(HKEY_CURRENT_USER, "Software\\Microsoft\\windows\\CurrentVersion\\Run", &hk));


RegSetValueEx(hk, "abc", 0, REG_SZ, (LPBYTE) value, strlen(value)+1);


RegCloseKey(hk);


=========================================================================================================

레지스트리 삭제

HKEY key;

RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS,&key);


RegDeleteValue(key, "abc") ;


RegCloseKey( key );

=========================================================================================================

레지스트리 데이터 구하기

HKEY hhkey;
TCHAR str1[4 + 1];
DWORD data_size1 = sizeof(str);
RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM",0, KEY_ALL_ACCESS, &hhkey);
int ret = RegQueryValueEx(hkey, "\\Device\\Silabser0", 0, NULL, (LPBYTE)str, &data_size1);
AfxMessageBox(str);

'Program Visual C++' 카테고리의 다른 글

ActiveX 권한2  (0) 2012.04.18
ActiveX 권한..1  (0) 2012.01.12
MFC CInternetSession클래스 사용시_유의점  (0) 2011.12.01
AVI 파일 다루기  (0) 2011.08.30
정적 라이브러리에서 MFC 사용  (0) 2011.08.25
MFC의 CInternetSession 클래스를 사용하면 간편하게 웹페이지를 읽어올 수 있죠..

일단 웹페이지를 열기위해 OpenURL() 멤버 함수를 호출합니다..

CStdioFile* OpenURL(" LPCTSTR pstrURL, DWORD dwContext = 1, DWORD dwFlags = INTERNET_FLAG_TRANSFER_ASCII, LPCTSTR pstrHeaders = NULL, DWORD dwHeadersLength = 0 );
Throw ( CInternetException );

요놈은 CStdioFile(pstrURL에 연결해서 가지고 온 내용이 담긴 파일) 포인터를 리턴값으로 가지고 있읍죠.

페이지 pstrURL 형식에 따라 원하는 클래스로 캐스팅이 가능합니다.

URL type Returns
file:// CStdioFile*
http:// CHttpFile*
gopher:// CGopherFile*
ftp:// CInternetFile*

제가 MSDN Library January 2001를 설치해서 보는데요..
이 함수 정보에서 Remarks나 Return Value란을 뒤져봐도

"리턴값으로 넘어온 파일 포인터를 어떻게 처리해야 한다"라는 언급은 전혀 없어서
그냥 썼었습니다.. 그랬더니 무지막지한 메모리 릭이..(무한루프 속에서 호출하였음..)

제가 무식해서 첨엔 메모리 새는 원인을 찾지못하고 헤매다가 이 함수가 왠지 걸쩍지근해서..

소스파일인 inet.cpp 파일을 직접 훓어보았더니..

리턴값이 CInternetSession의 멤버변수(CStdioFile)를 포인터로 돌려주는게 아니라 new로 생성된거 였더군요..

즉 리턴값에 대해 delete 처리가 반드시 필요하다는 거죠..(왜 멤버변수라고 단정 지었던 것인지 ㅡㅡ;)

덧붙여.. TRY-CATCH를 반드시 써주셔야 합니다.. 안그럼 프로그램 언제 종료될지 모릅니다... -_-;

고로 이 클래스를 이용하시는 분들은 다음과 같이 써주시면 안전(?)하겠습니당..

CInternetSession* pSession = NULL;
CStdioFile* pFile = NULL;
TCHAR szError[1024] = {0};

TRY
{
pSession = new CInternetSession;
pFile = pSession->OpenURL("http://www.devpia.com");
}
CATCH (CInternetException, pEx)
{
pEx->GetErrorMessage(szError, 1024);
}

END_CATCH

if (pFile != NULL)
{
//여기서 웹페이지 내용을 가지고 처리
//HTTP를 호출했을 시
CHttpFile* pHttpFile = (CHttpFile*)pFile;
delete pHttpFile;
pHttpFile = NULL;
pFile = NULL;
}

if (pSession != NULL)
{
//pSession->Close(); //CInternetSession 소멸자가 알아서 호출함
delete pSession;
pSession = NULL;
}

AVI 파일 다루기

Program Visual C++ 2011. 8. 30. 17:18 Posted by HisPark

가장 기본적인 방법만 소개 드리겠습니다.

Video For Windows라는 윈도우즈의 비디오 라이브러리가 있는데

모두 Windows API함수로 되어 있어 쉽게 사용할 있습니다.

 

vfw.h 파일을 인클루드시키고 컴파일한 프로그램을 링크시킬 vfw32.lib

함께 링크하면 됩니다.

 

함수 사용 순서는 다음과 같습니다.

 

AVIFile 라이브러리를 시작시킵니다. [AVIFileInit()]

작업하고자 하는 비디오 파일을 엽니다. [AVIFileOpen()]

비디오 파일의 비디오 스트림을 엽니다. [AVIFileGetStream()]

필요하다면 스트림의 정보를 얻습니다. [AVIStreamInfo()]

프레임 추출 작업을 준비시킵니다. [AVIStreamGetFrameOpen()]

필요한 프레임 데이터를 추출합니다. [AVIStreamGetFrame()]

프레임 추출 작업을 종료합니다. [AVIStreamGetFrameClose()]

열려 있는 스트림을 닫습니다. [AVIStreamRelease()]

열려 있는 파일을 닫습니다. [AVIFileRelease()]

AVIFile 라이브러리를 종료시킵니다. [AVIFileExit()]

 

이와 같이 스트림의 GetFrame기능을 사용하면 프로그래머가 일일이 코덱을 사용해서

압축을 해제하는 일이 필요 없고 시스템에 코덱만 깔려 있으면 알아서 복원해 주니

사용하기가 아주 편리합니다. , 이때 추출된 프레임 영상 데이터는 Packed DIB형태

이므로 여기에 BITMAPFILEHEADER 추가하면 그대로 BMP파일로 저장할 있습니다.

또한 영상 데이터가 DIB라서 직접 픽셀 데이터를 조작하기가 쉬어 여러가지 영상 처리

기법을 구사할 있습니다.

===========================================================================================

Avi 파일을 여는 부분<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Avi파일을 다루는 함수는 기본적으로 Windows API 제공된다. 프로그램에서는 LoadAviFile()함수가 그런 API 이용하여 Avi파일을 열고 있다. 먼저 AVIFileOpen()함수를 이용해서 파일의 핸들을 얻고 AVIFileInfo()함수를 통해서 헤더에 해당하는 정보를 얻어온다. 여기서 얻어온 헤더정보를 이용해서 Avi파일을 처리하게 된다.

void CAviDialog::LoadAviFile()

{

int ErrorCode;

gcpavi=0;

m_bSearchArea=false;

m_MouseRect=CRect(-1,-1,-1,-1);

// Avi 파일을 개방한다.

ErrorCode = AVIFileOpen(&ppAviFile, AviFilePath, OF_READ, NULL);

if (ErrorCode == AVIERR_BADFORMAT)

MessageBox("AVIERR_BADFORMAT", NULL, MB_OK);

else if (ErrorCode == AVIERR_MEMORY)

MessageBox("AVIERR_MEMORY", NULL, MB_OK);

else if (ErrorCode == AVIERR_FILEREAD)

MessageBox("AVIERR_FILEREAD", NULL, MB_OK);

else if (ErrorCode == AVIERR_FILEOPEN)

MessageBox("AVIERR_FILEOPEN", NULL, MB_OK);

AVIFileInfo(ppAviFile, &pAviInfo, sizeof(pAviInfo));

AviPlayRate = 1000 / (pAviInfo.dwRate / pAviInfo.dwScale);

// Refresh time

m_sFS.Format("%df/s", pAviInfo.dwRate / pAviInfo.dwScale);

UpdateData(FALSE);

// 파일에 포함된 스트림의 종류를 얻는다. audio, midi, text, video

// 파일에 포함된 스트림의 종류만큼 반복한다.

// pavi값을 배열에 저장해야 한다.

for (int i = 0; i <= MAXNUMSTREAMS; i++)

{

if (AVIFileGetStream(ppAviFile, &pavi, 0L, i) != AVIERR_OK)

break;

if (i == MAXNUMSTREAMS)

{

AVIStreamRelease(pavi);

MessageBox("Exceeded maximum number of streams", NULL, MB_OK);

break;

}

gapavi[i] = pavi;

}

gcpavi = i;

for (i = 0; i < gcpavi; i++)

{

// 스트림헤더의 정보를 얻는다.

AVIStreamInfo(gapavi[i], &avis, sizeof(avis));

switch (avis.fccType)

{

case streamtypeVIDEO:

// 전체 프레임 수를 얻는다.

length = AVIStreamLength(gapavi[i]);

// 전체프레임수를 나타낸다.

m_sFrameRate.Format("%d/%d", 1, length);

UpdateData(FALSE);

l= sizeof(format);

// 비트맵 정보를 읽는다.

AVIStreamReadFormat(gapavi[i], AVIStreamStart(gapavi[i]), &format, &l);

bi = (LPBITMAPINFOHEADER)format;

pgf = AVIStreamGetFrameOpen(gapavi[i], NULL);

// BITMAPINFOHEADER 정보를 설정한다.

bi = (LPBITMAPINFOHEADER)format;

// BITMAPFILEHEADER 정보를 설정한다.

bf.bfType = 19778;

// 트루컬러는 RGBQUAD 정보가 없다.

bf.bfSize =

sizeof(BITMAPINFOHEADER) +

sizeof(BITMAPFILEHEADER) +

bi->biWidth * bi->biHeight * 3;

bf.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);

bf.bfReserved1 = 0;

bf.bfReserved2 = 0;

// 현재 나타낼 프레임을 첫번째로 설정한다.

AviFramePosition = 0;

break;

case streamtypeAUDIO:

LPWAVEFORMAT pwf = (LPWAVEFORMAT)abFormat;

l = sizeof(wf);

length = AVIStreamLength(gapavi[i]);

AVIStreamReadFormat(gapavi[i], AVIStreamStart(gapavi[i]), &wf, &l);

/*fp=fopen("sample.pcm", "wb");

for (pos=0; pos<length; pos++)

{

AVIStreamRead(gapavi[i], (long) pos, 1L, lpAudio, sizeof(lpAudio), &s, NULL);

fwrite(lpAudio, s, 1, fp);

}

fclose(fp);*/

break;

}

}

Invalidate();

}

Avi 파일에서 프레임별로 Bmp파일을 추출하는 부분

AVIStreamGetFrame()함수는 원하는 위치의 프레임을 얻어오는 역할을 수행하는 API함수이다. 일단 함수를 통해서 얻어온 프레임은 다시 비트맵의 정보를 가지고 있는 LPBITMAPINFOHEADER구조체를 통해서 비트맵화 된다.

void CAviDialog::GetAviFrame(int AviFramePosition, HDC dc)

{

// 현재 나타낼 이미지의 프레임을 얻는다.

if ((gf = (unsigned char *) AVIStreamGetFrame(pgf, AviFramePosition))==NULL && CameraState==NONACTIVE)

MessageBox("CODEC 컴퓨터에 설치되어 있지 않습니다.", NULL, MB_OK);

else

{

bi = (LPBITMAPINFOHEADER)gf;

bi->biXPelsPerMeter = 0;

bi->biYPelsPerMeter = 0;

bitmapinfo.bmiHeader.biBitCount = bi->biBitCount;

bitmapinfo.bmiHeader.biClrImportant = bi->biClrImportant;

bitmapinfo.bmiHeader.biClrUsed = bi->biClrUsed;

bitmapinfo.bmiHeader.biCompression = bi->biCompression;

bitmapinfo.bmiHeader.biHeight = bi->biHeight;

bitmapinfo.bmiHeader.biWidth = bi->biWidth;

bitmapinfo.bmiHeader.biPlanes = bi->biPlanes;

bitmapinfo.bmiHeader.biSize = bi->biSize;

bitmapinfo.bmiHeader.biSizeImage = bi->biSizeImage;

bitmapinfo.bmiHeader.biXPelsPerMeter = bi->biXPelsPerMeter;

bitmapinfo.bmiHeader.biYPelsPerMeter = bi->biYPelsPerMeter;

gf += sizeof(BITMAPINFOHEADER);

rect.left = 8;

rect.top = 7;

rect.right = bitmapinfo.bmiHeader.biWidth + 8;

rect.bottom = bitmapinfo.bmiHeader.biHeight + 7;

// 이미지를 다이얼로그에 나타낸다.

if (m_bHSBMode!=TRUE)

{

// 이미지 분석모드가 아닐경우

SetDIBitsToDevice(dc, 8, 7, bitmapinfo.bmiHeader.biWidth, bitmapinfo.bmiHeader.biHeight ,

0 ,0, 0, (WORD)bitmapinfo.bmiHeader.biWidth, gf, &bitmapinfo, DIB_RGB_COLORS);

} else

{

// 이미지 분석모드일 경우

AnalysisImage(gf);

SetDIBitsToDevice(dc, 8, 7, bitmapinfo.bmiHeader.biWidth, bitmapinfo.bmiHeader.biHeight ,

0 ,0, 0, (WORD)bitmapinfo.bmiHeader.biWidth, m_BinImg, &bitmapinfo, DIB_RGB_COLORS);

}

}

}

[출처] AVI 파일 다루기 (차니의 컴퓨터 마을) |작성자 newchany