※ 요약

아래 이미지와 같이 자식 다이얼로그를 모달리스로 생성하고 띄울때, 부모 다이얼로그(윈도우)가 항상 자식 다이얼로그 밑에 위치하는 경우가 있다. 이는 자식 다이얼로그를 생성할때 부모 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

※요약
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"이 나온 걸 알 수 있다.






※요약
CString::Replace : 문자 또는 문자열을 교체한다.

※특징
문자나 문자열에 '\'가 있을 경우, '\'를 하나 더 붙여줘야 한다.
이유는 '\'는 Escape문자이기 때문이다.

※함수 원형 및 설명
int Replace( TCHAR chOld, TCHAR chNew );
//chOld : 교체될 문자
//chNew : 교체할 문자
//반환값 : 교체한 문자 또는 문자열의 수

int Replace( LPCTSTR lpszOld, LPCTSTR lpszNew );
//lpszOld : NULL로 종결되는 교체될 문자
//lpszNew : NULL로 종결되는 교체할 문자
//반환값 : 교체한 문자 또는 문자열의 수

※예제

#include <atlstr.h>       //CString

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

int main( )
{
	CString strText1;
	CString strText2;

	strText1 = "String";
	strText2 = "C⁄C++";

	print( strText1 );
	print( strText2 );

	strText1.Replace( "Str", "Play" );
	strText2.Replace( "C++", "Java" );

	print( strText1 );
	print( strText2 );

	return 0;
}


※결과







※요약
Compare : 대소문자를 구분하여 문자열을 비교한다.
CompareNoCase : 대소문자를 구분하지 않고 문자열을 비교한다.

※특징
operator ==, !=, <, >, <=, >= 도 대소문자를 구분하여 CString의 문자열을 비교할 수 있으며
C언어 함수 중 strcmp, strncmp, stricmp, strnicmp 등과 비슷하다.
또 한 비교는 아스키코드를 기준으로 비교하므로 아스키코드표를 참고하면 된다.

※함수 원형 및 설명
int Compare( LPCTSTR lpsz ) const;
int CompareNoCase( LPCTSTR lpsz ) const;
//lpsz : NULL로 종결되는 비교할 문자열
//반환값 : 문자열이 lpsz보다 작을 경우 -1
//         문자열이 lpsz와 같을 경우 0
//         문자열이 lpsz보다 큰 경우 1

※예제

#include <atlstr.h>       //CString

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

int main( )
{
	CString strText1;
	CString strText2;
	CString strText3;

	strText1 = "ABC";

	//Compare - 대소문자 구분
	print( strText1.Compare( "ABC" ) );
	print( strText1.Compare( "abc" ) );
	print( strText1.Compare( "123" ) );

	//CompareNoCase - 대소문자 구분 안 함
	print( strText1.CompareNoCase( "ABC" ) );
	print( strText1.CompareNoCase( "abc" ) );

	return 0;
}


※결과

첫 번째는 ABC == ABC 이므로 0

두 번째는 ABC < abc이므로 -1

세 번째는 ABC > 123 이므로 1

네 번째, 다섯 번째는 대소문자를 구분하지 않음으로 둘 다 0




+ Recent posts