https://msdn.microsoft.com/ko-kr/library/h90dkhs0(v=vs.90).aspx

 

 

=============================================

출처- 하기 블로그에서 참고하였으며, 문제가 되면 삭제하겠습니다.

        http://legendfinger.tistory.com/449

=============================================

 

 

공유 메모리 

일반적으로 exe나 DLL안의 전역변수들은 기본적으로 PAGE_WRITECOPY 속성이 지정되기 때문에 쓰기전에 복사본이 만들어진다(Copy-On-Write) 그러므로 A와 B는 둘 다 다른 물리 공간을 사용하게 된다.

하지만 DLL내에 공유 메모리를 만들어 사용하면 서로 다른 2개의 프로세스가 DLL내의 공유 메모리를 사용해서 통신할 수 있다.

 

DLL 공유 섹션 만드는 방법

#pragma data_seg("SHARED")

char shared_buffer[1024] = {0};

#pragma data_seg()

 

#pragma comment(linker, "/subsystem:SHARED,RWS")

 

단점(보안에 취약하다)

DLL은 Kernel Object의 보안속성을 줄수 없으므로 다른 프로세스에서 DLL을 로드하여 데이터를 가로챌수있다.(보안에 상관없는 통신에서 사용해야한다)

 

 

--------------------------------- X.dll -------------------------------------

공유 메모리 설정 DLL 파일

구성 파일 : X.h, a.cpp

 

X.h 

// X.h

 

#include <windows.h>

 

#ifdef DLLSOURCE

        #define DLLAPI __declspec(dllexport)

#else

        #define DLLAPI __declspec(dllimport)

#endif

 

EXTERN_C DLLAPI void Set(int);

EXTERN_C DLLAPI int        Get();

 

//--------------------------------------------------

 

 

a.cpp

 

// a.cpp

 

#define DLLSOURCE

 

#include "X.h"

 

// DLL 안에 공유 메모리를 만들면 이 DLL을 사용하는 모든 프로세스에서

// 공유 할 수 있다.

#pragma data_seg("SHARE")

int x = 0;        // 주의! 반드시 초기화된 data만 공유 메모리에

                  // 들어갈수있다.

#pragma data_seg()

 

 

#pragma comment(linker, "/section:SHARE,RWS")

// " "안에 띄여쓰기 하지 마라

 

void Set(int value)

{

        x = value;  // 공유 메모리를 변경한다

}

 

int Get()

{

        return x;

}

 

 

----------------------- AA.exe ------------------------------

공유메모리에 값을 할당하는 프로그램

 

#include <windows.h>

#include <stdio.h>

 

// X.h와 X.lib 복사해 와라

#include "X.h"

#pragma comment(lib, "X.lib")

 

void main()

{

        HANDLE hEvent = CreateEvent(0, 0, 0, "e");

 

        while(1)

        {

                int n = 0;

                printf("숫자를 넣으세요 >>");

                scanf("%d", &n);

 

                Set(n);       // DLL 안에 있는 공유 메모리에 data를 넣는다

 

                SetEvent(hEvent);

        }

}

 

// X.h와 X.lib는 현재 폴더에 복사해오세요

// X.dll은 c:\\winnt 아래에 복사해두세요

//      - BB프로세스와 공유하기 위해

 

 

 

------------------------------ BB.exe ---------------------------------

공유 메모리 값을 출력하는 프로그램

 

#include <windows.h>

#include <stdio.h>

 

// X.h와 X.lib 복사해 와라

#include "X.h"

#pragma comment(lib, "X.lib")

 

// DLL 안에 공유 메모리를 사용한 IPC 기법

 

void main()

{

        HANDLE hEvent = CreateEvent(0, 0, 0, "e");

 

        while(1)

        {

                WaitForSingleObject(hEvent, INFINITE);

 

                int n = Get();

 

                printf("X 값 : %d\n", n);

        }

}

 

// X.h와 X.lib는 현재 폴더에 복사해오세요

 

// B를 먼저 실행하고

// A를 실행 해보세요

// A에 값을 넣고 Enter

 

 

 

=============================================

출처- 하기 블로그에서 참고하였으며, 문제가 되면 삭제하겠습니다.

        http://blog.daum.net/mrdk/60

=============================================

 

callback 함수를 알아보기 전에..

   먼저 함수를 가리키는 포인터를 만들어서 그 포인터로 어떤 함수를 호출하는 방법에 대해 알아보자.

 

  먼저 다음과 같이 type def를 한다.

  typedef int (*func) (int);

 

  이렇게 하면,  func는  int를  return하고 int를 인자로 받아들이는 함수를 가리키는 포인터의 형이 된다.

  이와 같은 형태의 함수면 어떤 거든 포인트 할 수가 있다.

 

   예를 들어

   int example_function(int param1)

   {

          printf("%d",param1);

    }

    다음과 같은 함수가 있다면,

   

   func pointer_to_func;

   pointer_to_func = example_function; 

   pointer_to_func(5); 

   이것은 곧...

   example_function(5); 와 동일한 결과를 낳는다.

 

   여기까지가...

   함수에 대한 포인터를 만들어서 이 포인터로 함수를 호출하는 방법에 해당한다....

 

   그러면 DLL에서를 생각해보자. DLL이 쓰이는 상황은,

    User Program 과 DLL로 나눠서 생각을 해봐야 한다.

   

    DLL에 함수들이 잔뜩 있으며, User Program에 함수가 잔뜩 있다.

    우리는 DLL에서 User Program의 함수를 호출하게끔 만들고 싶을 수 있다.

    특정 파라메터를 가지고 DLL에서 user Pgoram의 함수를 호출하게 하여

    통신 비스므리한 효과를 내는 것이다.

 

    

  이를 위해서는 그림에서 보다시피,

  User Program에서는 그렇게 호출받기 원하는 함수를 정의한다. 함수1이 정의 되었으면,

  DLL에 있는 레지스터콜백을 위한 함수에다 이 함수의 이름(포인터)를 넘겨주면

  콜백이 등록이 되는 것이다.

  

   그러면, DLL에서는, 이렇게 넘겨온 함수에 대한 포인터를 가리킬 전역변수를 하나 만들고(func callbackFunc

   DLL레지스터콜백에서는 넘겨온 함수의 포인터를 callbackFunc에 배정을 시킨다.

 

   그러면 어떤다른 함수에서 user Program의 특정 함수를 호출해야 겠다 싶으면,

    callbackFunc()를 호출하면 user Program에서 지정한 함수가 호출되게 되는 것이다.


void CxxxDlg::OutputDispData(CONST TCHAR* pBuf, ...)
{
 va_list     ap; 
 TCHAR szInformBuf[1024]{0}; 
   
 if (pBuf != NULL)
 {
  va_start(ap, pBuf);
  ::_vsntprintf_s(szInformBuf, sizeof(szInformBuf) / sizeof(TCHAR), sizeof(szInformBuf),pBuf, ap);
  va_end(ap);  


 } 

}

 

 

// char * 가변인수

 if(pBuf != NULL)
 {
  va_start( ap, pBuf );
  vsprintf( szInformBuf , pBuf, ap );
  va_end( ap );
}

 

STL C++11 관련하여,

thread를 사용하고자 하는 경우 하기 처럼 지정하고 사용하면 된다.

 

 

예) Log 관련 thread를 만들고자 한다면...

.h 지정

#include <sstream>

 

 volatile bool     m_bAlive_thread_queueLogMsg;
 std::mutex      m_mutex_queueLogMsg;
 std::thread      m_thread_queueLogMsg; 
 void       m_fn_run_queueLogMsg_Proc();

 

 

 

.cpp 사용

 -. 종료하기

 // thread 안전 종료
 m_bAlive_thread_queueLogMsg = false;
 if (m_thread_queueLogMsg.joinable())
  m_thread_queueLogMsg.join();

 

 

 -. 생성하기

 // log receiver thread 생성
 m_bAlive_thread_queueLogMsg = true;
 m_thread_queueLogMsg = std::thread(&해당Class::m_fn_run_queueLogMsg_Proc, this);

 

 

 -. thread body

 while (m_bAlive_thread_queueLogMsg)
 {
  if (PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_REMOVE))

......

 

    {
     // mutext guard & insert queue
     std::lock_guard<std::mutex> lock(m_mutex_queueLogMsg);  // 지역 mutex 걸기.
     m_queueLogMsgContainer.push(stLogMsgInf);     
    }

 

Thread 안에서   Window Message를 사용하고자 한다.

이러한 경우 외부에서 PostThreadMessage를 사용하여야 한다.

std::thread::id 정보를 이용하여 threadid를 가져오는게 가능하다.

 

///////////////////////////////////////////////////////////

 auto myid = m_thread_queueLogMsg.get_id();
 std::stringstream ss;
 ss << myid;
 string mystring = ss.str();
 uint64_t test = std::stoull(ss.str());

DWORD dThreadId = (DWORD)test;

 PostThreadMessage(dThreadId, WM_USER, (WPARAM)xxx, (LPARAM)yyy);

///////////////////////////////////////////////////////////

 

이상.

 

 

 

하기 사이트에서 발췌:

http://extern.tistory.com/2

 

 

1, 바이트 정렬(Byte Alignment) 왜 해야 하는가 ?

현재 일반적으로 많이 사용하는 32bit 체계를 예를들면, CPU 가 메모리에서 데이타를 가지고 올때
32bit 즉 4byte 의 데이타를 가지고 와서 처리를 한다. 이 얘기는 CPU 가 메모리의 주소를 4byte 단위로
쪼개서 접근을 한다는 말과 같겠다. 

말로 하면 머리에 잘 안들어온다. 예들 들어보도록 하자.

int n; 이라는 변수가 있다.
이변수의 주소는 0x1000 ~ 0x1004 이다. 왜냐 4byte 변수니까 4byte 를 차지하고 있겠지.
이러면 cpu 에서 메모리 0x1000 ~ 0x1004 의 조소를 한번에 받아 처리 할수가 있다.
CPU 는 32bit 씩 처리 되니까.
이러면 아무런 문제가 없다. 그런데 만일 int n;. 의 변수가 0x1001 ~ 0x1005 의 주소에
존재 한다고 생각해 보라.
그러면 CPU 는 메모리의 0x1000 ~ 0x1004, 0x1005 ~ 0x1008 의 주소를 받아서 처리해야
int n; 을 처리할 수 있는것이다.

그러면 쓰잘데기 없이 두번의 일을 하는 결과가 됐다. 그래서 바이트를 정렬해서 효율을 높이자는 것이다.

2, 그럼 실제 바이트 정렬(Byte Alignment) 을 어떻게 설정하나 ?

VC++ 설정에 보면 기본적으로 바이트 정렬해야 하는 byte 가 설정이 되어있다.
다른 컴파일러는 잘 모르것다. 있긴 있겠지 ㅡㅡ

사용자 삽입 이미지

 

[VC++ 71 설정화면]

이렇게 말로만 해서는 감이 안온다. 직접 코드를 보고 비교해 보장.

사용자 삽입 이미지














이와 같은 코드를 높고 설정값을 변경 해보자. 결과는 다음과 같다.

설정값 ==> nsize 값
1byte ==> 5 (ch, n, n, n, n)
2byte ==> 6 (ch0, nn, nn)
4byte ==> 8 (ch000, nnnn)
8byte ==> 8 (chnnnn000)

% ch: char 변수, n: int 변수, 0: byte padding

3, 컴파일러 바이트 패딩(Compiler Byte Padding) 은 무엇인가 ?

위의 예에서 STTEST 구조체가 실제 5byte 이라도 구조체 멤버 설정이 2byte 이면 6byte 로 나온다.
어떻게 처리되는 것일까 ?

2byte 단위로 정렬하기 때문에 하나의 단위를 2byte 라고 생각해 보자. 그리고 구조체 내의 변수를 넣어보자
처음 char 을 2byte 중 첫번째 바이트에 넣고 다음 int 를 넣으려고 했는데, 4byte 중 1byte 밖에 넣을수가
없다. 그래서 컴파일러는 2byte 정렬제한을 위반하지 않도록 바이트 패팅을 추가하여 char 를 2byte처럼
처리하고 다음 공간부터 int 를 저장한다.


4, 바이트 정렬을 코드에서 처리하기

바이트 정렬 구간을 소스에서 정의 하려면 "#pragma pack" 을 사용한다.

#pragma pack(1)
typedef struct Test
{
 char ch;
 int n;
}STTEST;
#pragma pack()

이렇게 사용하면 1byte 로 정렬하게 된다.
%참고로 "pragma" 키워드는 컴파일러에게 어떻게 처리하라고 명려하는 컴파일러 지시자 이다.

추가로 정렬을 Stack 를 이용할수도 있다.

#pragma pack(push, 1)
typedef struct Test
{
 char ch;
 int n;
}STTEST;
#pragma pack(pop)

요런식이 되겠다.

% 1,2,4,8,16 이외의 값을 설정하면 무시되고 컴파일러 옵션에 설정된 값으로 사용된다.

 

'프로그래밍 > VC++ 개발 코딩' 카테고리의 다른 글

w_char (TCHAR) 가변인수 만들기  (0) 2016.04.29
C++11 STL thread 처리 관련  (0) 2016.04.05
DebugView 사용하기  (0) 2015.09.21
프로그램 관리자 권한 주기  (0) 2015.09.15
64bit Bit Shift  (1) 2015.09.14

https://technet.microsoft.com/en-us/library/bb896647.aspx

 

Win32계열 프로그램 개발시에 소스코드에 OutputDebugString을 출력하는 부분은 

모두 디버그 뷰로 볼 수 있습니다.

 

참고로 디버그 모드(비주얼스튜디오에서는 F5를 눌른상태)로 실행을 하시면 디버그뷰에는 출력이 안됩니다.

 그냥 Ctrl+F5로 실행하시면 디버그뷰에서 출력이 됩니다.

 

서버화 시킬수도 있는데요

 방법은 /c를 첨부해서 실행하시면 됩니다.

 

즉, 콘솔 모드에서 debugview.exe /c로 실행하시면 서버화 되어

(Tip. 바로가기를 만드신 다음에 속성에서 대상에 보이시는 .exe 파일 다음에 /c를 추가해도 됩니다.)

 

다른 컴퓨터에서 해당 컴에 접속을 하시면 메시지가 디버그뷰에 출력이 됩니다.(접속은 한대만 가능합니다)

 

'프로그래밍 > VC++ 개발 코딩' 카테고리의 다른 글

C++11 STL thread 처리 관련  (0) 2016.04.05
바이트 정렬(Byte Alignment) pragma pack(1)  (0) 2015.11.20
프로그램 관리자 권한 주기  (0) 2015.09.15
64bit Bit Shift  (1) 2015.09.14
mutex 사용하기  (0) 2014.10.28

하기 사이트에서 발췌... (감사합니다.)

http://blog.naver.com/sbspace?Redirect=Log&logNo=130163194983

 

 

프로젝트를 컴파일해서 나온 실행파일에 관리자권한을 주고 싶을 때가 있다. 예를 들어, C:\Program Files 또는 C:\Windows 에서 실행하고 그 안에서 파일쓰기나 수정을 하려면 반드시 관리자권한으로 실행해야하기 때문이다. 물론 실행파일을 우클릭하고 관리자권한으로 실행하기 메뉴를 선택하거나 속성-호환성에서 항상 관리자권한으로 실행되도록 할 수도 있다. 하지만 조금 번거로운 면이 있기 때문에 아예 실행파일에 관리자권한을 준 상태로 컴파일하는 방법을 이용하는 것도 좋다.

 

핵심은 프로젝트 속성 - 링커 - 매니페스트 파일 에서 사용자권한을 변경하면 된다. 변경하는 방법은 매니페스트 파일의 내용을 편집하면 된다. 다이얼로그 기반으로 임의의 프로젝트를 생성하면 "프로젝트명.exe.intermediate.manifest "라는 매니페스트 파일이 생긴다. 이것을 메모장이나 기타 에디터로 열면 대략 아래와 비슷한 내용이 있을 것이다. 이 중에서 하이라이트 표시한 부분을 주목하자. 기존에는 'asInvoker'로 되어있었는데 'requireAdministrator'로 수정하고 컴파일하니 실행파일에 작은 방패모양이 붙으면서 자동으로 관리자권한으로 실행할 수 있게 되었다.

 

 

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level='requireAdministrator' uiAccess='false' />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.VC90.DebugCRT' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.VC90.DebugMFC' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*' />
    </dependentAssembly>
  </dependency>
</assembly>

 

'프로그래밍 > VC++ 개발 코딩' 카테고리의 다른 글

바이트 정렬(Byte Alignment) pragma pack(1)  (0) 2015.11.20
DebugView 사용하기  (0) 2015.09.21
64bit Bit Shift  (1) 2015.09.14
mutex 사용하기  (0) 2014.10.28
WM_NCHITTEST 메세지  (0) 2014.04.30

32 compile 환경에서 64bit 만큼의 Bit Shift를 수행하는 경우,

Warning 발생되며 캐스팅해주지 않으면 32bit 이상 shift가 불가하다.

 

하기는 MSDN 에서 발췌한 정보..

컴파일러 경고 (수준 3) C4334

'operator' : 32비트 시프트의 결과가 암시적으로 64비트로 변환됩니다. 64비트 시프트를 사용하시겠습니까?

 

32비트 시프트의 결과가 암시적으로 64비트로 변환되었습니다. 컴파일러에서 64비트 시프트의 적용 여부를 결정할 수 없습니다. 이 경고를 해결하려면 64비트 시프트를 사용하거나 시프트 결과를 명시적으로 64비트로 캐스팅해야 합니다.

다음 샘플에서는 C4334 오류가 발생하는 경우를 보여 줍니다.

// C4334.cpp
// compile with: /W3 /c
void SetBit(unsigned __int64 *p, int i) {
   *p |= (1 << i);   // C4334
   *p |= (1i64 << i);   // OK
}

'프로그래밍 > VC++ 개발 코딩' 카테고리의 다른 글

DebugView 사용하기  (0) 2015.09.21
프로그램 관리자 권한 주기  (0) 2015.09.15
mutex 사용하기  (0) 2014.10.28
WM_NCHITTEST 메세지  (0) 2014.04.30
오픈 라이센스 Dia Program 소개  (0) 2014.01.23

 

하기 사이트에서 발췌하였습니다.   문제가 된다면 삭제하겠습니다.

http://jacking.tistory.com/1066

 

 

병렬 프로그래밍을 해보면 싫든 좋든 여러 스레드에서 하나의 객체에 동시에 접근하는 경우가 발생합니다. 앞선 std::thread에 관한 글을 보면 소개한 예제 중 그런 경우를 보실 수 있을 겁니다.

 

< 예제 >

#include <thread>

#include <iostream>

 

int main()

{

           std::thread Threads1( [] ()

              {

                        for( int i = 0; i < 5; ++i )

                        {

                                          std::cout<< "Thread Num : " << i << std::endl;

                        }

              } );

 

 

           std::thread Threads2;

           Threads2 = std::thread( [] ()

              {

                        for( int i = 10; i < 15; ++i )

                        {

                                          std::cout<< "Thread Num : " << i << std::endl;

                        }

              } );

 

           std::thread Threads3 = std::thread( [] ( int nParam )

              {

                      for( int i = 20; i < 25; ++i )

                      {

                                std::cout<< "Thread Parameter : " << nParam << std::endl;

                      }

              }, 4 );

 

           getchar();

           return 0;

}

 

위 예제에서 ‘std::cout’ 각 스레드에 동시에 접근하고 있습니다. 그래서 실행하면 아래와 같은 결
과가 나옵니다.


실행 화면을 보면 출력 결과 중 일부가 뒤죽박죽 되어 있는 것을 알 수 있습니다. 이유는 Thread1 스레드에서 출력스트림 결과를 다 출력하기 전에 Threads2가 출력스트림을 사용하여 발생한 문제입니다. 이런 것을 data-race(데이터 경합) 이라고 합니다.

 

그런데 위 예제를 여러 번 실행해 보면 아래처럼 올바르게 나올 때도 있습니다.



사실 이런 부분이 병렬 프로그래밍의 어려움 중의 하나입니다. 여러 스레드에서 하나의 공유 자원을 사용할 때 타이밍에 의해서 순서대로 사용할 수도 있고 그렇지 못할 수도 있기 때문에 버그 발생이 언제 어떻게 생길지 알기 힘듭니다.

 

병렬 프로그래밍을 할 때는 언제나 공유 자원을 최소한으로 하고, 공유 자원은 꼭 동기화 객체를 사용하여 여러 스레드가 동시에 사용하지 못하도록 해야 합니다.

 

위의 문제는 동기화 객체를 사용하면 해결 할 수 있습니다. 여기서는 앞선 글에서 사용한 적이 있는 뮤텍스(std::mutex)를 사용하겠습니다.

 

그럼 위 예제를 mutex를 사용하여 문제를 해결해 보겠습니다.

 

<예제 1 >

#include <thread>

#include <iostream>

#include< mutex>

 

int main()

{

           std::mutex mtx_lock;

 

           std::thread Threads1( [&] ()

              {

                        for( int i = 0; i < 5; ++i )

                        {

                                          mtx_lock.lock();

                                          std::cout<< "Thread Num : " << i << std::endl;

                                          mtx_lock.unlock();

                        }

              } );

 

 

           std::thread Threads2;

           Threads2 = std::thread( [&] ()

              {

                        for( int i = 10; i < 15; ++i )

                        {

                                          mtx_lock.lock();

                                          std::cout<< "Thread Num : " << i << std::endl;

                                          mtx_lock.unlock();

                        }

              } );

 

           std::thread Threads3 = std::thread( [&] ( int nParam )

              {

                      for( int i = 20; i < 25; ++i )

                      {

                                 mtx_lock.lock();

                                 std::cout << "Thread Parameter : " << nParam << std::endl;

                                 mtx_lock.unlock();

                      }

              }, 4 );

 

          

 

           getchar();

           return 0;

}

 

< 실행 결과>



std::mutex를 사용하기 위해서는 아래의 헤더 파일을 추가합니다.

#include <mutex>

 

스레드에서 공유 자원을 사용할 때는 아래 처럼 락을 걸어서 뮤텍스 mtx_lock의 소유권을 얻어서 다른 스레드가 접근하지 못하도록 합니다. 그리고 공유 자원을 다 사용하였다면 락을 해제하여 mtx_lock의 소유권을 버립니다.

mtx_lock.lock();

std::cout << "Thread Num : " << i << std::endl;

mtx_lock.unlock();

 

락을 건 후(lock) 락을 풀(unlock) 때까지는 다른 스레드는 대기를 하고, 락을 풀면 대기하고 있는 스레드 중 하나가 락을 건 후 공유 자원을 사용합니다.

그러므로 락을 건 후에는 꼭 락을 풀어야 하고(만약 풀지 않으면 데드락 상황에 빠지게 됩니다), 락을 사용하는 부위가 너무 빈번하면(스레드 대기가 늘어나므로) 병렬 프로그래밍의 장점이 많이 약해집니다.

 

 

try_lock

std::mutex lock unlock 이외에 try_lock 이라는 멤버 함수가 있습니다.

bool try_lock();

 

스레드에서 lock을 호출할 때 다른 스레드가 이미 lock을 호출하여 뮤텍스의 소유권을 가진 후 아직 unlock을 호출하지 않았다면 그 자리에서 대기를 합니다. 그러나 try_lock은 대기를 하지 않고 false를 반환합니다(뮤텍스의 소유권을 얻지 못한 경우). 반대로 true를 반환한 경우는 뮤텍스에 대한 소유권을 가지게 되므로 공유자원을 안전하게 사용할 수 있습니다.

 

try_lock을 사용하는 경우는 만약 공유 자원을 다른 스레드에서 사용 중이면 스레드가 대기하면서 그냥 시간을 소비하지 않고 또 다른 작업을 하도록 할 때 사용하면 좋습니다.

 


 

ps : 참고로 std::mutex Windows OS에서는 내부적으로는 크리티컬섹션을 사용합니다.

 

클래스 위자드에 보시믄 WM_NCHITTEST라는 메세지가 있습니다.

6.0을 쓰신다면 Class Info 탭에서 Message fiter 라는부분에서 Window로

바꿔주시면 보입니다...

메세지 추가해주시고

 

UINT hit = CDialog::OnNcHitTest(point);

if(hit == HTCLIENT) return HTCAPTION;

else return hit;

 

요 세줄 추가해주시믄 타이틀바 없이도 움직임이 가능합니다.

원하시는 답변이였으면 좋겠네요...^^

 

'프로그래밍 > VC++ 개발 코딩' 카테고리의 다른 글

64bit Bit Shift  (1) 2015.09.14
mutex 사용하기  (0) 2014.10.28
오픈 라이센스 Dia Program 소개  (0) 2014.01.23
CppCheck (정적분석도그) 프로그램 VS 6.0 연동 방법  (0) 2014.01.23
BSD Socket 사용방법  (0) 2014.01.17

Flow Chart 작성에 필요한 프리웨어를 소개합니다. 

일반적으로 많이 사용하는 Visio의 경우 License 비용이 지불되어야 하는 상황입니다. 

MS에서 판매하는 Visio의 경우 1Copy 61만원 가격이 책정되어 있는 상황이라, 팀원 개개인이 제공 받기 힘들듯 싶습니다.

 

그래서 차선책으로 오픈소스 프로젝트로 진행중인 Dia Program 찾아보았습니다.

 

Dia Program

 

 

홈페이지

     http://sourceforge.net/projects/dia-installer/ 

     http://dia-installer.de/index.html.en

 

다운로드

     http://sourceforge.net/projects/dia-installer/files/dia-win32-installer/

 

License

  - GPL(GNU General Public License)

 

기능
  - UML, Flowcharts, Network diagrams, Database models
30여가지의 다이어그램 작성 가능
  - 1
천개 이상의 아이템들을 다양한 용도로 가져다 쓸수 있을 뿐만아니라 비트맵/벡터 이미지를 읽거나 쓸수 있음.

  - Diashapes라는 이름으로 추가 오브젝트들을 배포하고 있고, 사용자 나름의 오브젝트를 추가 가능

  - Dia로 생성한 다이어그램을 기본적인 코드나 DB 설계의 기초 자료로 활용하는 형태로 CASE 도구화 가능.

  - 비트맵 및 벡터 이미지로 내보낼수 있고 Visio XML 파일을 읽을 수 있음.
  - GTK
기반으로 Windows, Mac, Linux에서 모두 사용 가능.


기능 정검 차원에서 간단하게 사용해 본 바로는 Visio 사용법과 유사하여 Visio를 사용하시는 분이라면 쉽게 적응 하실 수 있습니다.

, Flow Chart 작성 이외에 DataBase 설계 , UML 설계 기능 등이 추가되어 있어서 추후 S/W 확장성에도 도움이 될 것으로 생각 됩니다.

'프로그래밍 > VC++ 개발 코딩' 카테고리의 다른 글

mutex 사용하기  (0) 2014.10.28
WM_NCHITTEST 메세지  (0) 2014.04.30
CppCheck (정적분석도그) 프로그램 VS 6.0 연동 방법  (0) 2014.01.23
BSD Socket 사용방법  (0) 2014.01.17
Raw Sockets  (0) 2014.01.17

+ Recent posts