inflearn logo
강의

講義

知識共有

MFC Windowsプログラミング - 基本

RGBカラー、ペン、ライン

pOldPen = dc.SelectObject(); 관련 질문

解決済みの質問

267

Learn

投稿した質問数 9

0

안녕하세요 선생님

강의에서 옛날 윈도우(XP)에서는 pOldPen = dc.SelectObject()를 안해주면 문제가 생길수 있고, 요즘 윈도우즈에서는 괜찮을거라고 하셨는데요.

이부분에 대해서 조금 더 자세하게 알고 싶습니다.

테스트용으로 코드를 작성했습니다.

 

void CPenBrushDemoView::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	CBrush NewBrush;
	//비트맵 클래스 객체를 선언하여 비트맵 리소스 로딩.
	CBitmap Bmp;
	Bmp.LoadBitmap(IDB_BITMAP1);
	//로딩된 비트맵 리소스로 패턴 브러시 생성.
	NewBrush.CreatePatternBrush(&Bmp);
	CBrush* pOldBrush = dc.SelectObject(&NewBrush);

	//클라이언트 뷰 클래스의 클라이언트 영역 크기를 알아내고
	//그 크기에 해당하는 네모를 그림.
	CRect Rect;
	GetClientRect(&Rect);
	dc.Rectangle(&Rect);
	dc.SelectObject(pOldBrush);

	DWORD style[] = {6, 3};
	LOGBRUSH lb;
	lb.lbStyle = BS_SOLID;
	lb.lbColor = RGB(255, 0, 0);



	// 여기서부터...

	CPen* pOldPen;

	CPen FirstPen;
	{
		FirstPen.CreatePen(PS_GEOMETRIC | PS_USERSTYLE | PS_ENDCAP_FLAT,
			20, &lb, 2, style);
		pOldPen = dc.SelectObject(&FirstPen);
		dc.MoveTo(40, 40);
		dc.LineTo(240, 40);
	}

	CPen SecondPen;
	{
		SecondPen.CreatePen(PS_GEOMETRIC | PS_USERSTYLE | PS_ENDCAP_FLAT,
			40, &lb, 2, style);
		dc.SelectObject(&SecondPen);
		dc.MoveTo(40, 240);
		dc.LineTo(240, 240);
	}

	{
		CPen ThirdPen;
		ThirdPen.CreatePen(PS_GEOMETRIC | PS_USERSTYLE | PS_ENDCAP_FLAT,
			60, &lb, 2, style);
		dc.SelectObject(&ThirdPen);

		dc.MoveTo(40, 440);
		dc.LineTo(240, 440);
	}

	dc.MoveTo(40, 640);
	dc.LineTo(240, 640);

	dc.SelectObject(pOldPen);
}

 

위 코드에서는 총 4개의 직선을 그리고 있습니다.

여기서, CPen ThirdPen은 스코프 안에서 소멸자가 불러질 때 DeleteObject()가 실행되면서 gdi는 없어집니다. 하지만 디바이스컨텍스트(dc)는 계속 해당 gdi를 가리키고 있습니다. 그런데 그 이후에 dc는 지워진 gdi의 방식대로 직선을 그리고 있습니다.(dc.MoveTo(40, 640); dc.LineTo(240, 640);) dc가 가리키고 있던 gdi가 지워졌는데도 불구하고 어떻게 기존의 방식대로 그릴수 있는지 이유를 모르겠습니다.

 

그리고 위의 코드에서,

dc.MoveTo(40, 440);

dc.LineTo(240, 440);

를 지우게 되면 ...

	{
		CPen ThirdPen;
		ThirdPen.CreatePen(PS_GEOMETRIC | PS_USERSTYLE | PS_ENDCAP_FLAT,
			60, &lb, 2, style);
		dc.SelectObject(&ThirdPen);

		// dc.MoveTo(40, 440);
		// dc.LineTo(240, 440);
	}

ThirdPen이 스코프를 벗어난 이후 마지막 직선은 ThirdPen의 방식이 아닌 SecondPen의 방식으로 그려지고 있습니다. 좀 전의 위에서 동작한 방식과 일관성이 맞지 않는것같아요.

 

질문글이 길어서 요약을 해보자면..

  1. 2개의 소스코드가 사소한 차이가 있는데 왜 DC가 동작하는 방식이 다를까요?

  2. DC와 GDI에 대한 저의 생각에서 혹시 오류가 있을까요?

     

c++ mfc gdi sdi vc++ win32api

回答 1

1

nullnull8537

저도 정확히는 알 수 없습니다. 그러려면 윈도우 GDI 관련 요소를 디버깅하고 분석해야 하기 때문입니다. 그러나 추정은 해볼 수 있을 것 같습니다. 조금 이상한(?) 실험용 코드입니다만...추정으로 말씀드리자면 아마도 지역변수로 선언된 CPen 클래스 인스턴스들이 아직 메모리에 남아있어서 발생한 문제로 보입니다.

모든 지역변수는 Stack 메모리를 사용합니다. 그리고 스택은 스코프를 벗어날 때 크기가 줄어듭니다. 하지만 그렇다고 기존 값을 모두 0으로 Clear하지도 않습니다. 그리고 우연히 위치가 맞는 지점에서 값을 읽는다면 기존의 값이 그대로 출력되기도 합니다. 이와 같은 문제는 자동변수인 지역변수의 주소나 참조를 반환했을 때 발생하는 문제와 매우 흡사합니다.

참고하시기 바랍니다. 😄

Reticle이 안나옵니다.

0

8

1

진행 방법 질문드립니다!

0

29

2

Singleton 관련 질문입니다.

1

31

2

2-I) 왜 이 문제가 그래프이론 카테고리에 있는지 잘 모르겠습니다.

0

54

2

AddGameFrameworkComponentReceiver vs AddExtensionHandler

0

24

0

scanf("%d\n") 의미

0

20

1

2주차 개념#12 트리 순회

0

25

2

책과 강의 질문

0

156

2

MFC로 게임 엔진 제작 질문

0

175

2

이벤트 메시지 루프의 '응답 없음'에 대하여

0

136

2

그려진 도형 선택(Z-order 변경)부분[9분59초경]

0

92

2

메모리 창을 어떡해 뛰우나요?

0

164

3

안녕하세요 선생님

0

114

1

토글메뉴(강사도 삽질) 10:30 질문 / pch.h 전역변수 선언 에러

0

171

2

CMainFrame과 CCreateDemoView와의 관계 (교과서 p80 그림3-3)

1

109

1

메시지 루프에서 메시지 처리 성능 비교: WinAPI vs MFC

0

273

3

커스텀 드로우에 대해서도 다루나요?

0

187

2

MainFrame 에서 LButtonDown 이벤트 처리 질문

0

166

1

윈도우 프로그래밍 UI 관련 질문입니다

0

230

2

유튜브 강의와 차이점

0

316

1

책 질문입니다.

0

283

2

mfc 내부에서 콜백 함수 구현 방법

0

391

1

수강기간 무제한인지 문의드립니다!

1

453

1

라디오 버튼 그룹에 대해서 질문합니다.

0

302

1