여러 군대 찾아도 정보가 미흡하여,  사용 가능하게 정리하였습니다.

 - XLEzAutomation이나 ExcelLib의 기능에 원하는 기능 구현이 없고 수정 추가에도 어려움이 있어서...

 - 잘 활용하시기 바랍니다.

 

Excel 컨트롤 클래스 만들기.

(필요할 때마다 하나씩 추가 하자~~~~)

구현 기능

1 파일 열기,

2 파일 닫기,

3 다른이름 저장,

4 값 일기,

5 값 쓰기,

6 이미지 저장하기(클립보드, 절대 경로 Link, Link를 이용한 포함시키기)

7 Sheet Active 시키기.

 

미구현 기능

8 차트 만들기.

9 Sheet이름 바꾸기.

10 범용 알고리즘 콜하기.

 

추가된 Excel File들은 복사하여 다른 프로젝트에 Link를 걸고 그대로 사용 가능하다.

(MFC에서 Excel 컨트롤 하기(1)을 매 프로젝트에 추가할 필요는 없다)

#include "CApplication.h"//
#include "CWorkbook.h"//
#include "CWorkbooks.h"//

#include "CWorksheet.h"//
#include "CWorksheets.h"//


#include "CChart.h"//
#include "CCharts.h"//

#include "CBorder.h"//
#include "CBorders.h"//

#include "CPicture.h"//
#include "CPictures.h"//

#include "CRange.h"//
#include "CFont0.h"//

#include "CShapes.h"
#include "CShape.h"

 

 

구현 해더 파일.(ExcelCtrl.h)

#pragma once

#include "CApplication.h"//
#include "CWorkbook.h"//
#include "CWorkbooks.h"//

#include "CWorksheet.h"//
#include "CWorksheets.h"//


#include "CChart.h"//
#include "CCharts.h"//

#include "CBorder.h"//
#include "CBorders.h"//

#include "CPicture.h"//
#include "CPictures.h"//

#include "CRange.h"//
#include "CFont0.h"//

#include "CShapes.h"
#include "CShape.h"

static CString ColToColLetter(int colIndex)
{
	int div = colIndex;
	CString colLetter;// = String.Empty;
	int mod = 0;

	while (div > 0)
	{
		mod = (div - 1) % 26;
		colLetter = (char)(65 + mod) + colLetter;
		div = (int)((div - mod) / 26);
	}
	return colLetter;
}
static int ColLetterToColIndex(CString columnLetter)
{
	columnLetter = columnLetter.MakeUpper();
	int sum = 0;

	for (int i = 0; i < columnLetter.GetLength(); i++)
	{
		sum *= 26;
		sum += (columnLetter[i] - L'A' + 1);
	}
	return sum;
}

class CExcelCtrl
{
public:
	CExcelCtrl();
	~CExcelCtrl();

private:
	// spreadsheet variables
	CApplication	m_app;
	CWorkbook		m_book;
	CWorkbooks		m_books;


	CWorksheets		m_worksheets;


	COleVariant		m_covTrue;
	COleVariant		m_covFalse;
	COleVariant		m_covOptional;

	CString			m_strOpenFile;


private:
	void CloseWorkbook();
public:
	//1) File 열고 닫기.
	bool OpenFile(CString strFilePath);
	bool CloseFile();
	bool SaveFile();
	bool SaveAsFile(CString newFullPath);
	//2) Data 읽고 쓰기.
	CString GetValue(int nSheet, CString strCellPos);//CellPos :"A1", "O21"
	void SetValue(int nSheet, CString strCellPos, CString strNewValue);
	//3) Image 삽입.
	void SetPasteClipboard(int nSheet, CString strCellPos, double fViewSizeW = 0.0, double fViewSizeH = 0.0);//클립 보드의 이미지 삽입
	void SetPasteFileLink(int nSheet, CString strCellPos, CString strImgPath, double fViewSizeW = 0.0, double fViewSizeH = 0.0);//주어진 이미지 절대 경로를 삽입.(경로만)
	void SetFileLinkAndAdd(int nSheet, CString strCellPos, CString strImgPath, int orgW, int orgH, double fViewSizeW = 0.0, double fViewSizeH = 0.0);//경로의 파일을 삽입.(Excel File에 첨부)

	void SetActiveSheet(int nSheet);
};

 

구현 소스파일(ExcelCtrl.cpp)

#include "stdafx.h"
#include "ExcelCtrl.h"
#define rmm     23
CExcelCtrl::CExcelCtrl():
	m_app(nullptr),
	m_book(nullptr),
	m_books(nullptr),
	m_covTrue((short)TRUE),
	m_covFalse((short)TRUE),
	m_covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR)

{
	try
	{
		OleUninitialize(); //프로젝트 내 다른  COM이 초기화해 놓은 것을 죽여 놓으
		DWORD dwOleVer;

		dwOleVer = CoBuildVersion();

		// check the OLE library version
		if (rmm != HIWORD(dwOleVer))
		{
			MessageBox(NULL, _T("Incorrect version of OLE libraries."), L"Failed", MB_OK | MB_ICONSTOP);
			return;
		}

		// could also check for minor version, but this application is
		// not sensitive to the minor version of OLE

		// initialize OLE, fail application if we can't get OLE to init.
		if (FAILED(OleInitialize(NULL)))
		{
			MessageBox(NULL, _T("Cannot initialize OLE."), L"Failed", MB_OK | MB_ICONSTOP);
			return;
		}

		if (!m_app.CreateDispatch(L"Excel.Application"))
		{
			AfxMessageBox(L"Could not start Excel.");
			return;
		}
		m_app.put_DisplayAlerts(VARIANT_FALSE);
		m_app.put_UserControl(FALSE);
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}
}
CExcelCtrl::~CExcelCtrl()
{
	CloseFile();
	OleUninitialize();
	OleInitialize(NULL);  //프로젝트 내 다른 COM을 위한 센스
}
bool CExcelCtrl::OpenFile(CString strFilePath)
{
	m_strOpenFile.Format(L"%s", strFilePath);
	// close already-opened workbook
	CloseWorkbook();
	bool retV = false;
	try
	{
		// Get Workbooks collection.
		LPDISPATCH lpDisp;
		lpDisp = m_app.get_Workbooks();  // Get an IDispatch pointer
		ASSERT(lpDisp);
		m_books.AttachDispatch(lpDisp);  // Attach the IDispatch pointer to the books object.

		// open the document

		lpDisp = m_books.Open(m_strOpenFile.GetBuffer(m_strOpenFile.GetLength()),
			m_covOptional, m_covOptional, m_covOptional, m_covOptional,
			m_covOptional, m_covOptional, m_covOptional, m_covOptional,
			m_covOptional, m_covOptional, m_covOptional, m_covOptional,
			m_covOptional, m_covOptional);

		ASSERT(lpDisp);

		//Set CWorkbook to use lpDisp, the IDispatch* of the actual workbook.
		m_book.AttachDispatch(lpDisp);
		//WorkSheets Link.
		m_worksheets = m_book.get_Sheets();

		retV = true;
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}
	return retV;
}

bool CExcelCtrl::CloseFile()
{
	bool retV = false;
	CloseWorkbook();
	try
	{
		m_app.Quit();
		m_app.ReleaseDispatch();
		retV = true;
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}
	return retV;
}
bool CExcelCtrl::SaveFile()
{
	bool retV = false;
	if (m_app == nullptr || m_books == nullptr || m_book == nullptr)
		return retV;
	try
	{
		m_book.Save();
		retV = true;
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}

	return retV;
}
bool CExcelCtrl::SaveAsFile(CString newFullPath)
{
	bool retV = false;
	if (m_app == nullptr || m_books == nullptr || m_book == nullptr)
		return false;
	try
	{
		//51 = xlOpenXMLWorkbook(without macro's in 2007-2016, xlsx)
		//52 = xlOpenXMLWorkbookMacroEnabled(with or without macro's in 2007-2016, xlsm)
		//50 = xlExcel12(Excel Binary Workbook in 2007 - 2016 with or without macro's,xlsb)
		//56 = xlExcel8(97 - 2003 format in Excel 2007 - 2016, xls)
		int nPos  = newFullPath.ReverseFind(L'.');
		CString strExeName;
		strExeName.Format(L"%s", newFullPath.Mid(nPos+1));
		//strExeName.MakeUpper();
		long nFileCode = 51;
		if (strExeName.CompareNoCase(L"xlsm") == 0)
			nFileCode = 52;

		m_book.SaveAs(
			COleVariant(newFullPath.GetBuffer(newFullPath.GetLength())),
			COleVariant(nFileCode),//file format
			m_covOptional,//COleVariant(_T(""), // password
			m_covOptional,//COleVariant(_T(""), VT_BSTR), //readonly
			m_covOptional,//covFalse, 
	  //createbackup
			m_covOptional,//covFalse, 
	  //accessmode
			1,
			m_covOptional,//COleVariant((long) 1),  
			m_covOptional,
			m_covOptional,
			m_covOptional, m_covOptional);

		retV = true;
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}
	return retV;
}
void CExcelCtrl::CloseWorkbook()
{
	try
	{
		m_worksheets.ReleaseDispatch();
		// close already-opened workbook
		m_book.ReleaseDispatch();
		m_books.Close();
		m_books.ReleaseDispatch();
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}
}

CString CExcelCtrl::GetValue(int nSheet, CString strCellPos)
{
	if (nSheet < 1 || m_app == nullptr)
		return CString(L"");
	
	CString szValue;
	try
	{
		// sheet 생성, 연결 (1번 시트)
		CWorksheet sheet;
		sheet = m_worksheets.get_Item(COleVariant((short)nSheet));
		sheet.Activate();
		// range 생성, 연결
		CRange range;
		range.AttachDispatch(sheet.get_Cells(), true);

		range = sheet.get_Range(COleVariant(strCellPos.GetBuffer(strCellPos.GetAllocLength())), m_covOptional);
		range.Select();
		//------------------------------------------------------
		COleVariant vargValue = range.get_Value2();
		switch (vargValue.vt)
		{
		case VT_UI1:
		{
			unsigned char nChr = vargValue.bVal;
			//szValue = nChr;
			szValue.Format(L"%d", nChr);// = nChr;
		}
		break;
		case VT_I4:
		{
			long nVal = vargValue.lVal;
			szValue.Format(L"%i", nVal);
		}
		break;
		case VT_R4:
		{
			float fVal = vargValue.fltVal;
			szValue.Format(L"%f", fVal);
		}
		break;
		case VT_R8:
		{
			double dVal = vargValue.dblVal;
			szValue.Format(L"%f", dVal);
		}
		break;
		case VT_BSTR:
		{
			BSTR b = vargValue.bstrVal;
			szValue = b;
		}
		break;
		case VT_BYREF | VT_UI1:
		{
			//Not tested
			unsigned char* pChr = vargValue.pbVal;
			//					szValue = *pChr;
			szValue.Format(L"%f", *pChr);
		}
		break;
		case VT_BYREF | VT_BSTR:
		{
			//Not tested
			BSTR* pb = vargValue.pbstrVal;
			szValue = *pb;
		}
		case 0:
		{
			//Empty
			szValue = _T("");
		}

		break;
		}
		//------------------------------------------------------
		range.ReleaseDispatch();
		sheet.ReleaseDispatch();
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}
	return szValue;
}
void CExcelCtrl::SetValue(int nSheet, CString strCellPos, CString strNewValue)
{
	if (nSheet < 1 || m_app == nullptr)
		return;

	try
	{
		// sheet 생성, 연결 (1번 시트)
		CWorksheet sheet;
		sheet = m_worksheets.get_Item(COleVariant((short)nSheet));
		sheet.Activate();
		// range 생성, 연결
		CRange range;
		range.AttachDispatch(sheet.get_Cells(), true);

		range = sheet.get_Range(COleVariant(strCellPos.GetBuffer(strCellPos.GetAllocLength())), m_covOptional);
		range.Select();
		//------------------------------------------------------
		//Data 쓰기.
		range.put_Value2(COleVariant(strNewValue));
		//------------------------------------------------------
		range.ReleaseDispatch();
		sheet.ReleaseDispatch();
	}
	catch (CMemoryException* e)
	{
		CMemoryException* ep = e;
		AfxMessageBox(L"CMemoryException Could not clean up workbook.");
	}
	catch (CFileException* e)
	{
		CFileException* pe = e;
		AfxMessageBox(L"CFileException Could not clean up workbook.");
	}
	catch (CException* e)
	{
		CException* pe = e;
		AfxMessageBox(L"CException Could not clean up workbook.");
	}
}

void CExcelCtrl::SetActiveSheet(int nSheet)
{
	if (nSheet < 1 || m_app == nullptr)
		return;
	CWorksheet sheet;
	sheet = m_worksheets.get_Item(COleVariant((short)nSheet));
	sheet.Activate();
}
void CExcelCtrl::SetPasteClipboard(int nSheet, CString strCellPos,  double fViewSizeW , double fViewSizeH)
{
	if (nSheet < 1 || m_app == nullptr)
		return;
	CWorksheet sheet;
	CRange range;
	CPicture pic;
	CPictures pics;
	//CBorder border;

	sheet = m_worksheets.get_Item(COleVariant((short)nSheet));
	pics = sheet.Pictures(m_covOptional);
	sheet.Activate();
	// insert first picture and put a border on it
	range = sheet.get_Range(COleVariant(strCellPos.GetBuffer(strCellPos.GetAllocLength())), m_covOptional);
	range.Select();

	
	//링크 집어넣기
	//pic = pics.Insert(strLoadImgPath.GetBuffer(strLoadImgPath.GetLength()), covOptional);
	//붙여넣기
	sheet.Activate();
	pic = pics.Paste(m_covOptional);

	VARIANT varL = range.get_Left();
	VARIANT varT = range.get_Top();
	VARIANT varW = range.get_Width();
	VARIANT varH = range.get_Height();

	double l = varL.dblVal + 2.0;
	double t = varT.dblVal + 2.0;
	double w = varW.dblVal;
	double h = varH.dblVal;
	//Sheet 에서 위치 지정.
	pic.put_Left(l);
	pic.put_Top(t);
	pic.put_Locked(FALSE);
	//크기 지정.
	if (fViewSizeW > 0.0 )//&& fViewSizeH > 0.0)
	{
		pic.put_Width(fViewSizeW);
		//pic.put_Height(fViewSizeW);
	}
	pic.put_Visible(TRUE);

	
	//VARIANT Replace;
	//pic.Select(Replace);
	//m_book.Save();
	pic.ReleaseDispatch();
	pics.ReleaseDispatch();
	range.ReleaseDispatch();
	sheet.ReleaseDispatch();
}
void CExcelCtrl::SetPasteFileLink(int nSheet, CString strCellPos, CString strImgPath, double fViewSizeW, double fViewSizeH)
{
	if (nSheet < 1 || m_app == nullptr || strImgPath.GetLength()<3)
		return;
	CWorksheet sheet;
	CRange range;
	CPicture pic;
	CPictures pics;
	//CBorder border;

	sheet = m_worksheets.get_Item(COleVariant((short)nSheet));
	sheet.Activate();

	pics = sheet.Pictures(m_covOptional);
	// insert first picture and put a border on it
	// 링크 집어넣기
	range = sheet.get_Range(COleVariant(strCellPos.GetBuffer(strCellPos.GetAllocLength())), m_covOptional);
	range.Select();
	VARIANT varL = range.get_Left();
	VARIANT varT = range.get_Top();
	VARIANT varW = range.get_Width();
	VARIANT varH = range.get_Height();

	double l = varL.dblVal + 2.0;
	double t = varT.dblVal + 2.0;
	double w = varW.dblVal;
	double h = varH.dblVal;

	sheet.Activate();
	pic = pics.Insert(strImgPath.GetBuffer(strImgPath.GetLength()), m_covOptional);
	//붙여넣기
	//range = sheet.get_Range(COleVariant(strCellPos.GetBuffer(strCellPos.GetAllocLength())), m_covOptional);
	//range.Select();
	//pic = pics.Paste(m_covOptional);


	//Sheet 에서 위치 지정.
	pic.put_Left(l);
	pic.put_Top(t);

	//크기 지정.
	if (fViewSizeW > 0.0)//&& fViewSizeH > 0.0)
	{
		pic.put_Width(fViewSizeW);
		//pic.put_Height(fViewSizeW);
	}

	pic.ReleaseDispatch();
	pics.ReleaseDispatch();


	//m_book.Save();
	range.ReleaseDispatch();
	sheet.ReleaseDispatch();
}

void CExcelCtrl::SetFileLinkAndAdd(int nSheet, CString strCellPos, CString strImgPath, int orgW, int orgH, double fViewSizeW, double fViewSizeH)
{
	if (nSheet < 1 || m_app == nullptr || strImgPath.GetLength() < 3)
		return;
	CWorksheet sheet;
	CRange range;
	CPicture pic;
	CPictures pics;
	//CBorder border;

	sheet = m_worksheets.get_Item(COleVariant((short)nSheet));
	sheet.Activate();
	range = sheet.get_Range(COleVariant(strCellPos.GetBuffer(strCellPos.GetAllocLength())), m_covOptional);
	range.Select();
	VARIANT varL = range.get_Left();
	VARIANT varT = range.get_Top();
	VARIANT varW = range.get_Width();
	VARIANT varH = range.get_Height();

	double l = varL.dblVal + 2.0;
	double t = varT.dblVal + 2.0;
	double w = varW.dblVal;
	double h = varH.dblVal;

	CShapes  objShapes;
	CShape   objShape;
	objShapes = sheet.get_Shapes();
	objShape = objShapes.AddPicture(strImgPath, // Filename
		(long)0,    // LinkToFile
		(long)-1,	// SaveWithDocument
		(float)l,	// Left
		(float)t,   // Top
		(float)orgW,  // Width
		(float)orgH); // Height

	if (fViewSizeW > 0.0 && fViewSizeH > 0.0)
	{
		objShape.put_Width((float)fViewSizeW);
		objShape.put_Height((float)fViewSizeH);
	}
	if (objShapes.m_lpDispatch)
		objShapes.ReleaseDispatch();
	if (objShape.m_lpDispatch)
		objShape.ReleaseDispatch();

	range.ReleaseDispatch();
	sheet.ReleaseDispatch();
}

여러 군대 찾아도 정보가 미흡하여, 사용 가능하게 정리하였습니다.

- XLEzAutomation이나 ExcelLib의 기능에 원하는 기능 구현이 없고 수정 추가에도 어려움이 있어서...

- 잘활용 하시기 바랍니다.

 

프로젝트에 Excel Object Header File 넣기.

 

1) 프로젝트 -> 새 항목 추가-> MFC -> TypeLib의 MFC 클래스 선택.

2) 파일-> ...  선택 설치되어있는 Excel EXE(실행파일을 선택하기 위해)

3) 일반적인 설치 경로를 찾아 EXCEL.EXE를 선택한다.(Office 2016 버전 사용時"C:\Program Files\Microsoft Office\Office16\EXCEL.EXE")

4) 하단 왼쪽 항목에서 필요로 하는 파일(Class Header)을 선택한다.

오른쪽에 추가된 것이 Class File Name이 된다.

CApplication.h

CBorder.h

CBorders.h
CChart.h

CCharts.h

CFont0.h

CPicture.h

CPictures.h

CRange.h

CRanges.h

CShape.h

CShapes.h

CWorkbook.h

CWorkbooks.h

CWorksheet.h

CWorksheets.h

를 추가한다.

5) 추가를 완료하면 자동으로 프로젝트에 Header File일 추가된다.

빌드시 각 Header File의 아래 항목 주석 처리.

//#import "C:\\Program Files\\Microsoft Office\\Office16\\EXCEL.EXE" no_namespace

 

CRange.h파일의 DialogBox()함수 주석처리.(컴파일시 에러 발생)

//VARIANT DialogBox()
//{
// VARIANT result;
// InvokeHelper(0xf5, DISPATCH_METHOD, VT_VARIANT, (void*)&result, nullptr);
// return result;
//}

설치 파일 만들고, System 폴더의 INI를 바로 접근 하기기위해서 관리자 권한으로 실행 시키자.

CriticalSection : 하나의 Process에서 여러개의 Thread의 상호배제 구현
    선언 : CRITICAL_SECTION m_CrtSection;
    초기 :
    생성 : InitializeCriticalSectionAndSpinCount(&m_CrtSection, 2000);//Multi CPU를 지원 Spin Count를 추가 한다.
    진입 : EnterCriticalSection(&m_CrtSection);
    진출 : LeaveCriticalSection(&m_CrtSection);
    소멸 : DeleteCriticalSection(&m_CrtSection);

 

Mutex : 이름을 지정하여 여러개의 Process의 Thread에서도 상호배제 가능.Mutex는 동기화 대상이 오직 하나뿐일 때
    선언 : HANDLE m_hMutex;
    초기 : m_hMutex=NULL;
    생성 : m_hMutex=CreateMutex(NULL,FALSE,NULL); //OpenMutex()
    진입 : WaitForSingleObject(m_hMutex,INFINITE);
    진출 : ReleaseMutex(m_hMutex);
    소멸 : if(m_hMutex !=NULL ) CloseHandle(m_hMutex);

 

Semaphore : 여러 Process의 한가지 자원에 접근 배제.Semaphore는 동기화 대상이 하나 이상일 때 사용
    선언 : HANDLE m_hSemaphore;
    초기 : m_hSemaphore=NULL;
    생성 : m_hSemaphore= CreateSemaphore(
            NULL, // default security attributes
            3, // initial count. MAX_COUNT 10
            3, // maximum count. MAX_COUNT 10
            NULL); // unnamed semaphore

            WaitForMultipleObjects(5, &aThread[0], TRUE, INFINITE);
    진입 : dwWaitResult = WaitForSingleObject( 
            m_hSemaphore, // handle to semaphore
            0L); // zero-second time-out interval
            // Return value : 리턴값 ( dwWaitResult 에 저장되는 값 )
            // WAIT_ABANDONED 0x00000080L
            // WAIT_OBJECT_0 0X00000000L
            // WAIT_TIMEOUT 0x00000102L
            // WAIT_FAILED 0xFFFFFFFF(DWORD)
    진출 : ReleaseSemaphore(m_hSemaphore, // handle to semaphore
            1, // increase count by one
            NULL) ) // not interested in previous count

    소멸 : if(m_hSemaphore !=NULL ) CloseHandle(m_hSemaphore);

 

Event
    선언 : HANDLE m_hEvent;
    초기 : m_hEvent=NULL;
    생성 : m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); ResetEvent(m_hEvent);
    진입 : WaitForSingleObject(pDlg->m_hEvent, INFINITE);
    진출 : ResetEvent( hHandle );// 원하는 작업을 처리한다.
    소멸 : if(hHandle !=NULL ) CloseHandle(hHandle);
         

    이벤트 발생은 SetEvent(m_hEvent); //return value

        WAIT_FAILED : fail, GetLastError로 원인을 알수가 있다 이경우 logic을 빠져나간다
        WAIT_ABANDONED : 이 경우는 Event Object를 reset 하고 다시 WaitForSingleObject()를 호출한다
        WAIT_OBJECT_0 : 기다리던 Event가 signal 된 경우
        WATI_TIMEOUT : time-out 된 경우

생성 시 주의 점

 

1) Memory Leak현상.

a) 정적 라이브러리에서 MFC사용

=> 기본 OpneCV가 동적 Link DLL로 컴파일됨으로 C++ 사용 코드에서 오류 발생 시킴 비추천

https://sw-mcreator.tistory.com/15?category=816240

MFC 사용 방식 변경

b) 지연 dll등록으로 처리.(동적 오류, Memory Leak둘다 해결) 추천

DLL, Lib 위치한 폴더 지정
Lib를 종속시키고, DLL은 지연 시키다.

 

*VS2017에는 Installer가 기본 제공되지 않는다.

- 대상 항목을 업데이트 하여 추가 하자.

확장 및 업데이트에서 추가 해주자.

 

 

해당 Update를 찾아 다운로드 한다.

*다운로드가 완료되면 모든 Visual Studio를 닫아 준다. 그러면 아래 설치 관리자가 실행 된다.

Installer 설치 진행
Installer 프로젝트가 추가 되었음을 확인 한다.

 

나머시 설정은 타 TiStory에 정리가 잘되어 있으니 참고 하세요.

1) MFC  Dialog Base에서 F1 Key에 의한 Main Process Holding을 막기 위함입니다.

 

  - 초기 생성되는 APP 파일(" CTestPrgramDlg.cpp, CTestProgram.cpp")

BEGIN_MESSAGE_MAP(CTestProgramApp, CWinApp)
	//ON_COMMAND(ID_HELP, &CWinApp::OnHelp)//<<====주석 처리
END_MESSAGE_MAP()

2) 기타 종료 키 감지 및 막기

BOOL CTestProgramDlg::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
	//F1은 ON_COMMAND(ID_HELP, CWinApp::OnHelp)주석처리
	if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_F4)  //F4 Close App...
		return TRUE;
	if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) //ESC키 눌렀을때 방지..
		return TRUE;
	if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_SPACE) //Space키 눌렀을때 방지..
		return TRUE;
	if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN) //Enter키 눌렀을때 방지..
		return TRUE;
	return CDialogEx::PreTranslateMessage(pMsg);
}

+ Recent posts