※ 요약

아래 이미지와 같이 자식 다이얼로그를 모달리스로 생성하고 띄울때, 부모 다이얼로그(윈도우)가 항상 자식 다이얼로그 밑에 위치하는 경우가 있다. 이는 자식 다이얼로그를 생성할때 부모 Wnd를 어떻게 지정하느냐에 따라 달라지는데 이번 포스트에서는 부모/자식 다이얼로그에 상관없이 활성화된 다이얼로그가 위로 올라오게 하는 방법을 알아보겠다.


※ 소스코드

먼저 소스코드부터 보겠다. Create함수의 두 번째 파라미터의 부모 Wnd를 this로 할 경우 부모 다이얼로그가 항상 자식 다이얼로그 밑에 위치하게 된다. 반대로 CWnd::GetDesktopWindow()로 지정하면 부모/자식 상관없이 활성화된 다이얼로그가 위로 올라오게 된다.



※ 적용 후

this 대신 CWnd::GetDesktopWindow로 지정한 후에는 아래 이미지들 처럼 활성화된 창이 위로 오게 된다.



※ 요약

윈도우의 WM_GETMINMAXINFO 메시지에 대한 포스트다. 이 메시지는 윈도우의 크기나 위치가 변경되었을때 발생하며 보통 윈도우의 최소, 최대 크기를 지정하여 프로그램이 너무 작거나 너무 크게 변경할 수 없도록 해야할때 사용한다. 예제로 만든 프로젝트는 다이얼로그 기반이지만, SDI, MDI 등에서도 적용가능하다.


※ 설명

아래 MFC 프로젝트는 GetMinMaxInfo 설명을 위해 다이얼로그 기반으로 만든 순수 MFC 예제다. 먼저 "클래스 뷰"탭으로 이동하여 다이얼로그 클래스에 마우스 우클릭을 하여 팝업된 메뉴에서 "속성" 항목을 선택한다. (만약 SDI나 MDI 프로젝트일 경우엔 CMainFrame 클래스에 하면 된다.)


메시지 항목을 선택한 후 WM_GETMINMAXINFO 항목을 찾아 Add 해준다.


그럼 아래와 같이 소스코드가 추가되는데, 이곳에 최소/최대 사이즈를 지정해주면 된다.



예제를 위해 임의의 값을 넣어봤다. 아래 예제는 min값과 max값을 모두 넣었는데, 값을 넣을때는 min값만 넣어도 되고, max 값만 넣어도 된다. 필자는 보통 min 값만 넣는 편이다.


컴파일/실행 후 사이즈를 최소로 해본 화면이다. 더 이상 작게 변경할 수 없다.


아래는 최대 사이즈로 된 화면인데, 마찬가지로 더 크게 변경할 수 없다. 


※ 요약
MFC로 개발하다 보면 Alt키나 Ctrl키가 눌렸는지 알아야 할 때가 있다. 이번 포스팅에서는 그 방법을 알아보도록 하겠다. 참고로 전역적으로 하려면 후킹을 통해서 하거나 드라이버 단에서 해야하며, 후킹을 통한 방법은 나중에 올리도록 하겠다.

※ 소스코드



※ 실행예

아래는 실행화면이다. 프로그램 실행후 키를 누르면 그에 해당하는 버튼의 이름을 메시지로 띄우게 했다. 위에서도 언급했지만 프로그램이 트레이에 있거나 최소화 중일때도 Alt키나 Ctrl키가 눌렸는지 확인하려면 후킹을 하면 되며, 후킹 관련은 나중에 올리도록 하겠다.




※ 요약
API함수 GetModuleFileName를 이용하여 현재 실행중인 실행 파일의 경로를 얻는 방법이다. 자주는 아니지만 실행 중인 파일의 경로가 필요할때가 있는데 그럴때 사용하면 되며, 필자는 보통 프로그램 시작시 실행 경로를 얻고, 필요할 때마다 사용하는 편이다.

※ 소스
CString CAdoTestDlg::GetExecutedPath( )
{
	CString strResult;
    CString strPath;

	if( GetModuleFileName( nullptr, strPath.GetBuffer(_MAX_PATH + 1), MAX_PATH ) != FALSE )
	{
		strPath.ReleaseBuffer( );

		strResult = strPath.Left( strPath.ReverseFind( '\\' )+1 );
	}
	else
	{
	}

	return strResult;
}

※ 값 확인

아래와 같이 멤버 함수를 작성하였고, 값을 확인하기 위해 임시로 OnInitDialog 함수에서 호출하도록 했다.


아래와 같이 실행중인 파일의 경로를 확인할 수 있다.



'MFC > 기타' 카테고리의 다른 글

MFC 모달리스 창 띄워져 있나 확인하는 방법  (0) 2013.12.01
[MFC] Enter/ESC 키 방지  (0) 2013.10.14

 

※ 요약

아래는 필자가 서비스 중인 다이얼로그 기반의 MFC 프로그램이다.

얼마 전 가가 채팅을 도입하기 위해 웹 브라우져 컨트롤을 추가하여 MFC에 웹 페이지를 띄운 화면인데, 그 방법을 정리하고자 포스팅한다. 또 Visual Studio 2013으로 만든 예제도 첨부하였으니 필요시 참고하기 바란다.


 


※ 사전 검점
프로젝트를 생성할 때 "Active 컨트롤" 옵션을 활성화 했는지 확인해야 한다.

만약 활성화 하지 않았다면 InitInstance( )함수에서 AfxEnableControlContainer( );라는 함수를 호출해주면 된다.

그렇지 않으면 프로그램 실행시 Debug Assertion Failed가 떴던걸로 기억난다.

 

예제 :HTML.zip

 

 

※ 방법

먼저 해당 프로젝트에 클래스를 추가한다.

 

 

WebBrowser2를 선택하여 추가한다.

 

잘 진행되었다면 아래와 같이 파일이 추가된다.

 

이번에는 다이얼로그에 Active 컨트롤을 삽입할 차례다.

 

"Microsoft Web Browser"를 선택한다.

 

아래와 같이 검은 네모가 추가되었다.

 

Active 컨트롤에 변수를 추가해 준다.

 

변수명은 원하는대로 넣는다.

 

아래와 같이 추가되었다.

 

필자는 OnInitDialog( ) 함수에서 2줄을 추가해줬다.

 

그러니 아래와 같이 구글이 띄워진 모습이다.

 

구글 사이트로 테스트는 끝났고 가가 채팅을 띄워봤더니 역시 잘 뜬다.


 


※요약
CString::TrimLeft : 문자열의 왼쪽에서 공백이나 탭, 개행 문자 또는 지정한 문자/문자열을 제거한다.
CString::TrimRight : 문자열의 오른쪽에서 공백이나 탭, 개행 문자 또는 지정한 문자/문자열을 제거한다.

※특징
TrimLeft, TrimRight함수는 인자를 넘기지 않을 경우 각각 문자열 좌우측에서 공백, 탭('\t'), 개행 문자('\n')를 제거한다.
인자를 넘길 경우 넘겨진 문자나 문자열을 제거하는데, 이때는 인자로 넘겨진 것만 제거된다.
TrimLeft, TrimRight함수는 문자열의 좌우측에서만 작업을 하므로, 문자열 중간에서 작업하려면
CString::RemoveCString::Replace함수를 적절히 이용하면 된다.

보통 필자는 에디트 컨트롤 등으로 사용자로부터 값을 넘겨받을 때, 
"  오늘은 OpenGL을 해야겠다.  "
상기와 같이 문자열 중간의 공백은 냅두고, 문자열 좌우측 끝에서만 공백 등을 제거할 때 사용한다.

※함수 원형 및 설명
void TrimLeft( );
void TrimRight( );
void TrimLeft( TCHAR chTarget );
void TrimRight( TCHAR chTarget );
void TrimLeft( LPCTSTR lpszTargets );
void TrimRight( LPCTSTR lpszTargets );
//chTarget : 문자열에서 제거할 문자
//lpszTargets : 문자열에서 제거할 문자셋
※예제
#include <atlstr.h>       //CString

#define print( str ) printf( "%s\n", str )

int main( )
{
	CString strText11 = " Visual Studio 2013 ";
	print( strText11 );

	//Trim함수 사용시 인자를 사용하지 않을 경우 공백, 탭 개행 문자를 지운다.
	strText11.TrimLeft( );
	print( strText11 );
	strText11.TrimRight( );
	print( strText11 );
	
	//------------------------------------------------------------------------------

	CString strText22 = " OpenGL, OpenCV ";
	print( strText22 );

	//Trim함수 사용시 인자를 사용할 경우 공백, 탭 개행 문자말고 지정한 문자만 지운다.
	//아래는 Left에 "Op"가 있을 경우, Right에 "CV"가 있을 경우 지우라고 했는데
	//공백이 있으므로 지워지지 않는다.
	strText22.TrimLeft( "Op" );
	print( strText22 );
	strText22.TrimRight( "CV" );
	print( strText22 );

	return 0;
}


※결과





 


※요약
CString::Remove : 지정한 특정 문자를 모두 제거한다.

※특징
문자열은 지정이 안되고 문자만 지정되므로 알아도 잘 사용하지 않는 함수다.
필자의 경우, 보통 CString::Replace를 더 많이 사용한다.

※함수 원형 및 설명
int Remove( TCHAR chRemove );
//chRemove : 제거할 문자
//반환값 : 제거한 문자의 수

※예제
#include <atlstr.h>       //CString

#define print( str ) printf( "%s\n", str )

int main( )
{
	CString strText = "+V+i+s+u+a+l St+u+d+i+o C++ 20+13";

	print( strText );

	strText.Remove( '+' );
	print( strText );

	return 0;
}



※결과

아래 예제에서는 문자 '+'를 제거한다.

한 번의 Remove함수 호출로 모든 '+' 문자가 제거 되었다.




 

※요약
CString::Delete : 문자나 문자열을 삭제한다. 삭제하려는 위치와, 삭제하고자 하는 길이를 지정할 수 있다.

※특징
고정 길이의 문자열에서 필요 없는 부분을 삭제할 때 좋다.
예를 들어 아래와 같이 날짜시간 형식의 고정 길이 문자열이 있다고 할 때
날짜만 없애거나, 시간만 없애는 등 특정 부분을 지울때 사용.
2014-09-29 07:05
2014-09-29 08:15
2014-09-29 09:42
2014-09-29 10:18
2014-09-29 11:23

필자는 Delete함수를 알기 전까지는 보통 CString::Mid를 많이 사용하였으며, 삭제 말고 삽입(CString::Insert)도 알아두면 좋음.

※함수 원형 및 설명
int Delete( int nIndex, int nCount = 1 );
//nIndex : 문자가 삭제될 시작 위치. 첫 문자의 위치는 0
//nCount : 삭제될 문자의 수
//반환값 : 삭제된 후의 문자열 길이

※예제
#include <atlstr.h>       //CString

#define print( str ) printf( "%s\n", str )

int main( )
{
	CString strText = "Visual Studio C++ 2013";

	print( strText );

	strText.Delete( 14, 4 );
	print( strText );

	return 0;
}


※결과

문자열 "Visual Studio C++ 2013" 중에서 "C++ " 부분을 삭제하여 "Visual Studio 2013" 만 출력되게 하였다.




 

※요약
CString::Insert : 문자 또는 문자열을 원하는 위치에 삽입한다.

※특징
문자나 문자 삽입 시, 맨 앞에 삽입하려면 0으로 하고 
맨 뒤에 추가하려면 문자열의 길이로 하면 된다.
필자는 Insert함수를 알기 전까지는 보통 CString::Mid를 이용하였으며, 삽입 말고 삭제(CString::Delete)도 알아두면 좋음.

※함수 원형 및 설명
int Insert( int nIndex, TCHAR ch );
//nIndex : 문자가 삽입될 위치 첫 문자의 위치는 0
//ch : 삽입될 단일 문자
//반환값 : 문자열의 길이

int Insert( int nIndex, LPCTSTR pstr );
//nIndex : 문자가 삽입될 위치 첫 문자의 위치는 0
//pstr : NULL로 끝나는 삽입될 문자열
//반환값 : 문자열의 길이

※예제
#include <atlstr.h>       //CString

#define print( str ) printf( "%s\n", str )

int main( )
{
	CString strText = "Visual2013";

	print( strText );

	strText.Insert( 6, " Studio " );
	print( strText );

	return 0;
}


※결과

"Visual2013"이라는 문자열 중간에 " Studio "라고 삽입한 결과로 "Visual Studio 2013"이 나온 걸 알 수 있다.





※요약

MFC 프로젝트의 속성 중 런타임 라이브러리의 속성이 위와 같이 다중 스레드 속성으로 된 프로젝트가 있을때, 
PreTranslateMessage( )에서 새로운 다이얼로그를 생성했다가 닫으면 아래와 같이 Debug Assertion Failed이 발생한다.
Assert라 Release모드에서는 발생하지 않고, 디버그에서도 무시하면 아무런 문제가 없지만 매우 찜찜하다.


※해결 방법
원인은 잊어버렸지만 해결방법은 기억에 있다.
아래와 같이 return TRUE;를 해주면 더 이상 발생하지 않는다.

+ Recent posts