우와. 포스팅량이 늘었군요. 자축 자축.
에... 2부에서 예고했던데로 커서를 그려보고 왔습니다.
사실 만드는건 한 시간도 안걸렸는데 놀다보니(...) 포스팅이 좀 늦어졌네요.
별것도 아닌데 3부를 괜히 날려먹는거 아닌가? 몇 부작으로 갈 생각이지? 라는 생각은 저 멀리 다른 차원으로 집어던져버리고 빨리 코드를 살펴보겠습니다.

일단 간단하게 한개만 인클루드 해보죠.

#include <usp10.h>

좋습니다. 자 이제 함수 하나를 만들어 보겠습니다.

// 귀찮으니 전역 변수로 때워봅시다.
SCRIPT_CONTROL ScriptControl;
SCRIPT_STATE ScriptState;
SCRIPT_STRING_ANALYSIS analysis = nullptr;

void InitScriptStringAnalysis(HDC hdc, std::wstring str)
{
	if ( analysis == nullptr )
	{
		ZeroMemory(&ScriptControl, sizeof(ScriptControl));
		ZeroMemory(&ScriptState, sizeof(ScriptState));
		ScriptApplyDigitSubstitution(nullptr, &ScriptControl, &ScriptState);
	}
	else
		ScriptStringFree(&analysis);

	ScriptStringAnalyse(hdc, str.c_str(), str.length() + 1,
						str.length() * 1.5 + 16,
						-1,
						SSA_BREAK | SSA_GLYPHS | SSA_FALLBACK | SSA_LINK,
						0,
						&ScriptControl,
						&ScriptState,
						nullptr,
						nullptr,
						nullptr,
						&analysis);
}


으음. 뭐. 그럭저럭 테스트 해볼만 한 함수가 나왔습니다.

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	static HIMC imeID = nullptr;
	static std::wstring str;

	wchar_t debug[256] = { 0 };
	static int x = 0;

	RECT rect = { 0, 0, 0, 0 };

	switch ( message )
	{
		case WM_ACTIVATE:
			if ( imeID == nullptr )
			{
				imeID = ImmCreateContext();
				ImmAssociateContext(hWnd, imeID);
			}
			break;
		case WM_IME_STARTCOMPOSITION:
			break;
		case WM_IME_CHAR:
			str.push_back((wchar_t)wParam);
			InvalidateRect(hWnd, NULL, TRUE);
			break;
		case WM_CHAR:
			if ( (wchar_t)wParam == '\b' )
			{
				str.pop_back();
			}
			else
			{
				str.push_back((wchar_t)wParam);
			}
			InvalidateRect(hWnd, NULL, true);
			break;
		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);
			// DT_CALCRECT옵션은 출력할 글자의 범위를 구하는 옵션입니다.
			// 따라서, 아래 함수를 호출하게 되면 rect변수에 출력할 글자의 범위를 구해서 던져줍니다.
			// 여기에서 우리는 top와 bottom만 필요합니다. 전체 width 는 필요 없으니까요.
			DrawText(hdc, str.empty() ? L"A":str.c_str(), -1, &rect, DT_CALCRECT | DT_CENTER);
			DrawText(hdc, str.c_str(), str.length(), &rect, DT_CENTER);

			// 이 함수를 호출하게 되면 ScriptStringCPtoX를 사용하기 위한
			// SCRIPT_STRING_ANALYSIS 를 얻게됩니다. 자세한 내용은 MSDN을 참고해주세요.
			InitScriptStringAnalysis(hdc, str.c_str());
			ScriptStringCPtoX(analysis, str.length(), false, &nTrail);

			// 커서를 그립니다. DrawText에서 얻어온 글자의 출력 범위를 top와 bottom 으로 하고,
			// ScriptStringCPtoX에서 얻어온 마지막 글자 인덱스의 위치를 left로 하고 여기서 1을 더해 width가 1인
			// 사각형을 그립니다.
			Rectangle(hdc, x, rect.top, x + 1, rect.bottom);
			wsprintf(debug, L"커서 위치 : %d %d %d %d", x, rect.top, x + 1, rect.bottom);
			SetWindowText(hWnd, debug);

			EndPaint(hWnd, &ps);
			break;
		case WM_DESTROY:
			ImmDestroyContext(imeID);
			PostQuitMessage(0);
			break;
		// 코드가 길어져서 기본 프로시저 함수에서 수정되지 않은 이벤트는 쓰지 않았습니다.
	}
	return 0;
}

자 그럼 사진을 하나 투척해보죠.


짞짞짞.

으음. 하지만 커서가 안움직이니 뭔가 허전하군요. 명색의 커서인데 움직여야 하지 않겠어요? 움직였으면 움직인 자리에 무언가 입력하거나 삭제도 되야죠.
으음.. 한번 해보죠. 재밋을거같으니.

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	// 기존 변수 생략
	static int nowPosition = 0;

	switch ( message )
	{
		case WM_ACTIVATE:
			if ( imeID == nullptr )
			{
				imeID = ImmCreateContext();
				ImmAssociateContext(hWnd, imeID);
			}
			break;
		case WM_IME_STARTCOMPOSITION:
			break;
		case WM_IME_CHAR:
		case WM_CHAR:
			if ( (wchar_t)wParam == '\b' )
			{
				if ( nowPosition == str.length() )
				{
					str.erase(nowPosition - 1);
				}
				else
				{
					// 중간 문자를 삭제하기 위한 코드입니다.
					const wchar_t* strBack = str.c_str();
					strBack = &strBack[nowPosition];

					str.erase(nowPosition - 1);
					str.append(strBack);
				}
				nowPosition = nowPosition - 1 < 0 ? 0:nowPosition - 1;
			}
			else
			{
				// 중간에 글자를 삽입하기 위해 insert로 바꾸었습니다.
				str.insert(nowPosition, (wchar_t*)&wParam);
				nowPosition = nowPosition + 1 > str.length() ? str.length():nowPosition + 1;
			}
			InvalidateRect(hWnd, NULL, true);
			break;
		case WM_KEYDOWN:
			if ( (int)wParam == VK_LEFT )
			{
				nowPosition = nowPosition - 1 < 0 ? 0:nowPosition - 1;
				InvalidateRect(hWnd, NULL, true);
			}
			else if ( (int)wParam == VK_RIGHT )
			{
				nowPosition = nowPosition + 1 > str.length() ? str.length():nowPosition + 1;
				InvalidateRect(hWnd, NULL, true);
			}
			break;
		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);
			DrawText(hdc, str.empty() ? L"A":str.c_str(), -1, &rect, DT_CALCRECT | DT_CENTER);
			DrawText(hdc, str.c_str(), str.length(), &rect, DT_CENTER);


			InitScriptStringAnalysis(hdc, str.c_str());
			ScriptStringCPtoX(analysis, nowPosition, false, &x);

			Rectangle(hdc, x, rect.top, x + 1, rect.bottom);
			wsprintf(debug, L"커서 위치 : %d %d %d %d", x, rect.top, x + 1, rect.bottom);
			SetWindowText(hWnd, debug);
			EndPaint(hWnd, &ps);
			break;
		case WM_DESTROY:
			ImmDestroyContext(imeID);
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

이 기세라면! 마우스로 클릭해서 커서를 옮기는 것도 가능할거같군요. 확인해 보는것도 좋겠지만 이번 편은 ScriptString를 테스트해보기 위한 편이었으니 그냥 안할려고 합니다 ㅇㅅ.
작동되는거 확인했으니 됐죠 뭐 ㅋㅅㅋ.

이번에는 GDI로 직접 EditBox를 만들어 보았습니다. 코드는 좀 지저분하지만 어떠신지요?
중복된 코드를 지우기 위해서 WM_IME_CHAR에 keybd_event로 VK_RIGHT를 누르게 해 보았는데 왜인지 모르겠지만 한글 타이핑에 문제가 생기더군요.
원인을 모르겠네요. 아시는분 알려주시면 감사하겟습니다(_ _ )

그런고로! 다음에는 DirectX11에 직접 적용시켜 볼 차례군요.
자 그럼 다음시간에! (언제가 될지 모르겠지만 노력해 보겠습니다..)

커서 위치에 주목!

이전 글에서 글자를 출력 했으니 글자를 입력하는 방법을 알아야겠죠. EditBox를 만들어야 하는데 입력이 안되면 쓰나요.
누구나 Windows 프로그래밍을 처음 배울 때 키보드에서 입력하면 영어만 입력되는 아주 간단하지만 매우 의미있는 프로그램을 만들어 본 적이 있을거라 믿습니다.
허나 제가 원하는건 저번 시간에도 말했듯이 채팅이 되는 온라인 게임이란 말입니다. 근대 영어만 입력되면 쓰나요. 요즘 초등학생들이 영어 실력이 워낙 뛰어나다 보니 영어만 입력되도 상관 없을지도 모르겠지만 제가 영어를 못해서 한국어를 써야한다 이 말입니다. 그 뿐입니까? 해외 사용자도 배려해서(영어를 쓰면 되겠네요) 중국어라던가 일본어라던가도 입력 가능하게 해야한다 이말입니다!(그러니까 영어를 쓰면 된다고.)

그럼 어떻게 영어말고(어이) 다른 나라 언어를 입력 할 수 있을까요?
우리가 사용하는 EditBox는 IME라는걸 이용해서 글자를 입력받습니다.
좋습니다. 그럼 우리도 EditBox를 만드는 거니 이 녀석을 사용해보죠.

IME를 Windows에서 이용하기 위해서는 imm.h와 imm32.lib가 필요합니다. Windows.h를 인클루드 하시면 기본적으로 포함되어 있습니다.

자 그럼 잠시 살펴보죠.
일단 Win32 프로젝트를 하나 만듭니다. 귀찮으니 자동 생성 코드를 사용해서 만듭니다.(어차피 테스트하고 버릴거기 때문에 상관 없습니다.)

윈도우 프로시져 콜백 함수를 보시죠. 으음. IME를 언제 프로그램에 등록하면 좋을까요? 보통 EditBox는 창에 포커스 상태일 때 입력을 받습니다.
Focus 상태일 때 메시지를 MSDN에서 확인하는건 테스트 프로그램 만들 때 너무 귀찮으니 그냥 ACTIVATE 메시지를 이용해서 해보죠.(너무 대충이잖아 wwwwwww)

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	static HIMC imeID = nullptr;
	static std::wstring str;

	switch ( message )
	{
		case WM_ACTIVATE:
			if ( imeID == nullptr )
			{
				imeID = ImmCreateContext();
				ImmAssociateContext(hWnd, imeID);
			}
			break;
		case WM_IME_STARTCOMPOSITION:
			break;
		case WM_IME_CHAR:
			str.push_back((wchar_t)wParam);
			SetWindowText(hWnd, str.c_str());
			break;
		case WM_CHAR:
			if ( (wchar_t)wParam == '\b' )
			{
				str.pop_back();
			}
			else
			{
				str.push_back((wchar_t)wParam);
			}
			SetWindowText(hWnd, str.c_str());
			break;
		case WM_DESTROY:
			ImmDestroyContext(imeID);
			PostQuitMessage(0);
			break;
		// 나머지 메시지는 변경사항 없으므로 생략.
	}
	return 0;
}

발로 짜도 저것보단 잘 나오겠군요. 뭐 쓰고 버릴 코드니까 간단하게 테스트해보죠.

잘 되는군요. 중간에 일본어로 바꿔서 입력해도 잘 됩니다. 글자 변환도 잘 되구요.


이건 덤 입니다. 다음에 사용할 ScriptString 관련 함수들을 사용해서 간단히 테스트한거죠.
짤막하게 설명하자면 지금 Client 좌표계 기준으로 X=79 좌표에 '.'이 있는데 이 인덱스가 7이라는겁니다.
이게 왜 필요할까요?
마우스로 클릭하면 커서가 옮겨져야죠. 저희는 Client의 어떤 좌표에 어떤 글자가 써져있는지 알아야하니까요.


여기서 글을 끝내기로 하겠습니다 ㅇㅅㅇ.
다음에는 DirectX 프로그램에 실제로 적용해 보기 전에 GDI+로 커서를 구현해보도록 하겠습니다.

DirectX9와 10은  DXUT에 기본적으로 EditBox가 들어있습니다. 물론 아름답지 못하지만 나름 커스터마이징이 가능하더군요.
그 외에 약간의 버그같지 않은 버그라고 하면 한/영키로 한영 전환을 해도 여전히 인디게이터에 '가'라고 표시된다는 거랄까요 ㅋㅅㅋ.
이건 전에 고쳤었는데 굳이 소스를 보관할 가치를 못느껴서 포맷할때 같이 버렸던걸로 기억합니다. 조금 아쉽네요.

그래서 이번 주제는... DirectX11에도 EditBox를 만들어보자 입니다.
미리 말씀드리지만 이 글은 완결이 안날 수도 있습니다. 에 그러니까 갑자기 글이 뚝 끊기고 엉뚱한 XBMC 버그가 고쳐지는 글이 올라올지도 모르고 시작에서 멈출 수 있다는거죠. 또한 만약 막 DX에 입문하신 분이 희망찬 마음을 가지고 이 글을 읽기 시작하실까봐요... 사전에 일러두자면 저도 입문자라(...) 많은 도움은 드리지 못할거란 사실은 인지해 주셨으면합니다.

아니, DirectX에 왜 EditBox가 필요하죠? DX로 뭘 만들 작정이십니까?
EditBox를 DX에서 만든다고 하면 저런 질문이 먼저 들어오더군요. 뭐 보통 선배분들께 조언을 구한지라 저렇게 존댓말이 아니었지만요 ㅋㅅㅋ.
이유는 간단합니다. 채팅해야죠. 제가 원하는건 채팅이 되는 온라인게임이라 이말입니다.
그리고 한 가지 이유가 더 있는데 나중에 트위터랑 연동시켜서 귀여운 캐릭터가(...) 멘션을 알려주거나 작성한 트윗을 보내주는 등의 기능을 만들겁니다.
그 언제 만들어 질지 모르는 프로그램을 위해서(귀여운 캐릭터 모델이 있으면 완성될지도.) 한 번 노력해보죠.

왜 OpenGL이 아닌가요?
이유는 간단합니다. 제가 DirectX를 졸라 좋아하거든요. 뭐 미련맞은 짓이죠. 그래서 위에 써놓았지만, 이 글은 중간에 멈출 수도 있습니다.
OpenGL을 쓰면 EditBox를 구현할 필요가 없냐 라고 묻는다면 역시 그건 또 아니지만 뭔가 다른 방법이 있지 않을까 싶습니다.

자 그럼 혼자 질문하고 혼자 답하는 재미없는 글은 그만쓰고 어서 코드를 살펴보죠.

제가 이 글을 쓰기 위해 준비한 준비물은 다음과 같습니다.

DirectX SDK Sample - CustomUI
Direct2D - DirectWrite.
DirectX11.

자 그럼, 궁극적으로 EditBox는 뭐를 해야 할까요?
물론 글씨를 편집해야죠. 그러기 위해선 일단 글자를 출력해야합니다.

글씨를 출력한다. DirectX에서 글씨의 출력은 어떻게 해야 하는 걸까요?
렌더링을 해야합니다. 텍스쳐를 만들고 그 위에 글씨를 써서 렌더링 해야 합니다.

지금 '여보쇼, 이게 무슨 강아지 엿 씹어 먹는 소리야? 한글이 몇 글자 인줄 알아? unicodmap에서 hangul을 검색해서 나오는 카테고리의 모든 글자 수를 더하면 자그마치 11,524자나 된다고. 이걸언제 다 텍스쳐로 만들어서 로드하고 있어?' 라고 생각하신분 계시면 블로그 닫기 전에 잠시만 기다려주세요.
막 구글검색 하다가 미처 발견하지 못하신것 같은데 '순수하게' DirectX11만 사용한다면 당연히 그런 삽질을 해야겠지만 MS가 그렇게 멍청하게 DX를 만들어 놓진 않았습니다.
DXGI(DirectX Graphics infrastructure)를 사용하면 동기화된 공유 Surface를 만들 수 있다 이겁니다.

으음. 제가 개 엿씹어 먹는 수준의 설명을 하고있는것 같으니 이쯤에서 그냥 링크를 하나 뿌리죠. 이 링크 하나면 모든 설명이 끝납니다.
(절대로 코드를 올리기가 귀찮은게 아닐거라고 제 자신을 속여ㅂ...)

http://www.braynzarsoft.net/index.php?p=D3D11FONT

저 링크에 이 글의 모든게 들어있습니다. 사실 저는 윗 글을 보고 만들었거든요.
뭐 윗 글을 살짝 변형해서 설치 된 폰트가 아닌 어딘가의 경로에 별도로 있는 폰트를 로드 가능하게 수정했지만 그리 어려운 작업은 아닙니다.

영어가 보기 귀찮으시다면 어쩔수 없지만 이대로 글을 맺자니 사진도 없고 뭔가 허전하니 일단 뭐라도 써보죠.

위 링크에 들어가서 영어 말고 코드를 대충 읽고 오시면 대략적으로 다음과 같은 방법으로 진행된다는걸 아실겁니다.

DX11 디바이스를 생성합니다. 뭐 기타 등등의 렌더링에 필요한 초기화는 여러분이 만드신(혹은 쓰시는) 프레임워크나 라이브러리에 아주 잘 만들어놓여져있겠죠.
DX10 디바이스를 생성합니다. 뭐 렌더링 할건 아니구 공유 텍스쳐를 만들때 잠깐 사용되니 생성만 하시면 됩니다.
DX11 텍스쳐를 만듭니다.
위에서 만든 텍스쳐를 이용해 DX10과의 공유 텍스쳐를 생성합니다.
D2DFactroy를 하나 만들어서 DXGI의 Surface를 렌더 타겟으로 지정한 ID2DRenterTarget 객체를 하나 만듭니다.
ID2DRenterTarget을 이용해서 공유 텍스쳐에 글씨를 그리고
마지막으로 DirectX11 디바이스 컨텍스트에 텍스쳐를 3번째 단계에서 만든 텍스쳐로 설정하고 사각형 하나를 렌더링합니다.

끝.

왜 DX10 디바이스를 생성할까요? 위 링크에서 보면 마이크로소프트에서 충분한 종류의 DirectX11과 직접적으로 작동하는 Direct2D를 만들지 않았다고합니다.ㅜㅜ
뭐 그러니 DX10 디바이스를 생성해서 잠시 쓰는거죠 ㅇㅅㅇ.

프레임을 생각하면(이게 의외로 프레임 저하 현상이 심각합니다.) 초기 한번만 텍스쳐를 만들고 그 이후로는 만들어진 텍스쳐를 사용하는게 유리할 것 같습니다.
그러니까 어떤 문자를 처음 띄울 때는 텍스쳐를 생성하고 그 이후에는 만들어진 텍스쳐를 계속해서 사용하는거죠.

자 그럼 2부가 만들어지길 바라며 글을 마치죠.

사용된 폰트는 구글에서 배포한 NotoSansCJK-Regular.OTF입니다. 어떻게 설치되지 않은 폰트를 로드하는지는 다음에 시간나면 써보겠습니다. 하지만 Direct2D를 이용하면 어렵지 않은 일이니 Visual Studio의 인텔리센스 기능을 이용해서 잠시 함수를 뒤적거리시다가 삘 꽂히는 함수 하나를 발견 하신 다음에  MSDN을 뒤져보면 금방 찾으실 거라 믿습니다.

Windows 8 의 토스트 알림이 너무 맘에들어서 이걸로 무언가 개발해보려고 시작한거십니다.
Visual Studio 2012 이상의 버전이 필요합니다. 확인해 주세요.

Visual Studio 를 실행해서 C# 프로젝트 템플릿을 보면.. 스토어 앱에는 여러가지가 있는데 정작 Desktop App는 Windows 8 이상 버전만 지원하는 프로젝트를 디폴트로 생성 할 수 있는 무언가가 없습니다. (데스크탑 앱좀 챙겨달라구!!)

뭐 그냥 아무 프로젝트나 눌러서 만드시면 됩니다. 일단 만들어야 무언가 시작되니까요.


그 다음 Visual Studio가 아닌 기타 타 편집기로 csproj 프로젝트를 열어보면 XML 형식의 옵션들이 막 보이는데
PropertyGroup<TargetPlatformVersion>8.0</TargetPlatformVersion> 을 추가해주세요.

그 다음 다시 Visual Studio 로 돌아오면 다시 로드하겠냐고 물어보는데 당연히 모두 예를 눌러줍니다.

참조에서 C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral\Windows.winmd 를 추가 할 수 있으면 성공입니다.


이후 기타 등등의 필요한 winmd 파일이 있으시면 참조 추가해서 마음껏 쓰시면 됩니다.

winmd에 관한 설명은 MSDN을 참고해주세요.

샘플.




해골책에 나와있는 키프레임 애니메이션에 대해 얻은것...


해골책에서 3DS Max 작업한 내용물을 XML로 저장하는데....

3DS Max 에서 작업을 내가 왜함 ㅋㅋ 라면서 개무시까고 XML을 안 살펴봤다가 키프레임 애니메이션에서


"대체 애니메이션 키값이 어디 저장되어있는건데?"


에 대해 한참 소스코드 뒤지다가 문득 XML을 뜯어보고 싶어져 뜯어보니 프레임마다 지정되어있어서 20분간 좌절..

이외에 해골책의 소스코드가 복잡한건지 내가 멍청한건지 왠지 분석이 안되네요.ㅎㅎ.

망할놈의 상속은 코드의 기독성을 매우 떨어뜨려주는 아주 행복행복한 녀석이군요.


뭐 그거야 그렇다고 치고;


오늘 슬라이드 걸 이란 게임에서 배포한 캐릭터 모델을 잠시 사용해 볼까 했는데


.X 파일과 FBX 파일 두개 face 텍스쳐가 좌표가 이상하길래 뭐지뭐지 했는데 시계방향으로 한번 돌려주니 잘되는군여 ㄱ-..

이런 함정을 숨겨놓다니.

한창 이걸로 애니메이션을 어케 만들지 생각하고있는데 .X에도 애니메이션 값이 있었습니다 ㅇㅂㅇ;

그런데...

어떻게 로드해야 하는지 모르겠네여.... 진짜 모르겠음.

D3DXLoadMeshHierarchyFromX 이걸로 얻어온다는건 대충 알겠는데 말이죠.

중요한건 인자값으로 전달해 줘야 하는 ID3DXAllocateHierarchy 이녀석이 요구하는게 대체 뭔지 모르겠습니다.

순수 가상함수 인걸 보면 상속받아서 작업해야 하겠는데.. 대체 무슨 함수를 어떻게 완성시키라는건지;

MultiAnimation 이라는 DirectX SDK Sample 소스에 보면

셰이더와 x 파일을 사용해 무엇인가 하고 있는데 DXUT에 대해 아무것도 모르니 소스 분석 불가능 ㅁㄴㅇㄹ...

애초에 처음 보는 온갖 #define 문에 정신이 날아가버렸네요..

DX... 누가 마소에서 만든거 아니랄까봐.. 별별 이상한게 다있더군요 ㄱ-..


일단.. 분석도 안되는 SDK 소스 따위 버려두고 해골책이나 마저 공부해야겠네여 ㅠㅠ

오랜만에 글써보내요 ㅇㅅㅇ...

요즘 여러가지로 바빠서요;;


다름이 아니라 ... 

해킨토시로 바꾸고 나서 XCode 를 사용하고 있었습니다.

그이유는 Emacs 의 버그로 인해 한글의 일부가 깨져서 나오는 현상 때문이었는데요,

한글이 아니라 심지어 영어까지 깨져서 나오는 현상이 발생했었습니다.

폰트를 바꾸면 해결이 되는 문제였지만, 한글이 지원되는 폰트는 전부다 깨져서 나오는듯한 기분이 들더군요..

그래서 Monaco 인가.. 이 폰트를 잘 사용하다가.. 

CEDET 의 문제로 이맥스를 지우게 되었습니다.

맥은 기본적으로 편집기에 C-e C-a C-n C-p C-f C-b 의 단축키를 사용해 캡스락키를 컨트롤 키로 바꿔주기만하면

XCode 에서도 이맥스 못지 않은 개발환경의 구축이 가능하더군요.

하지만...

개인적으로 아직 개발환경을 구축 할 만큼 실력도 없고, 공부중인 녀석이 XCode 를 사용하기엔 좀 불편하더군요.

파일 만들고 코딩하고 컴파일하고 지우고 를 반복하려다보니

이럴바에 차라리 Emacs 가 훨씬더 편했을텐데.. 다시 해킨 버리고 다시 리눅스로 돌아갈까 진지하게 고민까지 했었는데요,

Emacs 24.2.1 2012-08-27 일 업데이트 받아서 다시 설정하니 잘되더군요.

CEDET 1.1 의 버그는 x-max-tooltip-size 의 문제였는데요,

semantic/semantic-complete.el 을 수정해 주셔야 합니다.

http://cedet.bzr.sourceforge.net/bzr/cedet/code/newtrunk/revision/8231/lisp/cedet/semantic/complete.el

참고해주세요.


이번에 추가한 플러그인은 바로 Emacs 의 frame 사이즈를 변경해 주는 플러그인 입니다.

키 바인딩

C-M-f (full size)

C-M-r (restore size)


emacs.tar.gz


음.

gtk를 공부하게 되면서 살짝 바꿔보았습니다.

이 설정은 저의 개인적인 백업 설정에 가깝습니다 ㅇㅅㅇ.


플러그인은 이쪽 -> http://youtil.wo.tc/55


8번째 줄은 gtk를 공부하기 시작하면서 cedet 가 gtk의 헤더파일을 인식 할 수 있게 include 폴더를 지정해 둔 것입니다.

필요 없으신 분은 gtk가 들어간 경로를 전부 지워주세요.

32-47 줄도 마찬가지 입니다.



저는 make 보단 gcc를 사용해서요.
사실은 makefile 를 만들줄 몰라요.,..

(setq compile-command "gcc -o ")

라고 .emacs 에 추가해 주시면 됩니다! 

이맥스 설정파일 리로드....

(defun reload-dotemacs ()
"Reload .emacs"
(interactive)
(byte-compile-file "~/.emacs") ;; 경로 설정
(load-file "~/.emacs.elc")) ;; 경로 설정
(global-set-key "\C-\M-e" 'reload-dotemacs)

최초 설정시 emacs 를 끄고 다시 실행해 주세요. 그 뒤 컨트롤 + 알트 + e 를 눌러주시면
.emacs 를 향해 byte-compile 를 진행하게 됩니다.
혹시 설정파일이 다른곳에 위치한 부분은 주석 부분의 경로를 변경해 주세요.

이 다음 부터는 .emacs 파일을 수정 후 저장하신 뒤 컨트롤 알트 e를 눌러주시면 됩니다.
원래 C-c e 로 하려고 햇는데 어떻게 설정하는건지를 모르겠더군요;
좀 알려줘봐요..; (왜 도움을 구하고 있는걸까..?) 
는 아니고, 몇번 써보았습니다 ㅎ.
자동완성 기능도 없고, 자동 들여쓰기 기능도 없이........

백업용입니다.
tcp/ip 소켓 프로그래밍을 공부해야 되는데
리눅스용하고 윈도우 용하고 프밍 방법이 틀리더라구요.
윈도우에선 visual studio 드림파크 얻어서 ㅎㅎ 쓰고있는데
리눅스에선 뭘 써야할지 망설여 지더군요,

한 때 진리라고 찬양하고 다녔던 vim.
다시 설정파일 만드려니 귀찮아 지더군요 ㅇㅂ;

기왕 만드는거 그냥 삽질 시작하자. 라는 느낌으로

삽 .... 들었습니다. 에.. 미친 짓을 시작 한거죠.

5시간정도 걸린것 같습니다.

ECB인가 뭔가 하는걸 사용하면


이런식으로 사용 할 수 있다던데 안해봐서 잘 모르겠군요 ㅋ
위는 홈페이지에 스크린샷 게시판에서 가져온 이미지입니다.

http://ecb.sourceforge.net/ 

홈페이지는 위를 참고해주세요,

저렇게 사용하는 방법 찾으려고 4개월전인가.. 쯤에 삽들고 삽질한 적이 있는데 못찾았다가 이번에 제대로 삽질하면서 찾았습니다 ㅎ.
저처럼 헤메지마시구....( 나만 힘든게 찾은건가!? )

Plugins.tar.gz

 위는 플러그인.

아래는 설정 입니다. [2012 03 18 수정]
== 수정내역 ==
Hide-Show 모드가 C모드에서 지원되지 않던것 수정.
자동완성 기능과  yasnippet 의 탭 키가 서로 겹쳐,  yasnippet 의 키를 컨트롤 q로 변경. (Caps Lock 키를 꼭 Ctrl 키로 바꿔주세요!)
**키를 바꾸시려면  yasnippet.el 을 편집기로 실행하신후 \C-q 를 검색하신 후, 원하시는 키로 변경하시길.

Cscope 추가.
우분투 사용자의 경우는 apt-get install cscope 안 될 경우 apt-get install cscope-el 를 사용해보시길.
그 외 리눅스 사용자 분들은 알아서 찾아보시길 바랍니다.
성의 없는게 아니라 원래 리눅스의 종류가 다르면 어쩔 수 없는 부분이라고 생각합니다.
Intellisens 기능 추가 (cedet 사용)
http://sourceforge.net/projects/cedet/ 
cedet 같은 경우는 직접 컴파일 해서 쓰고 있습니다.
터미널 실행하시고(리눅스 쓰면서 터미널을 무서워하시면 곤란합니다.)
cd 명령어로 cedet 압축 해제한 곳까지 들어갑니다.
make <RT>
----
** 이 과정에서 에러 발생시, 몇 가지를 설치해 주셔야 합니다. make로 컴파일 해보지 않으신 분들은 
** 에러메시지를 해석하신후 직접 해결해 보시길 ^^; (쉽습니다 엄청나게. 패키지 누락 에러라 apt-get install 로 패키지만 설치해 주면되기때문에.)
**컴파일 완료 후, cedet 폴더를 지우시면 곤란합니다. 어딘가에 잘 보관하신 후 .emacs 에 cedet.el 경로를 넣어주세요!
**반드시 README 파일을 읽어보시길 바랍니다. (자세한 설정 방법이 나와있습니다. 영어 6등급인 저도 해석했으니 무리 없이 볼 수 있을거라 생각합니다.)

flymake 추가. (Makefile 작성 하셔야 합니다. 자세한 사용방법은 구글링을 추천합니다. 저도 잘 모르겠거든요.
혹시 아시는 분은 댓글 달아주시면 감사하겠습니다.)

vim의 nu기능을 제거했습니다. 짜증나더군요;;


제 기준으로(~/.emacs.d/Plugins)  설정한거니 플러그인 위치라던가 뭐 이런건 직접 변경해 주시길.
여러군데에서 퍼왔습니다.

KLDP 는 기본으로 뒤지게 되네요.
언제나 도움받고 있는 곳.
저런 곳이 있어서 해외스레 안뒤져도 되니 영어 못하는 저는 행복합니다 ㅎ.
KLDP 감사합니다!

http://wonilkim.blogspot.com/ 
http://tkhwang.tistory.com/   <-블로그 이전했다고 하시더군요.. 아직 자료는 남아있으니 ㅇㅂ. 
(두 블로거 분께 진심으로 감사드립니다.)

그 외 몇몇 해외 사이트 돌아다녔습니디만 ㅇㅂ...

영어 못하면서 컴터를 잘 할 수 있는 방법 따윈 없더군요.
전자사전들고 죽도록 해석해야 되더군요....
우우.... 너무해...히도이요! 

자 그럼! 저는 이만 ㅇㅅㅇ

설정파일은 그렇게 기대하지마요.

emacs를 처음 사용하시는 분은 emacs 실행 후  
옵션 메뉴에서 save option 을 눌러주시면 홈 디렉터리에 .emacs 가 저장됩니다. 이걸 편집해 주시면 되요.
 
기본적인 단축키는 올리지 않겠습니다. 저도 모르겠고.
하나 재밌었던게, C-x C-f 이 파일이 존재할경우 해당 파일을 열고, 파일이 존재하지 않을 경우, 새로운 파일을 만들더군요 ㅎㅎ.
저는 몰랐어요 죄송해요 ㅎㅎㅎ.

자동 백업끄는 방법은 구글링 하면 나옵니다. 저는 그렇게 친절한 인간이 아니에요. 필요한건 언제나 구글링을 해야하는 저희들이잖아요?
이해하실거라 생각합니다 ㅇㅅㅇ.

그리고 위 설정은 ubuntu 에서 작업된거고, 따라서 아마 ubuntu 와 비슷한 작업 환경에서만 정상적으로 작동될지도 모릅니다.
플러그인도 같이 첨부합니다. 알아서 설정파일 경로 바꾸세요~ 

P.S. 인터넷 돌아다니면서 찾아봤는데요 한국엔 setnu.el 에 대한 언급은 많은데 (vim 쓰셧던 분이라면 뭐하는건지 짐작 갈겁니다 ㅇㅅㅇ)
setnu+.el 에 대한 언급이 거의 없는것 같더군요. 아니면 말구요,
버그가 있습니다. 블럭을 지정하고 백스페이스나 딜리트키로 글을 지우게 되면 글번호와 함께 지워지게 되는데 
이때 cpu 사용량이 100%가 되면서 emacs가 멈춰버리는 증상이 있습니다.
불편하신 분은 위에 설정파일에서 ;;Vim Style Line Number 밑으로 다음 주석 전까지 부분을 삭제해주세요, (3줄일겁니다. 아마.)
참고로 setnu.el 은

1
2
3
l <-(커서)

이렇게 있을때 백스페이스바를 누르면


1
2 3
l

이런식으로 되버립니다 ㅡㅡ;;


개설되고야 말았습니다.
개설하고야 말았습니다.
이런 잉여한 카테고리를요.

제가 공부하면서 햇갈렸던것들을 올릴거라
그다지 고 수준의 내용이 들어간다거나
뭐 그렇진 않을겁니다.

초보자 이기때문에.

아마도 주로 포인터나
API 쪽을 올리게 될것같네요.

컴활 공부하고있어서 아마 정리하면서 데이터베이스 부분같은것도 올라가지 않을까 생각해봅니다.

음...
블로그에 글을 자주 쓰러 오게될지도 모르겠네요 ㅋㅋ

저도 공부를 더 열심히 하게 될 지도 모른다는 ... 제발 그런 마음을 가지고 개설해보았습니다.

잘부탁드릴게요~

오늘 저녁부터 시작합니다! 

카테고리의 || 은 C언어와 C언어에서 파생된 여러가지 언어들에서
OR(또는) 으로 사용되고 있습니다.
이 카테고리는 프로그래밍 외에 제가 따로 공부중인 것들을 올릴 예정입니다.

글세요. 저는 공부를 못하기에.. 모의고사 5.0~4.5 등급 정도 밖에 안됩니다. 더 밑일 수도 있구요.
대학교가서 모의고사로 부터는 해방되었지만. 이제 토익으로부터 벗어날 수 없 ㅋ 어 ㅋ.
헛소리구요.
뭐 아마 내용은 아주아주 쉬울거라 생각됩니다만 저한탠 매우 어려운내용이니
필요한 분들만 보시고 아닌분들은 비웃지마시고 응원좀 부탁드립니다.
 

+ Recent posts