728x90
반응형

전체 글 337

[OpenGL] 비트맵 폰트 갱신

OpenGL을 사용하여 텍스트를 랜더링 할 때 Bitmap 방식을 사용하면 설정을 갱신해야 한다. wglMakeCurrent()로 갱신을 시도해보려 했지만 갱신이 되질 않았다. 한 번의 Refresh가 이뤄진 다음에야 제대로 그려졌다. 그러는 와중에 텍스트가 종류 별로 표시가 되는지 확인하려고 여러 개를 표시하니 첫 번째 텍스트만 표시되지 않았다. 작은 MOTION PTP 밑에 조금 더 큰 MOTION PTP라는 글자가 와야 하지만 생기지 않았다. 화면이 Redrawing 하면 생겨나게 된다. 그래서 wglUseFontBitmaps()를 두 번 호출하니 제대로 동작하였다. 성능에 얼마나 영향을 미칠지는 모르겠지만 갱신하는 법을 알 수 없으니 이 방법을 사용해야겠다. 전체를 새롭게 그리는 것보다 나을 듯하..

[VS] Visual Studio Dependencies(종속성) 설정

VS 프로젝트를 진행할 때, 여러 Lib 프로젝트를 만든 후 가져다 사용하는 경우가 많다. 그럴 경우 컴파일 실행 순서가 뒤죽박죽이면 여러 번 컴파일해야 한다. 왜냐면 가져 다 사용해야 할 Lib이 컴파일이 끝난 상태가 되었을 때 그것을 이용하는 프로젝트가 컴파일이 완료될 수 있기 때문이다. 이런 작업을 위해 컴파일을 순서를 정해주기 위해서는 프로젝트의 종속성을 설정해 줘야 한다. Visual Studio에서는 종속성을 설정하는 기능을 지원한다. 솔루션 이름에서 우클릭(1)하여 속성(2)을 클릭하면 솔루션의 속성을 볼 수 있다. 항목 중에 Project Dependencies를 선택(3)하고 종속성을 설정할 프로젝트를 선택(4) 한다. 해당 프로젝트를 선택하면 이 프로젝트를 제외한 프로젝트들이 나타난다...

[C++] namespace 사용 시 LNK2019 에러 발생

namespace 사용 시, cpp 파일의 활용을 편하기 하기 위해서 namespace를 정확하게 작성하지 않고 using namespace를 사용 시 link 에러가 발생할 수 있다. //header file namespace file_c { void open_file(); } using namespace file_c void open_file() { // ... } 이라고 했을 때, open_file()을 여러 단계를 거치다 보면 2019 LNK ERROR가 발생하는데, 헤드 파일 라이브러리 링크 등 보통의 경우를 모두 체크하더라도 에러가 발생한다. 그렇기 때문에 헤드 파일과 cpp파일 모두에 제대로 된 네임스페이스 형식으로 구현하도록 하자. namespace file_c { void open_fil..

[C++] std::bind 시 변수 메모리 유지 불가

function을 구성할 때 운용하기 쉽도록 하기 위해 bind를 이용하여 매개변수를 미리 넣어둘 수 있다. 하지만 이 방향은 하나의 패키지처럼 묶기기 때문인지 변수의 메모리 주소가 변경되었다. 아래와 같이 간단히 테스트해보면 bind로 묶은 변수 b와 실제 함수에 적용되는 b의 주소 값이 다르다. 결과도 적용되지 않는다. #include #include using namespace std; void add(int a, int& b) { b = a * a; cout

[MFC] TreeCtrl Node 모두 확장하기

CTreeCtrl을 사용하여 아이템을 추가한 경우, 모두 닫혀 있게 되는데 매번 모두 여는 작업은 귀찮을 수 있다. 이를 위해서 한꺼번에 확장하는 함수를 만들어서 사용하게 된다. 우선 ITEM의 확장을 위해서는 간단하게 아래와 같이 만들 수 있다. ( 예는 Subclassing 한 경우다.) void CMxTreeCtrl::ExpandTree(HTREEITEM hItem) { if (this->ItemHasChildren(hItem)) { Expand(hItem, TVE_EXPAND); HTREEITEM hChild = GetChildItem(hItem); if (hChild) { do { ExpandTree(hChild); } while (hChild = GetNextSiblingItem(hChild)..

[SQLite] LIKE 구문

Query문의 WHERE을 사용하여 제약을 만들 때 부분적 일치를 확인하는 구문이다. MySQL과 대부분 동일하며, &를 %로 바꿔 사용하면 된다. -- A로 시작하는 이름을 가진 레코드 SELECT '컬럼명' FROM '테이블명' WHERE '컬럼명' LIKE 'A%' -- A로 끝나는 이름을 가진 레코드 SELECT '컬럼명' FROM '테이블명' WHERE '컬럼명' LIKE '%A' -- A를 포함하는이름을 가진 레코드 SELECT '컬럼명' FROM '테이블명' WHERE '컬럼명' LIKE '%A%' -- A로 시작하는 이름을 가진 두 글자 레코드 SELECT '컬럼명' FROM '테이블명' WHERE '컬럼명' LIKE 'A_' -- A로 시작하는 이름을 가진 세 글자 레코드 SELECT '..

DB/SQLite 2021.11.17

[SQLite] 현재 날짜 혹은 시간 가져오기

테이블을 만들다 보면 가입한 날짜라던지 log가 기록된 시간을 사용해야 할 때가 있다. 이때 사용하는 명령어로는 DATE, TIME, DATETIME이 있다. SELECT DATE('now') AS DATE; SELECT TIME('now') AS TIME; SELECT DATETIME('now') AS DATETIME; 위와 같은 결과를 얻을 수 있다. 만약에 DEFAULT로 현재 시간을 지정하고 싶다면 테이블을 생성 시 아래와 같이 CURRENT_TIMESTAMP를 사용하면 된다. CREATE TABLE `datetbl` ( `Datetime`TIMESTAMP DEFAULT CURRENT_TIMESTAMP );

DB/SQLite 2021.11.17

[SQL] INSERT INTO

테이블에 레코더를 추가하고 싶을 때에는 INSERT INTO 문을 사용하게 된다. INSERT INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...); INSERT INTO table_name VALUES (value1, value2, value3, ...); INSERT INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...); 이 구문은 테이블의 필드를 선택해서 넣을 수 있도록 할 수 있다. INSERT INTO table_name VALUES (value1, value2, value3, ...); 이 구문은..

DB/SQLite 2021.11.17

[C++] 변수 묶어 사용하기 (pair, tuple)

함수를 이용할 때 연관된 내용을 동일한 개수만큼 전달하거나 관리해야 할 때 묶어서 사용하곤 한다. 자주 사용되는 경우라면 struct나 class를 이용하여 작업을 할 수도 있지만 임의로 묶어 사용할 때에는 비효율적이다. 이런 점을 해결하기 위해서 C++에서는 pair와 tuple을 지원한다. pair : 2개의 값을 묶고 싶을 때, tuple : 3개의 값을 묶고 싶을 때, pair의 경우에는 웬만한 STL 헤드 파일을 첨부하면 사용할 수 있지만 tuple의 경우에는 을 include 해줘야 한다. pair의 경우에는 make_pair를 tuple은 make_tuple을 사용하면 된다. pair는 first, second를 참조하면 되고, tuple은 get을 이용해야 한다. #include #incl..

[MFC] ID_FILE_OPEN 재정의

Frame이 있는 프로젝트를 실행할 때, 기본적으로 제공하는 ID_FILE_OPEN의 경우, 이벤트를 실행하면 파일 다이얼로그가 열리고 해당 경로는 Document의 OpenDocumentFile를 호출하게 된다. 이때 읽을 파일의 확장자나 기능으로 추가하기 위해서는 재정의를 할 필요가 있다. BEGIN_MESSAGE_MAP(CTaskViewApp, CWinAppEx) ON_COMMAND(ID_APP_ABOUT, &CTaskViewApp::OnAppAbout) // Standard file based document commands ON_COMMAND(ID_FILE_NEW, &CWinAppEx::OnFileNew) ON_COMMAND(ID_FILE_OPEN, &CWinAppEx::OnFileOpen) E..

[C++] file in/out

C++에서 파일 관련하여 제공하는 Stream 클래스는 다음과 같다. ofstream : 파일에 쓰는 기능의 Stream class ifstream : 파일을 읽는 기능의 Stream class fstream : 파일에 대한 읽고 쓰는 기능을 모두 갖춘 Stream class wifstream : 유니코드 문자로 쓰인 텍스트 파일을 읽는 Stream class wofstream : 유니코드 문자를 텍스트 파일에 쓰는 Stream class #include #include using namespace std; int main() { setlocale(LC_ALL, ""); ofstream fout; fout.open("D:\\sample.txt"); fout

[C++] XMLLite를 이용한 XML 파일 읽어오기

XML을 읽어오는 방법에는 여러 방법이 있다. 직접 코딩할 수도 있고, tinyXML 같은 오픈 api를 사용해도 된다. 여기서는 Visual Studio에서 제공하는 XMLLite를 이용하여 읽어 오도록 해보자. 우선 XML의 ELEMENT를 저장할 수 있는 구조체를 지정한 후 typedef struct XML_ATTRIBUTE_T { wstring name; wstring value; } XMLATTR; typedef vector XMLATTRV; typedef struct XML_ELEMENT_T { wstring title; XMLATTRV attribute; bool bSubElement; bool bSeperator; vector vElem; XML_ELEMENT_T() { bSubElemen..

코드/C++ 2021.11.08

[자료구조] 버블 정렬

버블 정렬이란? 매우 기본적인 정렬 알고리즘인 버블 정렬(Bubble sort)은 이해하기 쉽기 때문에 단순 정렬(simple sort)이라 불린다. 다만 빠르다고 알려진 정렬 알고리즘보다는 비효율적이다. 버블 정렬은 다음과 같은 단계를 따른다. 1. 배열 내에서 연속된 두 항목을 가리킨다. 첫 번째 항목과 두 번째 항목을 비교한다. 2. 두 항목의 순서가 뒤바뀌어 있으면 (왼쪽 값이 오른쪽 값보다 크면) 두 항목을 교환(swap)한다. 순서가 올바르다면 아무것도 하지 않는다. 3. 비교 위치(포인터)를 오른쪽으로 한 셀씩 옮긴다. 4. 더 이상 교환하지 않을 때까지 1단계부터 3단계까지 반복한다. 더는 교환을 하지 않는다는 것은 배열이 정될된 상태라는 뜻이며 1 ~ 3 단계를 반복하는 것을 패스스루(p..

단계적 통합과 증가적 통합

단계적 통합 단계적 통합 과정은 다음과 같다. 각 루틴에 대해 설계, 코딩, 테스트, 디버그를 한다. 이 단계는 "단위 개발"이라 부른다. 루틴들을 하나의 거대한 시스템으로 묶는다. 이것은 "시스템 통합"이라 부른다. 전체 시스템을 테스트하고 디버그 한다. 이것은 "시스템 분해"라고 부른다. 단계적 통합의 한 가지 문제는, 시스템의 루틴들이 처음에 합쳐질 때, 새로운 문제가 필연적으로 드러나고, 그 문제의 원인은 어디에나 있을 수 있다는 것이다. 특정 문제의 위치에 대한 불확실성은 모든 문제들이 갑자기 정체를 드러낸다는 사실에 의해 복잡해진다. 단계적 통합은 모든 루틴들이 단위 검사된 후, 프로젝트의 후반부까지는 시작될 수 없다. 루틴들이 최종적으로 결합되고 오류가 행운에 의해 드러날 때, 프로그래머들은..

[C++] RAII Pattern

C++ 에는 RAII (Resource Acquisition Is Initialization)이라는 패턴이 있다. 리소스의 획득은 초기화다라는 뜻인데 보통 RAII Design Pattern이라고 한다. 예를 들자면, lock_gaurd class가 있다. class lock_guard {// class with destructor that unlocks mutexes public: explicit lock_guard(_Mutexes&... _Mtxes) : _MyMutexes(_Mtxes...) {// construct and lock _STD lock(_Mtxes...); } lock_guard(_Mutexes&... _Mtxes, adopt_lock_t) : _MyMutexes(_Mtxes...) ..

[C++] std::thread 종료 (abort() has been called)

std::thread를 사용하다 보면 abort() has been called라는 에러 메시지를 만나는 경우가 있다. 이는 thread가 종료되기 전에 시스템이 종료되거나, 객체가 사라질 때 발생한다. 이 때는 join()을 사용해서 해결하면 된다. #include #include using namespace std; int total; void sum() { for (int i = 0; i < 200000; i++) total += 1; } int main() { while (1) { total = 0; std::thread th1(sum); std::thread th2(sum); cout

728x90
반응형