*** 공부 방법 ***
1. 코딩을 해야 하는 부분은 첫 부분에 변수나 함수, 메소드에 대한 선언이 코드블럭으로 표시되어 있다. //ex) MakeFunction(); 2. 코드블럭 하단에는 해당 선언에 대한 구현 로직이 작성되어 있다. 처
hyrule.tistory.com
class EditDlg
- 지난 번에 텍스처를 로드하는 과정까지는 완료했다.
- 이번에는 텍스처 파일을 불러와 특정 텍스처 파일로 타일맵을 만들어 보자.
< 다이얼로그 창 >
- ' 이미지 불러오기 ' 버튼을 하나 생성해준다.
< WinProc() >
- 버튼이 눌릴 시 LoadTexture() 메소드를 호출한다.
< LoadTexture() >
- '파일 열기' 대화창을 불러와서 파일을 열어주어야 한다.
- 과정은 다음과 같이 정해져 있다.
TCHAR FilePath[MAX_PATH] = {};
OPENFILENAME OpenFile = {};
OpenFile.lStructSize = sizeof(OPENFILENAME);
OpenFile.hwndOwner = m_hDlg;
OpenFile.lpstrFilter = TEXT("모든파일\0*.*\0BmpFile\0*.bmp");
OpenFile.lpstrFile = FilePath; // FilePath 에 풀경로가 들어온다.
OpenFile.nMaxFile = MAX_PATH;
OpenFile.lpstrInitialDir = CPathManager::GetInst()->FindPath(TEXTURE_PATH)->Path;
if (GetOpenFileName(&OpenFile) != 0)
{
{ OPENFILENAME OpenFile }
- 파일 열기 창의 기본 설정을 전달해주기 위한 구조체이다.
.hwndOwner 어떤 윈도우 핸들에서 호출한 것인지, 어떤 파일을 열 것인지,
.lpstrFilter 어떤 확장자를 보여주어야 하는지
.lpstrFile 파일 열기를 한 후에 주소를 담을 변수 주소
.nMaxFile 경로 최대 길이
.lpstInitialDirl 기본값 경로 설정. 우리는 텍스처 파일을 불러올 것이므로 CPath 클래스에서 텍스처 폴더의 주소를 받아와서 넘겨준다.
< GetOpenFileName(&OpenFile) != false >
- 파일 관리자로부터 결과를 얻어온다.
- Bool 변수를 반환한다. true 반환 시 정상적으로 로딩했다는 것이다.
< _wsplitpath_s / _splitpath_s >
- 파일 경로를 분해한다. 드라이브 명, 경로 명, 등등 다양하게 분리 가능하지만, 우리가 가져올 것은 '파일명'이다.
- 위에서 받아온 주소에서 파일명만 분리 추출해 준다.
-- '파일명'만 딱 들고와서, 이것을 텍스처맵의 Key로 사용할 것이다.
- _wsplitpath_s(경로, 드라이브 받아올 문자열, 문자열의 크기, 경로 받아올 문자열, 문자열의 크기, 파일명 받아올 문자열, 문자열의 크기, 확장자 받아올 문자열, 문자열의 크기)로 구성되어 있다.
-- 우리는 파일명만 받아오면 된다. 나머지 문자열 주소는 nullptr, 문자열 크기는 0으로 해주면 된다.
< WideCharToMultiByte >
- 텍스처를 보관하는 map의 Key는 현재 멀티바이트 문자열로 받고 있으므로, 유니코드 문자 집합을 사용하고 있는 경우 변환 과정이 필요하다.
-- #ifdef를 이용해서 변환한다. 멀티바이트 문자 집합일 경우 그냥 복사만 해주면 된다.
- 이제 로드 전 경로 준비는 끝났다. 여기까지만 해놓고 파일을 로드하면 메시지박스에 경로를 출력하게 하여 작동하는지 확인해 보았다.
[ 다이얼로그 창 ]
- 이제 로드한 텍스처 목록을 볼수 있게 해주어야 한다.
- 도구 목록에서 'List Box' 를 추가하자.
- ID를 ID_LIST_TEXTURE로 바꿔 주고, 정렬은 false로 바꿔준다.
- 여기에 로드된 텍스처의 목록을 전달해주어야 한다.
< Init() >
{ HWND m_hListBoxTexture = GetDlgItem(m_hDlg, IDC_LIST_TEXTURE) }
- 윈도우 핸들 구조체에 리스트박스의 핸들을 얻어온다.
- 다시 < LoadTexture() > 로 돌아와서,
< SendMessage(m_hTextureListBox, LB_ADDSTRING, 0, (LPARAM)FileName) >
- 핸들로 메시지를 전달하는 함수이다.
- 지금은 리스트박스 핸들(인자 1)에,
문자열을 추가(인자 2),
WPARAM에 전달할 내용 - 0을 전달(인자 3),
LPARAM에 전달할 내용 - 파일이름 문자열을 전달(인자 4)
하고 있다.
- 텍스처를 추가하면, SendMessage를 통해서 텍스처 파일의 이름을 리스트박스에 전달해주는 역할이다.
- 마지막으로, 파일 열기에서 받아온 FullPath를 이용하여 SceneResource로 접근하여 텍스처를 로드해준다.
- 컬러키는 일단 255, 0, 255로 셋팅해준다.
< WndProc() >
- 리스트박스에 내용을 보냈다면, 다시 받아오는 작업도 필요할 것이다.
- 수신도, Message를 통해서 한다.
case IDC_LIST_TEXTURE:
switch (HIWORD(wParam))
{
case LBN_SELCHANGE:
g_Dlg->SelectTexture();
break;
}
break;
- IDC_LIST_TEXTURE 메시지를 통해서 들어오고,
- 전달된 내용은 wParam의 HIWORD 부분을 통해 들어온다.
-- wParam에서 리스트의 선택이 바뀌었다고 메시지가 전달되면, SelectTexture() 메소드를 호출하여 현재 선택된 텍스처를 바꿔준다.
<< SelectTexture() >>
{ CSharedPtr<class CTexture> m_SelectTexture }
- 선택된 텍스처의 주소
{ int m_SelectTextureIndex }
- int 타입의 인덱스를 저장할 변수를 하나 만들어주고,
'-1'로 초기화한다. 인덱스는 0부터 시작이므로 -1이면 인덱스가 선택되지 않았다는 의미이다.
< m_SelectTextureIndex = (int)SendMessage(m_hTextureListBox, LB_GETCURSEL, 0, 0) >
- 메시지를 통해, 현재 리스트에서 선택된 게 몇번째 것인지 인덱스를 얻어올 수 있다.
- m_SelectTextureIndex -1이 아닌 값이 들어왔다면, 리스트의 인덱스를 얻어온 것이다.
{ TCHAR m_SelectTextureName[MAX_PATH] }
- 받아온 인덱스에 적혀있는 문자열을 받아오기 위한 변수.
- 매번 받아오기 전 memset을 통해 0으로 초기화해준다.
< SendMessage(m_hTextureListBox, LB_GETTEXT, m_SelectTextureIndex, (LPARAM)m_SelectTextureName) >
- m_SelectTextureIndex 변수에 -1이 아닌 값이 들어온게 확인되었다면, 이번엔 리스트박스로부터 텍스트를 얻어온다.
- LB_GETTEXT 메시지를 전달하고, wParam에 인덱스 번호, lParam에 텍스처 이름 문자열을 받아올 주소를 전달하면 된다.
- 문자열을 받아오는 과정이 끝났으면 다시 m_SelectTextureIndex를 -1로 초기화 해준다.
- 이름을 얻어왔으면, 아까처럼 #ifdef문을 사용하여 파일명을 멀티바이트로 변경하고,
FindTexture() 함수에 이름을 넣어 주소를 받아온 것을, m_SelectTexture에 넣어준다.
- CEditScene의 SetTileTexture() 메소드를 호출하여 선택된 텍스처로 그리도록 해준다.
CTileMap::SetTileTexutre()로 전달만 해주면 된다.
- 코드를 작성한 뒤 정상 작동하는지 확인해 보았다.
'WIN32API FrameWork > 한단계씩 직접 구현' 카테고리의 다른 글
73. 타일맵 에디터 4: 기타 기능 추가. (0) | 2022.06.14 |
---|---|
72. 타일맵 에디터 3: 스프라이트 텍스처의 프레임 좌표 지정 (0) | 2022.06.14 |
70. Font 관련 수정 (0) | 2022.06.13 |
69. 타일맵 에디터1: 제작 및 타일맵 불러오기 (0) | 2022.06.12 |
68. 타일 맵 (0) | 2022.06.10 |