Showing posts with label VisualC. Show all posts
Showing posts with label VisualC. Show all posts

Thursday, July 14, 2016

C언어 Quick Soft 예제

int data[7] = { 3,5,1,2,6,9,7 };

void swapInt(int &a, int &b)
{
int tmp = a;
a = b;
b = tmp;
}

void printArr(int arr[]) {
printf("arr=");
for (int i = 0; i < 7; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}

void quickSort(int arr[], int left, int right)
{
printf("left=%d right=%d\n", left, right);

int i = left;
int j = right;
printArr(arr);

int pivotIndex = (left + right) / 2;
int pivot = arr[pivotIndex];
printf("pivotIndex=%d pivot=%d\n", pivotIndex, pivot);

while (i <= j) {
// 피봇을 기준으로 left의 값이 pivot의 값보다 큰 것을 찾는다.(잘못 놓여진 것을 찾음)
while (arr[i] < pivot) {
printf("arr[%d]=%d i++\n", i, arr[i]);
i++;
}
// 피봇을 기준으로 right의 값이 pivot의 값보다 작은 것을 찾는다.(잘못 놓여진 것을 찾음)
while (arr[j] > pivot) {
printf("arr[%d]=%d j--\n", j, arr[j]);
j--;
}

// 인덱스가 정상적인 상황일때 스왑한다.
if (i <= j) {
printf("swap begin %d %d\n", i, j);
swapInt(arr[i], arr[j]);
printArr(arr);
i++;
j--;
printf("swap end %d %d\n", i, j);
}
}

// 나머지 좌우에 대해서 다시 퀵소트 한다.
if (left < j) {
quickSort(arr, left, j);
}

if (i < right) {
quickSort(arr, i, right);
}
}


int main()
{
quickSort(data, 0, 6);
printf("data=");
for (int i = 0; i < 7; i++) {
printf("%d ", data[i]);
}
printf("\n");
return 0;
}

Sunday, April 3, 2016

Visual C++ Win32 타이머 CreateTimerQueueTimer 예제

#include <stdio.h>
#include <windows.h>
VOID CALLBACK TimerCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
 printf("TimerCallback\n");
}
int main() {
 // 타이머 큐를 만든다.
 HANDLE timerQueue = CreateTimerQueue();
 // 타이머를 만든다.
 HANDLE timer;
// 처음 시작할때 0.5초 지연, 주기 0.5초마다 호출되게
 CreateTimerQueueTimer(&timer, timerQueue, TimerCallback, NULL, 500, 500, 0);
 while (1) {
  Sleep(100);
 }
 return 0;
}

Sunday, December 13, 2015

Visual C++ 11자리 정수형 유니크 ID 만들기

정수형으로 유저ID로 사용할 유니크ID를 만들어 보았다.
32비트 UINT_MAX는 0xFFFFFFFF로 4,294,967,295가되며 약 42억9천만이 된다.
그리고 rand()를 사용하면 리턴값은 int지만 사실상 short인 SHRT_MAT 32767이 최대값이다.
따라서 다음과 같이 만들면 long형인 11자리 값을 만들수가 있다.

srand(time(NULL));
unsigned hirand = rand() << 16;
unsigned lorand = rand();

//앞에 1또는 다른 값을 붙여 써도 됨
printf("1%010u\n", hirand | lorand);

Sunday, December 6, 2015

Visual C++ 파일 열기 다이얼로그 API

char szFile[256];
  //API file dialog
  OPENFILENAMEA ofn;
  ZeroMemory(&ofn, sizeof(ofn));
  ofn.lStructSize = sizeof(ofn);
  ofn.hwndOwner = NULL;
  ofn.lpstrFile = szFile;
  ofn.lpstrFile[0] = '\0';
  ofn.nMaxFile = sizeof(szFile);
  ofn.lpstrFilter = "All\0*.*\0Map\0*.map\0";
  ofn.nFilterIndex = 1;
  ofn.lpstrFileTitle = NULL;
  ofn.nMaxFileTitle = 0;
  ofn.lpstrInitialDir = NULL;
  ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
  BOOL ret = GetOpenFileNameA(&ofn);
  if (ret) {
   // load map and enter training mode
  }

Friday, June 19, 2015

Debugging Managed C++ (If the breakpoint is not hit)

When linking C# and Managed C++, there are times when a breakpoint is set in C# but not in Managed C++ alone.

In that case, follow these two procedures:
1. In the Managed C++ properties window, set Debugging - Debugger Type to Mixed.

2. In Visual Studio options, check Debugging - Use Managed Compatibility Mode.

Wednesday, June 17, 2015

Freetype 문자열 픽셀 길이 구하기

int penx = 0;
    for (int i = 0; i < wcslen(wstr); i++) {
        if (len > 0 && i >= len)
            break;
        FT_Load_Char(face, wstr[i], FT_LOAD_NO_BITMAP);// 문자열 width 테스트용
        penx += face->glyph->advance.x >> 6;
    }
return penx;

Freetype 안티 알리아싱(anti aliasing) 적용 안하기

bool glyphBit(const FT_GlyphSlot &glyph, const int x, const int y)
{
    int pitch = abs(glyph->bitmap.pitch);
    unsigned char *row = &glyph->bitmap.buffer[pitch * y];
    char cValue = row[x >> 3];
    return (cValue & (128 >> (x & 7))) != 0;
}

for (int idx = 0; idx < wcslen(wstr); idx++) {
//FT_Load_Char(face, wstr[idx], FT_LOAD_RENDER | FT_LOAD_NO_BITMAP);// 이렇게 하면 anti-aliasing 적용됨
FT_Load_Char(face, wstr[idx], FT_LOAD_RENDER | FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO);
int width = face->glyph->bitmap.width;
int height = face->glyph->bitmap.rows;

for (int i = 0; i < height; i++) {//y
for (int j = 0; j < width; j++) {//x
 
// 비트별로 8비트 팩되어 있으므로 그것을 풀어냄
bool value = glyphBit(face->glyph, j, i);
 
// true일 경우 글자 칠해진 픽셀
if (value)
{
// 이제 까만 영역이므로 색칠을 하자
int xx = face->glyph->bitmap_left + j;
int yy = FREETYPE_SIZE - face->glyph->bitmap_top + i;
int idx = tgt->wid*yy + xx;
pimg[idx] = 1;
}
}
}

Tuesday, June 16, 2015

Visual C++에서 iconv 사용하여 wchar_t 변환하기

Visual C++에서는 wchar_t로 유니코드를 사용한다. 그런데 유닉스나 모바일 호환성을 위해서 Win32 API가 아닌 iconv로 인코딩을 변환하다보면 에러가 발생한다.

그럴때는 다음과 같이 tocode에 "UTF-8" 대신에 "WCHAR_T"를 입력하면 된다.
char str[] = "두덕리온라인";
TCHAR str2[4096];
iconv_convert("WCHAR_T", "EUC-KR", str, (char*)str2, 4096 * 2);

현재 사용하고있는 iconv 래퍼 함수이다.
int iconv_convert(const char* tocode, const char* fromcode, const char* instr, char* outbuf, size_t outlen)
{
    iconv_t cd = iconv_open(tocode, fromcode);
    if (cd == (iconv_t)(-1)) {
        //LOG("iconv_open error");
        return -1;
    }

    // 이거 왜이렇게 했지? 내부적으로 버퍼를 사용함
    char inbuf[BUF_SIZE];
    sprintf(inbuf, "%s", instr);

    // 포인터만 기록해 놓음
    const char *in = inbuf;
    size_t inlen = strlen(in);

    // 메모리 초기화
    memset(outbuf, 0, outlen);
    char *out = outbuf;

    if (iconv(cd, &in, &inlen, &out, &outlen) < 0) {
        //LOG("iconv error");
        return -1;
    }

    iconv_close(cd);
    return 0;
}

Monday, June 15, 2015

Visual Studio 2013 C4996 에러 완벽 해결법

C4996에러는 Visual Studio 2005버전부터 unsafe한 함수를 다른 함수로 대체하라는 명령이다.

warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

에러 메세지를 보면 define등으로 정의를 해주어야 하는데 그럴 필요없이 다음과 같이 컴파일러 옵션에서 SDL(Secure Development Lifecycle) checks을 끄면 자동으로 해결 된다.





Monday, June 1, 2015

Visual Studio 2010 IDE 최적화(3/3) - WPF(XAML)

Visual Studio 2010 최적화의 3편, WPF(XAML)언어 최적화이다.

1. 먼저 Options - Text Editor - XAML - Apply Cut or Copy commands to blacnk lines when there is no selection을 끈다.

2. Formatting에서 자동완성과 관련된 기능들을 전부 끈다.

3. 기타 자동완성 기능을 끈다. 그리고 XAML 최적화에서 중요한 게 Always open documents in full XAML view를 끄는 것이다. 이는 XAML 파일을 열었을 때 언제나 UI디자인 에디터가 나오게 되던 것을 XAML 텍스트 편집을 우선 나오게 함으로서 UI 에디팅시 최적화를 제공한다.


Friday, April 10, 2015

Visual Studio 2010 IDE 최적화(2/3)

지난글에 이어서 Visual Studio 2010 IDE 최적화(프로그래밍시 사용하는 UI) 2번째이다.
이번에는 좀더 심화적으로 속도업을 해보았고, 이후에는 언어별 최적화를 할 예정이다.

1. 일단 OS가 윈도우XP라면 다음과 같이 윈도우XP 스타일로 만들자. 클래식 스타일보다는 원래 윈도우XP 스타일이 GUI렌더링시 더 빠르다.(의외의 결과임)

2. 다음과 같이 바탕화면 등록정보에서 ClearType을 끄자. 이는 글자를 부드럽게 만들어 주는 옵션인데 소스 편집시 텍스트 렌더링에 많은 리소스를 차지 한다.

3. Visual Studio 2010 IDE를 열어서 [Tools]-[Options]로 간다.
그리고 다음과 같이 Rich Client Visual Experience를 끈다. 이것은 윈도우7의 Aero인터페이스와 비슷하다.

4. Macro를 전부 끈다. 특별히 사용하는 매크로가 있으면 패스하자.

5. 자동 복구정보를 5분에 한번씩 저장하는 기능을 끄자.

6. 현재 윈도우 재사용 기능(저장되었다면), 외부에서 편집된 파일을 로딩하는 기능, 저장할때 리드온리 워닝기능 등을 끄자.

7. IDE 로딩시 빈 페이지를 로딩하게 하자.

8. 비쥬얼 스튜디오 익스텐션 갤러리에 접속하는 걸 막자.

9. 편집하고 계속하기를 끄자.

중간중간에 안해도 되는 부분이 있지만 이렇게 하면 공통 UI부분은 최적화가 된다. 다음 순서는 언어별 옵션 설명과 최적화이다.

Visual Studio 2010 IDE 최적화(1/3)

Visual Studio 2010으로 소스편집을 하다가 너무 느려져서 예전의 2005/2008과 같은 최적화 옵션이 있는지 알아봤다. Visual Studio 2005/2008에는 UI 애니메이션을 끄는 것과 소스 편집시의 몇가지 옵션이 있었다. 그런데 Visual Studio 2010에서는 UI쪽이 약간 변경이 되었다.

간단하게 UI 애니메이션과, 소스 편집시 delimeter highlighting만 껐다.

1)UI 애니메이션 끄기

2)소스 편집시 delimeter highlighting, drag and drop, utf-8 자동 인식 끄기


이렇게 하면 쓸데없는 UI애니메이션과 delimeter highlighting 등을 안하게 된다. 소스편집시에 멤버변수나오거나 하는데에는 전혀 문제가 없다. 그리고 속도도 무척 만족할만하게 빨라졌다.

Visual Studio에서 Visual C++ 화면 레이아웃 및 키보드로 재설정하기

일반적으로 Visual C++개발자가 Visual Studio .NET(2002이상, Visual C++ 7.0이상)으로 넘어 왔을 경우에 화면의 레이아웃(배치)라던가 키보드 단축키 설정이 마음에 들지 않는다. 왜냐면 Visual Studio 6.0은 Visual C++이 그 자체로 Visual Studio를 대표하고 있었고, Visual Studio .NET은 VB개발자를 통합하여 만든 것이기 때문에 VB의 화면 레이아웃도 가져온 경향이 있다.

아무튼, 전통적인 Visual C++개발자에겐 6.0의 레이아웃과 단축키가 가장 익숙하다. F5로 디버그 실행, Ctrl+F5로 실행, F7로 빌드 등... 그런데 Visual Studio .NET으로 넘어올 경우에 설치후 최초 실행시 세팅을 정하라는 화면에서 설정하지 않으면 다시 찾기란 쉽지 않다. 또한, Visual Studio 버전별로 설정 메뉴의 위치가 상이하므로 최신버전인 Visual Studio 2010에서 Visual C++ 설정을 하는 방법을 알아 보겠다.

Visual Studio C++ 설정을 하지 않은 화면

먼저 [Tools] - [Import and Export Settings...]를 선택

다음과 같은 Import and Export Settings Wizard에서 Reset all settings를 선택

Save Current Settings에 No라고 선택

다음 설정에서 Visual C++ Development Settings를 선택

Reset 완료

짜잔! 다음과 같이 Visual Studio 2010의 레이아웃이 바뀌면서 키보드(단축키) 셋팅도 바뀐다.

Visual Studio 2010 - Visual Studio 2008(v90)으로 컴파일 하기

Managed C++ 프로젝트의 .NET Framework 버전 선택

Visual Studio 2010을 발표하면서 가장 큰 공약으로 내 건 것이, .NET Framework 뿐만 아니라 네이티브인 Visual C++도 이전 버전의 컴파일러(ToolSet)을 사용하게 해준다고 한 것이다. 그러나 공약만 거창했을 뿐, 실제로는 Visual Studio 2008만 하위버전 컴파일러를 지원한다. 그리고 실제 Visual Studio 2008에 대한 라이센스와, Visual Studio 2008이 설치가 되어 있어야 한다.

다음과 같이 [General] - [Platform ToolSet]을 v90으로 맞춘다. v100은 10.0이라는 뜻으로 Visual Studio 2010이며, v90은 2008, v80은 2005, v71은 2003, v70은 2002라는 것은 Visual Studio 사용자라면 익히 일수 있는 버전번호이다.

그런데 이것은 컴파일러만 v90을 선택하기로 한것이지, 나머지 include(STL)이나 lib는 v100을 사용하겠다고 암묵적으로 동의한 것이다. 따라서 완벽한 호환성을 보장하기 위해서는 아래의 include, lib를 Visual Studio 2008의 것으로 다음과 같이 설정을 추가해주어야 한다.

[C/C++] - [General] - [Additional Include Directories]
- "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include" (64비트)
또는
- "C:\Program Files\Microsoft Visual Studio 9.0\VC\include" (32비트)


[Linker] - [General] - [Additional Library Directories]
(64비트 머신에서)
- C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib\amd64 (64비트 컴파일)
- C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib (32비트 컴파일)
(32비트 머신에서)
- C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib


이렇게 설정하면 include와 lib가 Visual Studio 2008과 동일하게 설정되어 컴파일 결과도 같아진다.

Managed C++ 프로젝트의 .NET Framework 버전 선택

.NET Framework 버전 선택은 C#등 .NET Framework 프로젝트에서는 프로젝트 속성창에서 Target Framework 버전을 선택할 수 있었다.

그런데 Visual Studio 이전버전의 Managed C++ 프로젝트를  변환한 경우에는 Target Framework 버전을 프로젝스 속성창에서 명시적으로 선택할 수가 없다.(Managed C++의 경우 프로젝트 속성창이 .NET Framework 프로젝트와 상이하기 때문이다.) 기본적으로 Visual Studio 2010의 경우에는 .NET Framework 버전이 4.0이다. 그대로 컴파일 할 경우에는 많은 문제가 발생한다.

따라서, Visual Studio 2008 이전버전의 Managed C++ 프로젝트를 Visual Studio 2010으로 변환한 경우에는 다음과 같이 *.vcxproj(Visual Studio 2010에서 vcproj가 vcxproj로 변환됨)에 아래 문장을 삽입 함으로서 이전 버전의 Visual Studio 에서 지원하는 Framework으로 명시적으로 기술할 수가 있다.

<Project ...>
  <PropertyGroup>
    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
  </PropertyGroup>
</Project>

위 문장으로 Visual Studio 2010의 Managed C++프로젝트는 .NET Framework 2.0을 사용하여 컴파일 한다.

Managed C++에서 System.BadImageFormatException 에러

An unhandled exception of type 'System.BadImageFormatException' occurred in mscorlib.dll
Additional information: Could not load file or assembly 'CLRMC8, Version=1.0.3820.17987, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format.

위와 같은 에러메세지가 Managed C++.NET에서 DLL로 만든 다음에 C# 프로젝트에서 참조로 넣어서 로딩할때 발생하였다. (개발환경은 Windows XP 64Bit/Visual Studio 2005/2008/2010)

C#으로 Class Library를 만들어서 C# 프로젝트에서 참조로 넣었을때는 되는데 왜 MC++로 만들때는 저렇게 에러가 나는가... 고민끝에 나온 결론은 C++은 x86/x64가 엄격하게 분리가 되며, C#은 Any CPU라는 것이 있어서 알아서 적용이 되는 것 때문에 그랬던 것이다.

따라서 위와 같은 문제를 해결하려면, C++을 x86 -> C#도 x86으로 명시적으로 Configuration Manager에서 설정하고, C++을 x64일 경우에는 C#도 x64로 명시해 주어야 한다.


Visual C++ MD5 암호화 예제

MD5 암호화를 MIT에서 공개한 라이브러리의 예제파일이다.

다운로드

Monday, April 6, 2015

Visual C++ MFC MDI 프로그램 시작시 뜨는 도큐먼트 없애기

자동으로 열리는 빈 윈도우를 없애는 방법은 의외로 간단하다. 클래스 위저드로 생성한 소스중 xxxApp.CPP라는 파일에 CWinApp에서 상속받은 클래스가 들어 있는데, 이 멤버 함수중 InitInstance() 안에 다음 코드가 존재한다.
ParseCommandLine(comInfo);
if( ProcessShellCommand(...))..

이 두 줄 사이에 다음 코드를 추가하면 프로그램이 처음 실행될 때 쉘명령(ShellCommand)으로 새로운 파일을 만들라는 'FileNew' 명령행이 인자로 들어오게 됩니다(도큐먼트를 지정하지 않았을 때). 이 경우에만 FileNothing으로 바꿔주면 빈 도큐먼트를 만들지 않으며 당연히 뷰/프레임도 보이지 않는다.

if(cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew )
  cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;

Visual C++ MFC 실시간 윈도우 스타일 변경하기

void CMainFrame::OnStyleNosysmenu()
{
        // 기존의 스타일 정보를 얻는다
        long style = GetWindowLong(m_hWnd, GWL_STYLE);
        // 시스템 메뉴 속성을 없앤다
        style &= ~WS_SYSMENU;
        // 변경된 스타일 반영
        SetWindowLong(m_hWnd, GWL_STYLE, style);
        // 화면이 실제로 변경된 것을 반영하도록 한다
        SendMessage(WM_NCPAINT, (WPARAM)1);
}

void CMainFrame::OnStyleSysmenu()
{
        long style = GetWindowLong(m_hWnd, GWL_STYLE);
        style |= WS_SYSMENU;
        SetWindowLong(m_hWnd, GWL_STYLE, style);
        SendMessage(WM_NCPAINT, (WPARAM)1);
}