MFC에서 PCL을 사용하려고 작업하는 중에,

 

다음과 같은 에러가 떴다.

 

...

Warning C4003: 'max' 매크로의 실제 매개 변수가 부족합니다.

error C2589: '(' : '::' 오른쪽에 잘못된 토큰이 있습니다.

error C2988: 템플릿 선언/정의를 인식할 수 없습니다.

error C2059: 구문 오류 : '::'

...

 

도대체 뭐가 문제일까.. 하면서 고민 하던 중,

 

공통점은 max 매크로의 실제 매개 변수가 부족하다 라는 공통된 경고를 깨닫게 되었고,

 

error C2589로 검색을 하던중, 한 블로그에 들어가서 문제점과 해결방법을 알게 되었다.

 

참조 블로그 링크 : http://blog.naver.com/smurfe380/150002451786

 

 

 

 

 

문제점은 바로..

 

std::min() 과 windef.h 파일에 있는 #define min(a,b) (((a) < (b)) ? (a) : (b)) 끼리 서로 충돌하는 에러 였던 것이었다.

 

 

 

 

 

그래서 해결 방법은,

 

문제가 되는 소스코드의 제일 첫 부분(include 하기 전), 아래의 소스코드를 추가해주면 문제는 깔끔히 해결 된다.

 

---------------------------------------------------------------------------------------------------

 

 

#ifdef max

 

#undef max

#undef min

#endif // max

 

---------------------------------------------------------------------------------------------------

 

이렇게 함으로써, max가 충돌되는것을 막음과 동시에, 적절한 min() 함수가 호출되서, 오류들을 말끔히 해결 할 수 있었다.

 

 

Posted by Tommy™
,

현재 진행중에 있는 프로젝트에서 Dialog창을 모달리스로 새로 생성을 해야하는데, 포커스가 이동이 안되는것이다.

 

그러다 검색하다보니,

 

방법이 있었다.

 

기존의 모달리스 창 생성할때 Create 부분에 CWnd::GetDesktopWindow() 을 추가해주면 되는것이었다.

 

이렇게 하면 부모 다이얼로그랑 동급의 오더를 가지게 되어 각각의 포커스를 부여할 수가 있는것이었다.

 

m_pMyDlg = new m_pMyDlg;
m_pMyDlg->Create(IDD_MY_DIALOG, CWnd::GetDesktopWindow());

 

참조 : http://blog.naver.com/ice4tea/70015838748

 

 

Posted by Tommy™
,

현재 하고 있는 프로젝트에서 새로운 다이얼로그를 리소스 추가해서 두개의 창으로 진행중에 있다.

 

하지만 여기서 종료시 치명적인 문제점이 발생하는데..

 

delete 했을때 OnDestroy() 로 들어가지 않는것이었다.

 

그로 인해 메모리 누수가 주루루......

 

이를 해결하는 방법이 꼼딱마 님의 블로그에 고스란히 적혀있었다.

 

링크 : http://blog.naver.com/PostView.nhn?blogId=teramarine&logNo=150030061661&redirect=Dlog&widgetTypeCall=true

 

말을 좀 인용하면, 새로 생성된 다이얼로그를 바로 delete 하게 되면 내부 핸들은 삭제가 되지않고 남아있게 되어 밑에와 같은 로고가 뜬다고 한다.

 

Warning: calling DestroyWindow in CDialog::~CDialog --
 OnDestroy or PostNcDestroy in derived class will not be called.

 

그래서 프로그램 종료시 먼저 DestroyWindow(); 를 호출 해주면 깔끔히 사라지고 메모리 누수도 깔끔히~

 

소스코드도 발췌하면..

 

if( m_pTempDialog != NULL )

{

m_pTempDialog ->DestroyWindow();

delete m_pTempDialog;

m_pTempDialog = NULL;

}

 

 

 

Posted by Tommy™
,

최근에 매프레임 영상을 출력해줘야 하는 부분에 있어서 여러방법을 시도해보면서 느꼈던 점을 정리한다.

 

일단 나의 상황은 매 프레임 얻어온 영상을 갱신하거나 OpenGL을 Render() 시켜야만 하는 상황이었다.

 

그래서 선택한 사항들은...

 

1. OnTimer() 이용

 

2. Thread 생성

 

3. OnKickIdle()

 

4. 다이얼로그를 modal 말고 modaless로 생성 이었다.

 

 

하지만 여기에는 여러 문제점들이 발생했으니..

 

1. OnTimer() 이용

 

일단 제일 중요한게 퍼포먼스이다.

 

영상이 뚝뚝 끊기고 렉이 생기는데.. 무슨말이 필요한가.

 

테스트 후 바로 삭제!! Pass~

 

 

 

2. Thread 생성

 

일단 Thread 를 생성 후 이벤트 핸들러를 통해 접근 하려고 했지만.. 무슨일인지 모르게 Render() 함수로는 들어가지지만.. OpenGL 화면이 더이상 Render 되지않아 갱신이 되지 않았다. 무슨문제인지는 모르겠다...;; 그래서 Pass~

 

 

 

3. OnKickIdle()

 

Dialog 기반에서 OnIdle() 대신 널리 쓰이는 방법이 OnKickIdle() 이다.

 

이는 SDI 방법에서 주로 쓰는 OnIdle()과 같은기능??을 한다고 본다. (주관적인 생각!!)

 

어째뜬 이를 통해 Render() 시키니 잘~~된다. 정말 기뼜다.

 

하지만... 종료시 무슨 문제인지 모르겠지만, 계속 프로그램이 뻑난다.

 

메모리쪽도 아니고, NULL Pointer 로의 접근도 아니고.. 음... 도대체가 알수가 없었다.

 

이놈때문에 나의 금쪽같은 주말을 날렸지만 결국 해결 못했다... 젠장..!! 역시 Pass~

 

 

 

4. 다이얼로그를 modal 말고 modaless로 생성

 

낙담한 상태로 구글링을 하다가 MFC Dialog 기반일때 Modal 말고 modaless 로 생성하여 Idle() 돌리는법!! 이라고 소개 되어있는 곳을 검색하게 되었다.

 

올레!!!!!!

 

사이트 : http://blog.naver.com/oneofall?Redirect=Log&logNo=60110572078

 

여기서 제시한 방법은..

 

App::InitInstance() 함수내에서

원래는 (다이얼로그 클래스 이름을 CMyDlg 라고 하겠다.)

----------------------------------------------------------------
CMyDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.Domodal();
if(nResponse == IDOK)
{
}
else if(nResponse == IDCANCEL)
{
}

return FALSE;

----------------------------------------------------------------

위와 같은 소스로 되어 있는데 이걸

 

CMyDlg * dlg = new CMyDlg;
dlg->Create(다이얼로그 리소스 ID);
m_pMainWnd = dlg;

return TRUE; // 이것을 주의 하자 꼭 TRUE 로 리턴해야 실행하자마자 종료되지 않는다.

 

 

라고 되어있다. (사이트 참조!)

 

이말 즉슨 , Domodal() 하지않고, 동적생성하여 Modaless 상태로 따로따로 생성하면 SDI 처럼 OnIdle()을 사용할수 있다는 말이었다.

 

그리고 종료시 메모리 누수 때문에, App::ExitInstance() 에서 delete dlg; 를 해주라는 친절한 설명까지...

 

 

이제는 OpenGL Render()도 잘되고, 영상도 출력 잘되고.. 너무 만족한다.

 

나같은 실수나 과오를 똑같이 저지르지 말라는 생각에 이렇게 해결되자마자 급 작성중.. 얼마나 열불 터졌으면.. 에효!!

 

그래도 실수하면서 배운다 는 말이 맞기는 한거 같다.

 

 

 

 

젠장.

 

 

Posted by Tommy™
,

1. 변수 선언

BOOL m_bTransparent; // 텍스트의 배경을 투명하게 할 것인지
COLORREF m_colorText; // 텍스트 전경색
LOGFONT m_logFont;  // 텍스트를 출력할 논리적 글꼴

cf> 배경색을 지정하려면 변수 추가 : COLORREF m_bkText; // 텍스트 전경색


2. 생성자(보통 뷰 클래스)

 m_bTransparent = TRUE;

 m_colorText = RGB(255, 255, 0);
 m_logFont.lfHeight  = 35;
 m_logFont.lfWidth  = 0;
 m_logFont.lfEscapement = 0;
 m_logFont.lfOrientation = 0;
 m_logFont.lfWeight  = FW_NORMAL;
 m_logFont.lfItalic  = FALSE;
 m_logFont.lfUnderline = FALSE;
 m_logFont.lfStrikeOut = FALSE;
 m_logFont.lfCharSet  = DEFAULT_CHARSET;
 m_logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
 m_logFont.lfClipPrecision = CLIP_CHARACTER_PRECIS;
 m_logFont.lfQuality  = DEFAULT_QUALITY;
 m_logFont.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
 strcpy(m_logFont.lfFaceName, _T("Arial Black"));

cf) 배경색 지정하려면 m_bkText = RGB(255, 255, 0);


3. OnDraw or OnPaint

 // LOGFONT로부터 글꼴을 생성
 CFont newFont, *pOldFont;
 newFont.CreateFontIndirect(&m_logFont);
 // 생성된 글꼴을 DC에 선택
 pOldFont = (CFont *)pDC->SelectObject(&newFont);
 // 텍스트의 전경색과 배경색 설정
 pDC->SetTextColor(m_colorText);
 // 배경 모드를 설정
 if(m_bTransparent) pDC->SetBkMode(TRANSPARENT);
 else pDC->SetBkMode(OPAQUE);
 // 텍스트 출력
 pDC->TextOut( 20, 7, "사용자 로그인");

Posted by Tommy™
,