도킹 윈도우 생성 중 CButton을 추가하였으나 비활성 상태로 사용 불가 현상이 있어 검색 중 

참조 링크를 찾았다.

 

내용 추가로 IDC_XX선언 범위가 벗어나 동작 오류도 있었다.

 

 

#define IDC_PROPER_ACTION_BT 0xD111 //번호는 8~0xDFFF 사이에서 지정

 

해더파일

afx_msg void OnBTAcition();

afx_msg void OnUpdateButton(CCmdUI *pCmdUI);

 

소스파일

ON_BN_CLICKED(IDC_PROPER_ACTION_BT, OnBTAcition)

ON_UPDATE_COMMAND_UI(IDC_PROPER_ACTION_BT, OnUpdateButton)

 

void CPropertiesWnd::OnBTAcition()
{
           AfxMessageBox(L"Action Button Click");
}

void CPropertiesWnd::OnUpdateButton(CCmdUI *pCmdUI)

{
         pCmdUI->Enable(TRUE);
}

 

참조

https://blog.naver.com/agebreak/60145877957

Excel 각 필드에 연속되는 값을 빠르게 삽입하기 위한 함수 형태.

 

CStringArray에 입력할 정보들을 추가하여 넘겨주고 내부 for문을 돌며 정보를 삽입한다.

->하나씩 접근하는 방식에 3배 정도 빨라지게 된다.

CRange range;
range.AttachDispatch(sheet.get_Cells(), true);

...

range.Select();

를 반복하면서 시간이 많이 걸린다.

 

해당 함수를 활용하여 원하는 정보 List를 빠르게 Excel에 입력하자.

 



void SetValueListData2(bool *pbRun, int nSheet,
		CString strCharCol1, int nStartRow1, CStringArray *pstrNewValueList1);



void CExcelCtrl::SetValueListData2(bool *pbRun, int nSheet,
	CString strCharCol1, int nStartRow1, CStringArray *pstrNewValueList1)
{
	if (nSheet < 1 || m_app == nullptr || 
		pstrNewValueList1 == nullptr)
		return;

	try
	{

		int nCnt1 = pstrNewValueList1->GetCount();
		if (nCnt1 > 0)
		{
			// sheet 생성, 연결 (1번 시트)
			CWorksheet sheet;
			sheet = m_worksheets.get_Item(COleVariant((short)nSheet));
			sheet.Activate();
			// range 생성, 연결
			CRange range;
			range.AttachDispatch(sheet.get_Cells(), true);

			CString strCellPos;

			for (int i = 0; i < nCnt1; i++)
			{
				if (*pbRun == false)//쓰기 중지.
					break;

				strCellPos.Format(L"%s%d", strCharCol1, nStartRow1 + i);
				range = sheet.get_Range(COleVariant(strCellPos.GetBuffer(strCellPos.GetAllocLength())), m_covOptional);
				//Data 쓰기.
				range.put_Value2(COleVariant(pstrNewValueList1->GetAt(i)));
			}
			//------------------------------------------------------
			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.");
	}
}

 

불가피하게 Release 모드에서 Debugging을 진행해야 할 때

컴파일 옵션에서 최적화를 "사용 안 함(/Oc)"로 하면 조금이지만~~~ 도움이 된다.

 

Release 모드에서 Debugging시 최적화 OFF

 

기본 설정이 함수 단위로 확장 축소가 가능하게 되어있다.

이것을 if문 for문과 같이 문장 블록 단위로 확장 축소를 하자.

 

간단하지만 긴코드 분석에 매우 유용 

'작업 > MFC' 카테고리의 다른 글

MFC에서 Excel 컨트롤 하기(4)  (0) 2022.09.02
Visual Studio Release모드 Debugging  (0) 2022.01.10
CFileDialog Error (File Click-Mouse R)  (1) 2021.10.14
MFC에서 Excel 컨트롤 하기(3)  (0) 2021.06.16
MFC OpneMP 간단 사용하기.  (1) 2020.03.10

 

문제점 : 프로그램내에서 공용 컨트롤 CFileDialog를 사용, 파일 선택시 마우스 오른쪽 클릭시 메모리 참조 에러 발생.

          - 마우스의 왼쪽(선택) 정상동작, 드래그 정상동작, 오른쪽 클릭시 메뉴 발생시 오류 

<발생 오류 표시>

분석 :

  - 타 프로그램에서는 발생 하지 않음.(신규 생성 MFC Window S/W에서 발생)

  - 여러가지 옵션, 설정값등 변경하여 동작 Test. (모두 동일 현상 발생)   

<호출 스택 확인시 문제 발생 위치 확인>

해결 :  해당 S/W 제거 후 동일 동작 확인 결과 오류 발생 없음.

<마우스 Event 정상동작>

 

결론 : 특정 S/W기능중 마우스 우 클릭의 메뉴 항목이 추가될경우 CFileDialog 호출에 영향을 줄 수 있다.

 - 현재는 해당 S/W를 제거 하거나 대용 S/W를 설치 하여 오류를 피하고 있다.

 - 근본적 해결방법은 아직 못찾음.(아시는분은 답글 부탁 드립니다.)

 

Cell의 색상(배경색) 정하기.

 

생성되는 Cntreior.h파일을 기존 폴더에 복사합니다.

  - MFC에서 Excel 컨트롤 하기(1)에서 만든 파일들이 있는 곳.

1)"Cnterior.h"의 

 //#import "C:\\Program Files\\Microsoft Office\\Office16\\EXCEL.EXE" no_namespace//<<------주석처리

 

2) "ExcelCtrl.h"파일에  #include "Cnterior.h"//<<------링크 추가.

 

3) 사용 방법

void CExcelCtrl::SetValue(int nSheet, CString strCellPos, CString strNewValue){} 함수에 추가.

CRange range의 범위 내의 Cell을 칠하게 된다.

Cnterior Itr;
Itr = range.get_Interior();
Itr.put_Color(COleVariant((double)BColor));

 

4) 함수 Overriding을 통해 Color인자를 받아 색상을 지정한다.

 

주: Data 쓰기 전에 색상변경을 먼저 해주어야 한다.

    - 순서가 바뀌지 않으면 Try Catch에서 예외가 발생(랜덤)한다.

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();

		//------------------------------------------------------
		//색상 변경
		COLORREF BColor = RGB(255, 0, 0);
		Cnterior Itr;
		Itr = range.get_Interior();
		Itr.put_Color(COleVariant((double)BColor));
		//------------------------------------------------------
		//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.");
	}
}

 

Cnterior.h
0.00MB

 

병렬 Process를 적용 하자.

 

a) for문 구성을 간단하게 Multi Thread와 같은 형태로 변환해준다.(병렬 프로그래밍)

- 8Thread CPU에서 4개를 사용할 경우에 속도 향상이 가장 좋아 4개로 기준 한다.(여러가지 요건에 의해 바뀔 수 있음)

b) 임의로 분리 수를 조절 할 수 있다.

c) 아주 간단하게 반복문의 정보 처리를 빠르게 할 수 있다.

 

* Window 자원요소등에 접근해야 할 경우 주의를 요한다.(로컬 변수 형태로 Object를 관리해줘야 한다)

 (직접 작성 코드에 대한 병렬화에 매우 좋은 효과를 기대 할 수 있다)

* GPU가 아닌 CPU자원을 사용하는 것이다 *^^;;

 

1) 설정.

Open MP를 사용하기 위한 설정

 

 

2) 기본 코드

		int nThAllCht =  OMP_TH_CNT;//(4)// omp_get_num_threads();
		omp_set_num_threads(nThAllCht);
#pragma omp parallel//윈도우즈용 비주얼 스튜디오는 알아서 컴파일 해준다.
		{
            //이하 코드는 For문을 각 Thread에게 공통적으로 분배 해주는 역할을 한다.
            // 1003개의 Data를 4개의 Thread가 처리 한다면.
            //1번 250개, 2번 250개, 3번 250개, 4번 250 + 3(나머지)를 처리 한다.
			int nListCnt = nReadFileCnt;//for문을 돌릴 총 수
			int nThCnt = omp_get_max_threads();
			int nThNum = omp_get_thread_num();

			int nJump = nListCnt / nThCnt;
			int nJumpN = nListCnt % nThCnt;

			int nStartIndex = (nThNum*nJump);
			int nTailAddCnt = 0;
			if (nThCnt == (nThNum + 1))//nThNum이 Zero Index임으로.
				nTailAddCnt = nJumpN;

			for (int iF = nStartIndex; iF < (nStartIndex + nJump + nTailAddCnt); iF++)
			//for (int iF = 0; iF < nReadFileCnt; iF++)//원본 For문
			{
            ...//반복 수행 코드.
            }
  #pragma omp barrier //모든 Thread가 여기에 도착 하도록 기다린다.
		}

1) 파일명에 특수(%)등이 포함된 문자열을 TRACE로 찍으면 에러가 난다.

 - File명에는 "%"문자가 들어갈 수 있다.(오류메시지가 안나고 그냥 죽는다).


2) CTime Obj는 1970년 이전 설정시 DebugMessage가 뜬다.

   int nYYYY = 1970;

 - CTime cTimeX(nYYYY, nMM, nDD, 0, 0, 0);//Debug Message가 출력되며 죽는다.

+ Recent posts