기본 콘텐츠로 건너뛰기

글

LOGGING 을 얼마나 중요하게 생각하십니까?(LOG4CXX)

황제펭귄의 게임개발이야기 [여기는 한국] | 황제펭귄 http://blog.naver.com/kimbeast/60016524389 hello world 프로그램을 만들때 초보는 기능 구현에만 충실하게 된다. void main() { printf("hello world"); } 이렇게 만들어 놓구..아 ~~ 기쁘다.이렇게 생각하겠지. 중급 정도 되면 고민을 먼저한다. 이거 hello world 를 출력하지만 나중에는 입력받아서 처리하게 할꺼야. void main() { char chInput[80]; printf("출력할 글자를 입력하세요"); scanf("%s", chInput); printf("%s", chInput); } 조금더 생각하는 사람이라면.. 입력방식의 변화가 생기기때문에 로직분리를 위해서 함수또는 class로 입력기를 처리할수 있다. void main() { CInputManager inputManager; inputManager.input(); printf("%s", inputManager.getInputChar()); } 자..그럼 만족하겠지. 근데..예를 들어 문제가 생겼다고 하자. 출력이 안된다던지.한글이 깨진다던지.아니면..DB에서 읽어들이는데 자꾸 읽히지가 않고 문제가 생긴다고 하자. 어떻게 해결할 것인가?~ 간단한 프로그램이니까 디버그로 돌리면 될것이다. 그런데 큰 프로그램이라면 어떻게할것인가~? 개발할때 무수히 많은 printf문장으로 console에 출력을 쭈르륵 할것이다. 그리고 나중에 서비스에 올릴때에는 이넘의 printf 또는 cout ...

[STL] erase()를 사용하여 List 원소 삭제 시 주의사항

picbuddy님의 블로그 (Mesh Generation) | 플라나 http://blog.naver.com/picbuddy/80032246219 다시 한번 기억을 환기시키기 위해 /////////////////////////////////////////////////////// for( Iterator = Vector.begin(); Iterator != Vector.end(); ) { Vector.erase(Iterator); } /////////////////////////////////////////////////////// for( Iterator = List.begin(); Iterator != List.end(); ) { List.erase(Iterator); } 위 두 문장의 차이가 뭘까? 위의 문장에서는 문제가 없지만 아래 문장에서는 에러가 발생한다. 왜 그럴까? erase 함수의 구현은 둘다 똑같은데... 그 이유는.... RandomAccessIterator와 BidirectionalIterator의 차이에 있습니다. vector는 해당 원소가 삭제되면 Iterator의 공백을 삭제된 원소 다음에 있는 원소 위치로 채워지게 된다. 이는 RandomAccessIterator(멋대로 접근 가능 지시자)라 가능한 듯...(솔직히 컴파일러에 따라 다른지 그것까지는 모르겠음. 일단 Visual Studio에서는 그렇게 작동) 허나 list는 BidirectionalIterator(순서대로 차근차근 접근 가능)이므로 해당 원소가 삭제되면 Iterator는 그 다음 위치를 잃어버리게 되는 것이다. 결국 그 다음 지시자의 위치는 까마득한 별나라로... 이를 위한 해결 방법 가장 확실한 방법은 erase 함수의 리턴값을 이용하는 것이다. erase 함수의 리턴값이 바로 삭제 원소 다음에 있는 원소 iterator이기 때문... for( Ite...

pml용 vim syntax 파일

pml용 vim syntax 파일 입니다. 이 파일을 vim의 syntax 폴더 안에 넣어두고, vim 폴더 안에 있는 filetype.vim 에 아래의 내용을 추가합니다. au BufNewFile,BufRead *.pmlfnc,*.pmlfrm,*.pmlobj setf pmlfnc 2007.11.16 $* 주석 처리한 것 --2007.12.20 기타 등등 추가. --2008.01.18 ...

[code project 펌]Hacking the CPropertySheet

돼지스머프 | 돼지스멒 http://blog.naver.com/bbk1999/90001777342 Hacking the CPropertySheet By Mustafa Demirhan Introduction In my applications, I usually need to change the default look and feel and the behavior of Property Sheets. Working with property sheets and pages is really a pain and you must do most of the work on yourself for non-standard operations (such as changing the coordinates of the buttons, adding new controls to the property sheet, ...etc). In this article, I tried to give as many tips and tricks as I can do. Before going in to the details, you should first create a CPropertySheet derived class - say CMyPropSheet. Lets begin with some simple things: Hiding Standards Buttons When our property sheet shows up, by default it has all the buttons visible and the Apply button is disabled. In general we don't need to use Apply button. To hide the apply button, you can simply use the following code: propsheet.m_psh.dwFlags |= PSH_NOAPPLYNOW; Ho...

CDocument::DeleteContents

출처 행복하세요~ | 논스모커 원문 https://blog.naver.com/ttcoupe/20017784895 MFC Library Reference CDocument::DeleteContents Called by the framework to delete the document's data without destroying the CDocument object itself. //CDocument 객체 자체를 없에지 않고, document에 있는 내용을 지운다. virtual void DeleteContents( ); Remarks It is called just before the document is to be destroyed. It is also called to ensure that a document is empty before it is reused. This is particularly important for an SDI application, which uses only one document; the document is reused whenever the user creates or opens another document. Call this function to implement an "Edit Clear All" or similar command that deletes all of the document's data. The default implementation of this function does nothing. Override this function to delete the data in your document. //이 함수는 기본적으로 아무것도 하지않는다. 하지만 사용자의 document의 데이터를 지우기 위해서 재정의한다. Example // This example is the handler for an Edit Clear All command. ...

등고선 그리기

이번 작업을 하면서 등고선 그리는 일이 필요하게 되었습니다. 며칠동안 인터넷을 뒤져 가면서 등고선 그리는 루틴( 소스이면 좋겠다고 생각 함)을 찾아봤지만  이거다 싶은 것을 발견하지 못했습니다. 그나마 겨우 찾아낸것이 Kriging 알고리즘으로 등고선을 그린다는 것이었습니다. Kriging 알고리즘은 그리 복잡하지 않은 몇개의 식으로 표현되어 있었는데 이것을 어떻게 프로그래밍해야 할지 알수가 없었습니다. 다시 인터넷을 뒤지던 중 나의 상황에 맞는 루틴을 코드구루에서 찾을 수 있었습니다. 이것은 아주 단순했습니다. 저의 경우는 1mm 간격으로 놓여 있는 그리드의 측정점(x , y , z)들을 미리 알고 있는 상태였습니다. 아래 이미지는 측정 데이터들의 일부분을 캡쳐한 것입니다. TOP에서 봤을때 ISO로 봤을때 이 측정점들로 삼각망들을 형성할 수 있습니다. min z ~ max z의 간격을 7등분하였고 각 등분된 간격에 무지개 색상을 각각 할당하였습니다. 등분된 간격에 들어가는 삼각망을 할당된 색상으로 칠하기만 하면 되는 것입니다. 좀더 자세히 생각해 보면, 최초의 삼각망은 LEVEL( min z ~ max z를 등분하는 값)에 의해 분할이 일어나게 됩니다. 이렇게 분할이 일어날때 삼각망은 2개의 다각형으로 분할되는데 이 다각형을 다시 삼각형으로 나누어줍니다. $N$개의 정점을 가지는 다각형은 $N-2$개의 삼각형으로 나눌 수 있습니다. $N-1,i,i+1$의 3개의 정점을 가지고 삼각형을 생성한다고 생각하면 됩니다. $(i = 0,...,N-3)$ 이러한 작업은 모든 삼각망에 대해 모든 LEVEL에 걸쳐 수행하게 됩니다. 결과로 생기는 모든 삼각망들은 모든 LEVEL에 의해 나누어지게 됩니다. 삼각망들을 2D로 내려 할당된 색상으로 칠해주면 됩니다. 여담으로 소스포지에 보면 FMesh라는 프로그램이 있는데 이 프로그램을 분석해보면 3D 좌표를 가지고 먼저 삼각망을 구성하고 나서 앞서 이야기한 내용대로...

c++로) unicode를 multi-byte character로 변환하려고 하는데

출처 :   http://tong.nate.com/thisbe71/24531681 안녕하세요. 일단 문자세트, 테이블에 대해서 조금 이야기를 할까 합니다. SBCS(Single Byte Character Set) DBCS(Double Byte Character Set) MBCS(Multi Byte Charecter Set) WBCS(Wide Byte Charecter Set) 4종류의 테이블이 있습니다. 옛날 ASCII 코드라고 들어보신 적이 있으실까 모르겠습니다. 이넘들이 1바이트를 가지고 문자를 표현했었습니다. 1바이트니까 256개의 문자를 표현할 수 있지요. 그것이 저 위에 있는 SBCS입니다. 그러다가 한글도 써야 되고 일어도 써야 되고 한문도 써야 되지요... 그것을 위해서 만들어진 것이 바로 DBCS입니다. 한글을 쉽게 쓸 수 있어서 좋긴하지만 문제가 발생했습니다. SBCS와 DBCS가 호환이 되지 않았던 겁니다. 그래서 저거 두개 묶어 쓰자...라고 나온 것이 MBCS이구요. 하지만 MBCS 내부에서 호환이 되지 않았기 때문에 앗싸리 바이트를 여러개 써서 모든 문자를 표현하기 위해서 나온 것이 바로 WBCS입니다. multi-byte characater는 바로 MBCS이구요. 유니코드는 WBCS랍니다. 자~ 그럼 왜 WBCS에서 MBCS로 바꿔야 할까요. 그것은 바로 윈도우즈 운영체제 때문입니다. 윈도우즈 95, 98, me 계열, 9x계열들은 MBCS를 사용했었습니다. 그러다가 윈도우즈 2000 넘어가면서부터 WBCS를 사용하게 되었는데요. 물론 윈도우즈 2000이상급들에서도 MBCS를 사용할 수 있긴 하지만 9x계열에서는 WBCS를 사용할 수가 없죠. 프로그램의 운영체제간 호환성을 위해서 어쩔 수 없이 써야하는 것이랍니다. 여기까지 대략적인 문자세트를 설명했구요. 이제 답변을... 624b -> 이렇게 있으면 '手'이 뮨자가 나와야 한다는 건가여? ==> 네 그...

SHBrowseForFolder 디폴트 경로 설정하기...

출처 : http://codeguru.earthweb.com/mfc/comments/5889.shtml [[ Starting SHBrowseForFolder from arbitrary directory is easy ]] This is very easy... // this is how we set the initial directory int CALLBACK MyBrowseCallbackProc( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData ) { switch (uMsg) { case BFFM_INITIALIZED: ::SendMessage( hwnd, BFFM_SETSELECTION, TRUE, lpData ); break; } return 0; } void BrowseForDirectory( CWnd* pWndOwner, LPCTSTR title, CString& folderName ) { TCHAR path[MAX_PATH]; LPTSTR pFolderName = folderName.GetBuffer(folderName.GetLength()); BROWSEINFO browse; browse.hwndOwner = pWndOwner->GetSafeHwnd(); browse.pidlRoot = NULL; browse.pszDisplayName = pFolderName; browse.lpszTitle = title; browse.ulFlags = BIF_RETURNONLYFSDIRS; browse.lpfn = MyBrowseCallbackProc; browse.lParam = (LPARAM)pFolderName; LPITEMIDLIST pidl = SHBrowseForFolder(&browse); folderName.Relea...

SHBrowseForFolder로 폴더 브라우징 하는 방법.

나만의 노트' ' | 나츠히메 http://blog.naver.com/iizumi/30002116144 폴더만 브라우징 해서 경로를 가져오는건데요. //---------------------------------------------------- bool MyApp::OpenPath( CString& outpath ) { char path[MAX_PATH]; memset(path,0,sizeof(char) * MAX_PATH ); BROWSEINFOA bi; bi.hwndOwner = GetSafeHwnd(); bi.pidlRoot = NULL; bi.lpszTitle = "경로를 입력해주세요"; bi.pszDisplayName = path; bi.ulFlags = BIF_RETURNONLYFSDIRS; bi.lpfn = NULL; LPITEMIDLIST idlist = SHBrowseForFolderA( &bi ); if ( idlist ) { SHGetPathFromIDListA( idlist, path ); outpath = path; return true; } outputpath = ""; return false; } //---------------------------------------------------- 물론 idlist가 NULL이면 취소를 했다는 거죵. 좀 더 자세한건 MSDN에서 SHBrowseForFolder 로 검색해 보시면 됩니당. 이거랑 이전에 올린 CFileFinder를 이용하면.. 특정 폴더를 지정하고, 그 폴더의 경로를 이용해, 하위 폴더의 파일목록을 만든다든지 검색을 한다든지 유용하게 쓰실 수 있습니당.. - .-

BuildAssist

일일 빌드를 위한 배치 파일을 보다 쉽게 만들기 위한 간단한 프로그램입니다. 컴파일러 파일 설정 : 커맨드 라인상에서 컴파일을 위한 프로그램을 각각 VC6.0 , .NET 2003 , VB6.0에 대해서 설정을 합니다. 패키지 파일 : 인스톨러 프로그램을 설정합니다. NSIS의 경우 : makensis.exe Window Installer의 경우 : DEVENV.EXE 패키지 파일을 설정합니다. 결과 파일을 저장할 폴더 : 컴파일 결과를 저장할 폴더를 설정합니다. 빌드할 프로젝트들... : 빌드할 프로젝트들을 설정합니다. Compiler : < VC6.0 , NET 2003 , VB6.0 > 중 하나 선택 Mode     : < Release  , Debug > 중 하나 선택 Project   : 프로젝트 파일 선택 OK 버튼 : 저장할 배치 파일 이름을 설정합니다. 첨부 파일

Doxygen - Visual Studio 6.0 에서 Doxybar쓰기

Seize the day | 더미 http://blog.naver.com/pokev25/80001993980 참조 URL - http://www.gpgstudy.com/gpgiki/DoxygenTutorial 1. 필요파일 다운로드 Doxygen - http://www.doxygen.org/index.html Doxybar - http://doxbar.sourceforge.net/ MS HTML help workshop - http://msdn.microsoft.com/workshop/author/htmlhelp 2. 설치 Doxygen과 help workshop은 setup진행 Doxybar는 적절한 위치에 압축을 풀어 놓는다. (위의 참조 URL에선 path설정이 필요하지만 setup을 한경우는 자동 설정된다.)     3. 환경설정 Doxygen - 기본 설정파일을 만들자 도스창을 열고 doxygen -g 기본파일 (doxyfile)이 생긴다 boxybar설정할때 필요하므로 doxygen폴더에 넣어두자 노트패드 같은것으로 이 파일을 열어서 OUTPUTLANGUAGE를 Korean으로 고친다. Doxybar - 퍼온다. 필요한 부분만 코멘트 처리함 Installation Do the following to install the tool: Start developer studio. From the "Tools" menu select "Customize...". Select the "add-ins and Macro Files" tab. Press "Browse" and select files of type "add-ins (.dll)". Browse to the location of doxbar....

IE 에서 DHTML Editing 컨트롤을 이용한 MFC OCX의 탭 키 처리 문제

IE 에서 DHTML Editing 컨트롤을 이용한 MFC OCX의 탭 키 처리 문제 현상 DHTML Editing 컨트롤을 Embed하여 MFC OCX를 작성한 경우, IE에서 이 컨트롤을 사용하면 DHTML Editing 컨트롤에서 방향 키 및 탭 키가 동작하지 않습니다. 위로 가기 원인 IE 컨테이너가 Accelerator Key에 대한 이벤트를 MFC OCX에서만 처리할 수 있도록 해주기 때문입니다. 즉, IE 에서 MFC OCX에 Embed된 DHTML Editing 컨트롤이 Accelerator Key인 탭 키 및 방향키에 대한 이벤트를 처리하지 못하기 때문입니다. 위로 가기 해결 방법 IOleInPlaceActivateObject 인터페이스를 이용하여 MFC OCX의 TranslateAccelerator 메소드가 호출되었을 때 DHTML Editing 컨트롤의 TranslateAccelerator 메소드가 강제적으로 호출되도록 합니다. 예제 코드 // MFC OCX의 이벤트 핸들러 BOOL CTest1Ctrl::PreTranslateMessage(MSG* pMsg) { IOleInPlaceActiveObject* piOleInplace; IUnknown* piUnknown; switch (pMsg->message) { case WM_KEYDOWN: case WM_KEYUP: switch (pMsg->wParam) { // 처리하려는 키에 대하여 case VK_UP: case VK_DOWN: case VK_LEFT: case VK_RIGHT: case VK_HOME: case VK_END: OutputDebugString ("Key down for Arrow ...

메모리 풀링

탑건매직 | 탑건매직 http://blog.naver.com/topgunmagic/120033903901 메모리 풀링? : 메모리 풀링이란 간단히 말해서 필요할때마다 new나 malloc을 사용하는것이 아니고, 필요한 만큼에 메모리를 미리 잡아두고 사용하는것을 말한다. 그럼 이것을 어따쓰냐.... 잦은 메모리 할당은 성능을 저하시킬수 있다. 따라서 한번에 미리 메모리를 잡아두고 사용한다면 성능면에서 매우 효율적일때 사용될수 있다. 위 MemPooler.h는 Edited from C8MemPool class (Hitel, gma 7 3) - 1CoinClear - 라는 사람이 만든건데, 메모리 풀링이 어떤식으로 돌아가는지 분석 해보도록 하자. 메모리 풀링은 언제 사용하나?? new와 delete가 빈번하게 반복 발생될때 메모리풀을 사용합니다. 게임에 사용자가 접속할때마다 사용자 객체를 new해주고 접속을 해제할때마다 delete를 해준다면 속도는 물론이고 메모리 단편화의 문제가 발생할 수 있기 때문에 시작할 당시 n개의 사용자 객체를 생성한뒤 접속할때 가져다 쓰고 접속을 해제할때 제거하지 않고 다시 사용할 수 있게 해주는 경우도 해당합니다. template<class Type> class MemPooler 템플릿 클래스를 사용하였습니다. 왜일까요? Type이 쓰이는 부분들을 일단 살펴 보도록 하겠습니다. m_nListBlockSize=sizeof(BlockNode)+sizeof(Type); 음...보시면 일단 사이즈를 잡는건데요. 그렇습니다. MemPooler 클래스 설계시 우리는 필요한 만큼의 메모리를 잡아야 하는데 이시점에서 이 필요한 만큼의 메모리가 어느정도인지 우리는 알수 없습니다. 이럴때 한번 사용했군요. Type* Alloc() 한 블럭을 사용할 시 사용가능한 메모리를 가리켜 그 주소를 리턴하는 함수인데요. 여기서 한블럭이라는건 차차 설명 하도록 하지요. 우리는 메모리풀링을 만들시 필요...

다국어 버전 만들기

현재 진행중인 프로젝트가 어느 정도 끝이 보이는 시점에서 다국어 버전을 만들어 보기로 했습니다.(국내 회사에서 사용하는 것이므로 필요하지는 않겠지만...) 먼저 주 프로젝트에서 resource.h , rc 파일 , 그리고 관련된 리소스 파일들을 이용해서 DLL을 만듭니다. InitInstance 함수에서 리소스 DLL을 로딩합니다. 로딩한 DLL로 리소스 핸들을 설정합니다. ExistInstance 함수에서 리소스 DLL을 해제시킵니다. 전체적인 줄거리는 위와 같으며 쉽게 할 수 있습니다. 그러나 현실에서는 그렇게 쉽게 되지 않습니다. 2번 항목에서 InitLanguage()함수를 InitInstance()에서 가장 먼저 호출하였습니다. - InitLanguage() 함수는 리소스 DLL을 로딩하고 리소스 핸들을 설정하는 함수 BOOL CAdminApp::InitLanguage() { //Set the new language m_hMultiLangRes = LoadLibrary("Lang\\AdminKorLang.dll"); if (m_hMultiLangRes) AfxSetResourceHandle(m_hMultiLangRes); return TRUE; } BOOL CAdminMain::InitInstance() { InitLanguage(); AfxEnableControlContainer(); FileZilla의 소스를 보고 이렇게 했습니다. 그랬더니 프로그램이 에러가 발생하고 종료되었습니다. 원인을 살펴보니 Grid Control을 폼의 초기화 부분(OnInitialUpdate)에서 Create 함수를 통해 생성하고 있었는데 생성하는데 실패되었습니다. 참고로 Grid Control은 유명한 MFC Grid Control이며 다른 DLL( 컨트롤에 관련된 DLL을 만들어 사용하고 있었음 )에 포함되어 있었습니다. 이 ...