MIDAS LOG
Last updated
Was this helpful?
Last updated
Was this helpful?
적응
help.midasit.com (네트워크 환경 구성 등등)
모니터 신청, RAM 신청
각종 회원가입
개발환경 구성
C++ 공부
자기소개 PPT 발표 준비
MFC 공부
MFC로 전화번호부 구현 시작
Alt + O
Header file과 Source file같은 전환~같은 전환
Alt + G
함수의 선언과 구현부를 왔다갔다 함
Ctrl + G
원하는 줄로 이동함
Alt + Shift + S
심볼 찾기
Alt + Shift + O
파일 찾기
Alt + M
현재 파일의 함수 찾기
Shift + Alt + F
Reference 찾기
필요 없는 컴파일 경고 없애는 방법
밑에 처럼 하면 Test 경고는 출력이 안 되고, SubTest 경고는 출력된다.
mday 자기소개 발표!
이번 주 마무리
OpenSource 경진대회 휴가 계획 짜기
밀렸던 자료 정리
김남윤 교수님께 메일?
다음 주 할 일 미리 정리
MFC 인테리어 프로그램 개발 시작
먼저 설계부터 하자. MVC 생각하면서 설계하면 좀 편함
MVC 패턴에 기반한 기본 틀 완성!
MVC 패턴에 기반한 기본 틀 함수 추가, MVC에 따른 패키징!
DrawRoom, Select 구현
SAFE DELETE, 원하는 뷰 포인터 얻어오기
MFC 환경에서 console에 log 출력하는 법
c++에서 virtual을 붙여주게 되면 상속 관계에서 파생 클래스의 함수를 부르게 된다.
상속 관계에서 소멸자에 virtual을 붙여놓지 않는다면, 만약 업캐스팅한 객체는 해당 가리키고 있는 객체의 소멸자를 호출하지 않게된다. 그러므로 통상적으로 상속관계에 있는 클래스중 제일 상위 클래스의 소멸자에는 보통 virtual을 붙인다.
여기에서 하나 문제가 있다. 해당 객체의 type을 알 수 있는 c++의 typeid에서, 업캐스팅한 객체의 타입을 알고 싶었는데 가리키고 있는 객체의 타입이 아닌 자기 자신만 가리키는 결과가 나왔다. -> 해결방법으로 상위 클래스에 소멸자를 붙여주게 되면 하위 클래스의 소멸자를 호출하여 올바르게 가리키는 객체를 참조하는 결과가 나왔다. 그러므로 typeid를 쓰려면
알고리즘
기준 꼭지점을 정해야함
MouseDown 시 선택된 Shape의 기준 꼭지점과 클릭한 point와의 차이점을 구해놓는다.
MouseMove에서 구해놓은 차이와 현재 드래그 되는 좌표값을 더해준다!
그 값은 InteriorProgramView를 넘으면 안 된다.
그 외 프로그램 상 각종 예외처리
[09.12] Issue 1. 80% 해결
Move 성공!
Update 성공!
HowManySeleted 성공!
Current Selected 성공!
AddShape 미완
DeleteShape 미완
현재까지 각종 Error 체크 했을 시 오류 없었음!
천천히 생각하자. 오늘은 계속 어려운 것만 해결하다보니 많이 힘들었다. 그래도 천천히 많이 생각하고, 코드를 깨끗하게 구조를 깨끗하게 하다보니 오래 생각하면 계속 방법이 나왔다. 급하게 짜지 말고 좋은 방법을 찾을 것!
[09.13] Issue 2
DrawDoor
MoveDoor
DrawWindow
MoveWindow
AddShape
DeleteShape
마우스 우클릭 삭제 이벤트 구현했음
Door와 Window는 Room의 범위내에서 특정 크기 한정으로 그려져야한다.
그려지는 범위가 특정 어느 룸의 DrawRange 범위인지 찾고 거기서 각각 그려지는 방향에 맞춰서 고정할 부분을 고정하고 움직일 부분은 움직이며 그린다.
그 상황 속에서 선택된 룸은 그 문을 가지고 있다는 뜻으로 룸의 ShapeVector 인덱스를 기억하다가 마우스를 때면 전체 벡터에 문을 넣고, 해당 룸의 Door나 Window 벡터에도 객체를 담는다. m_nRememberIndexForDoorWindowVector
문과 창문의 자세한 알고리즘은 너무 기므로 생략 SetDoorWindowRange 라는 ShapeHandler의 멤버함수에 있다.
방을 삭제할 때는 그 방이 가지고 있는 Door와 Window 벡터를 모두 삭제하고 전체 벡터 상에서도 Door와 벡터를 삭제해야한다. 즉 둘다 삭제해야 하는데, 둘다 넣고 삭제하는 것이 쉽지 않았다.
물론 하나만 삭제할 때도 각각 다 삭제해줘야 한다.
그룹화 삭제 알고리즘 DeleteSelectedShape
의 함수를 보면 코드가 있다.
DrawDoor 해결
MoveDoor 미완 -> 룸의 범위를 벗어나게 하면 안 됨
DrawWindow 해결
MoveWindow 미완 -> 룸의 범위를 벗어나게 하면 안 됨
AddShape 해결
DeleteShape 해결
MoveDoor
MoveWindow
MoveGroup
Redo, Undo ( 딜리트 시 스택에 담으면 됨 )
Scale ( 마우스 휠 이벤트 처리기로 하기 )
Edit, Copy, Rotate ( 이벤트 처리기 리스너 만들어놈 )
User Object ( 마그네틱, 스냅 등등 )
Material ( 그냥 이미지 덮기 )
auto type은 말그대로 자동 할당이라는 말이다. c++의 컴파일러는 오른쪽에서 왼쪽으로 코드를 읽어들이는데 auto type은 대입문에서 오른쪽 변수의 타입을 자동으로 읽어 갖다 놓는다는 것으로 활용할 수 있다.
C++, 단순 반복문일 경우 for auto문을 활용하자, 속도면에서도 더 빠름
C++ 벡터에서 at 이런 거 안써도 [] 대괄호로 사용 가능했었음...ㅎㅎ
밑의 문장은 똑같은 일을 하는 반복문이다. 밑의 for auto문을 사용한 것이 훨신 간결하다!! ( iterator를 리턴함 )
어제 사용했던 삭제 알고리즘은 너무 많은 의존성과 벡터를 인덱스로 가지고 삭제한다는게 너무 바뀌어서 다 삭제!
새로운 알고리즘 도입
이상한 index 다 가질 필요 없이, 룸에 속한 문이나 창문은 룸을 포인터로 가지고 있는다. pInRoomShapePointer
항상 벡터의 삭제 구현은 뒤에서부터 할 것!!!!
코드가 정말 간결하고 깔끔해졌다...
선택된 방의 ID 값을 쓰레기 값으로 변경 tmpInRoomPtr->SetId(-600000);
먼저 방안의 문 벡터 창문 벡터를 모두 동적할당 해제 후 삭제
전체 Shape 벡터에서는 아이디 값이 쓰레기 값인 것을 삭제 후, 동적할당 해제
같은 요소를 벡터에 포인터로 넣은 것이기 때문에 모든 것이 끝난 후 동적할당 한번만 하면 됨 주의
주의! 특정 방 안의 문이나 창문 벡터는 포인터가 아닌 그냥 변수이기 때문에 다른 곳에서 값을 바꿔도 값이 바뀌지 않는다 때문에 값을 받을 때 &dynamic_cast<RoomShape *>
위와 같이 주솟 값을 받아야 한다!!
이것 때문에 3시간 해멘듯ㅎ
선택된 문이나 창문의 ID 값을 쓰레기 값으로 변경 tmpSelectedDoorPtr->SetId(-600000);
전체 Shape 벡터에서는 아이디 값이 쓰레기 값인 것을 삭제
문 벡터에서는 아이디 값이 쓰레기 값인 것을 삭제
같은 요소를 벡터에 포인터로 넣은 것이기 때문에 모든 것이 끝난 후 동적할당 한번만 하면 됨 주의
내가 어차피 각 Shape 마다 고유의 id 값을 만들어 놨다.
ShapeHandler가 map 이라는 것을 가지게 만들어서 key 값은 고유 id, value 값은 각 Shape의 포인터를 리턴하게 하면 정말 사용하기 쉬을 듯!
삭제의 각종 오류 해결, 자료구조 정리!!
추가 : 야근으로 해결 더 함ㅎㅎ, 설계를 잘 해놓으니 금방했음!
창문이나 문을 그릴 때 갖다 붙이면 두번째 Room에는 안 들어감! 코드 수정 해결!
Group Move 해결!!, 방안의 문이나 창문이 이상한 모양이 되지 못하게 해결 함
MoveDoor, MoveWindow 미완 -> 룸의 범위를 벗어나게 하면 안 됨
Redo, Undo ( 딜리트 시 스택에 담으면 됨 )
Scale ( 마우스 휠 이벤트 처리기로 하기 )
Edit, Copy, Rotate ( 이벤트 처리기 리스너 만들어놈 )
User Object ( 마그네틱, 스냅 등등 )
Material ( 그냥 이미지 덮기 )
Save Load As JSon ( 저장 로드 )
멘탈 나갔었지만 해결
로직 문제
이제 점점 프로그램이 커지다 보니 생각할 것이 매우 많아졌다. 하지만 범위를 계속 좁혀나가고 무슨 문제가 오류일까를 근본적으로 해결할 것!!
수학적인 공식을 대충하려 하지말고 완벽하게 해서 대입할 것, 그 부분이 나 스스로 확신이 안 들면 나중에 계속 거기 문제라고 생각함ㅠㅠㅠㅠ
포기하지 말고 다시 생각해보고 꾸준히 생각해보자
MoveDoor, MoveWindow
Copy
Scale
Redo, Undo ( 딜리트 시 스택에 담으면 됨 )
Edit, Rotate ( 이벤트 처리기 리스너 만들어놈 )
User Object ( 마그네틱, 스냅 등등 )
Material ( 그냥 이미지 덮기 )
Save Load As JSon ( 저장 로드 )
Magnetic 알고리즘 설계 (정말 사용자가 필요할 것이라고 생각되는 모든 경우에서 Magnetic이 됨!), 구현은 70%
알고리즘 설명
Redo, Undo ( 딜리트 시 스택에 담으면 됨 )
Edit, Rotate ( 이벤트 처리기 리스너 만들어놈 )
User Object ( 마그네틱, 스냅 등등 )
Material ( 그냥 이미지 덮기 )
Save Load As JSon ( 저장 로드 )
블록 범위의 문법을 사용할 수 있다.
중괄호 내에서 변수를 만들면 중괄호가 끝나면 사라지게 된다.
for문
내에서 int i
를 선언하고 끝나면 i
가 사라지는 것과 같다.
동일한 변수 이름을 사용할 수도 있지만 그건 좋은 생각은 아니다.
블록 범위의 개념을 사용할 수 있다.
특정 (하위) 목적을 달성하는 코드 블록을 단순히 분리하는 것이다.
조금 더 자세히 말하면, 한 덩어리는 일관된 개념과 목적을 가지고 사용할 수 있다.
이것을 이용하면 조금 더 가독성 있는 코드를 만들 수 있으며, 주석을 이용하면 남이 봐도 이해하기 쉬운 코드를 만들 수 있다.
예시
필요에 따라 리팩토링하는 코드, 테스트하는 코드를 넣어 사용할 수 있다.
UI 관련 클래스에서도 유용하다.
기타 장점
편집자가 접기 / 펼치기 기능을 쓸 수 있다.
일회용 메소드를 만들 기에는 좋지 않지만 개념적으로 나누어야 할 때, 이 문법을 이용해서 블럭 단위로 나누고, 다른 개념이 되는 코드 덩어리를 구성하여 사용하면 유용하다.
Magnetic, 구현 완벽히 다 됨!
각종 코드 정리, 구조 정리, 필요없는 변수 정리
UI, 필요없는 버튼 지우기
Redo, Undo ( 딜리트 시 스택에 담으면 됨 )
Edit, Rotate ( 이벤트 처리기 리스너 만들어놈 )
Save Load As JSon ( 저장 로드 )
User Object ( 마그네틱, 스냅 등등 ) -> 그냥 간단히, 색깔 다른 Rect로 만들 것
PNG 사진 찍는 기능 -> 단순한 api 이용
키보드 단축기
ctrl+c : 복사 구현
ctrl+v : 붙여넣기 구현
ctrl+x : 삭제 구현
Edit 구현
dbclick 구현
Menu 마우스 오른쪽 구현, 둘다 다 됨
Redo, Undo ( 딜리트 시 스택에 담으면 됨 )
Save Load As JSon ( 저장 로드 )
User Object ( 마그네틱, 스냅 등등 ) -> 그냥 간단히, 색깔 다른 Rect로 만들 것
PNG 사진 찍는 기능 -> 단순한 api 이용
키보드 단축기
ctrl+z : undo ( 이벤트 처리기 리스너만 만들어놈 )
ctrl+y : redo ( 리스너 만들었는데 안 불림ㅠ )
ctrl+s : 저장 ( 리스너 만들었는데 딴 거 불림 )
마우스 우클릭 메뉴
Rotate ( 이벤트 처리기 리스너만 만들어놈 )
UserObject
SetImageIcon, Add, Edit, Delete, Wheel, Copy Paste, Move, Magnetic, Select 구현
PNG 사진 찍는 기능 -> 단순한 api 이용
Redo, Undo ( 딜리트 시 스택에 담으면 됨 )
Save Load As JSon ( 저장 로드 )
마우스 우클릭 메뉴
Rotate ( 이벤트 처리기 리스너만 만들어놈 )
키보드 단축기
ctrl+z : undo ( 이벤트 처리기 리스너만 만들어놈 )
ctrl+y : redo ( 리스너 만들었는데 안 불림ㅠ )
ctrl+s : 저장 ( 리스너 만들었는데 딴 거 불림 )
UserObject
추 후 Room 그룹화 고민해 볼 것
이미지 Width, Height Edit 가능하게 하기 (비트맵 이미지 크기를 바꿔야됨)
코딩 규칙
클래스를 넘길 때, 값에 의한 호출을 하면 클래스가 생성이 되므로, 복사생성자를 만들지 않았을 시 올바른 복사가 이루어지지 않는다. 때문에 클래스는 참조를 통해 넘기거나 복사생성자를 만들어야하는데, 값에 의한 호출의 경우 어차피 값이 바뀌지 않으니 참조와 const를 이용해 값을 넘겨 사용한다.
박종봉 선배님
Filter의 개념
Feature, Member
개발 시작
CIM -> CIMc_ui, Feature, 3D, Filling
: 진짜 어려움... FormView가 생성이 안 되서 따로 만들어 줘야 함, 만들어진 자료 확인
: 첫 커밋, Controller의 싱글톤과 FileManager, Main의 define