CRuntieClass Reflection

Programming/C,CPP,CS 2016. 8. 17. 14:25 Posted by TanSanC
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

최근에 Open Platform으로 갖춰야 할것 중 하나가 개발 툴인데, 
IDE같은 개발 툴들은 대부분 Import, Plug-in, User Defined Control(ActiveX control) 등과 같이, System이 개발 된 당시에는 존제하지 않았던 class 나 객체들을 자연스럽게 설치, 추가하여 사용할 수 있도록 해주는 부분들이 매우 많은 범위에 존제합니다..
이때 framework  구현부는 실제 class의 실체를 모른 상태에서 runtime시에 binding 되는 class의 객체를 생성해야 할 때가 있다.

class의 인스턴스 생성방법은 다들 알다시피 new를 통해 생성합니다.

BaseClass * pInstance = new SubClass; 

바꾸어 말하면 우리는 반드시 SubClass를 알고 있어야 한다는 것입니다. 그래야만 instance를 생성 할 수 있습니다.

아래와 같이 CameraPlugIn class를 framework에서 모르는 상태라고 한다면 절대 instance를 만들 수 없다는 예기죠.


IPlugIn * pPlugIn = new CameraPlugIn; 



만약 우리가  CameraPlugIn를 모르는 상태 즉,  PlugIn Framework 개발당시에는 CameraPlugIn이라는 class를 모르는 상태에서  camera.dll또는 lib을 download받아서, 이를 link 또는 load 해서 사용할 수 있는 기능을 제공하려 할때,
class를 모르는 상태에서 class 를 runtime시에 동적으로 search 하고 instance를 생성할 수 있도록 하는 기술이 필요하게됩니다.

이러한 기술을 리플렉션( Reflection) 이라한다.

C# 에서도 이와같은 리플렉션은 지원하고 있고, Runtime중에 type binding을 지원하는 Dyanimc 이라는 새로운 타입이 추가될 예정이라고 합니다.

그외  루비, 스몰토크, PHP, 파이썬, 펄 등의 언어에서는 리플렉션 객체를 제공하며, 대부분 유사한 형태를 띄고 있습니다.


아쉽게도 C++ 에서는 공식적으로 지원하지 않는 기능이지만, 전세계의 수많은 똑똑한 개발자 분들이 이런 기능을 다양한 방법으로 제공하고 있습니다.

아마 MFC의 CRuntimeClass는 리플랙션과 비슷한 기능을 위해 만들어진 가벼운 Macro 정도이고 실제 훨씬 편리하고 플랙서블한 그런 library들도 많이 있으니 관심이 있다면 구글링으로 찾아보셔도 좋을 것입니다.


그중 하나의 기술 (?, 그렇죠 말그대로 Programming 테크닉이라 불리울 만한 기술이죠. )MFC에서 Runtime class 라는 것이 있습니다.


저도 나름 이와 비슷한 아이디어를 떠올리면서 구현을 했었는데 , 거의 구현이 완료되고 나서 생각해보니 MFC에 이런게 있었다는 것이 생각이나, Source code를 뒤져봤답니다.

역시나 이미 상용화되어서 아주 ~~ 아주 잘 쓰고 있는 메크로들이라 그런지, 제가 생각했던 개념과 유사한 뼈대위에 많은 살들이 붙어있더군요.
(!! 메크로에 Templete 까지 넣어서 만들었을 줄이야 ㅠ_ㅠ)

회사에서 사용하기 위해 작성한 코드가 좋은 예가 될수 있을텐데, 회사의 자산이라 공개를 할 수 없어서  MFC의 Runtime class의 내용을 살펴보는 것으로 대신 하겠습니다.

저는 사실 한 일주일 쯤 해서  이런 고민에 빠져 있었습니다.

만약 내가 개발 툴을 만들어주고, application 개발자는 자기가 짠 class를 이 개발툴에 plug-in 한 후에 ,
개발 툴에서 재공하는 Generator 를 이용해  Generator("TestClass") 라고 하면 testclass의 instance를 만들어준다고 합시다.
이때 개발툴을 개발할 당시에는 TestClass를 모르고 있기 때문에 일반적인 개발 방법으론, 이를 구현할 수가 없습니다.
즉, Runtime 중에 class를 register하고 이를 parsing하여 instance를 생성 시킬 수 있는 기술이 필요하다.!!

class라는 게 어찌 보면 type인데, 내가 type을 모른 상태에서 object를 생성할 수 있을까?
예를 들면 
Object* pA = CreateInstance("TestClass");
라고하면 pA는 class TestClass 로 생성이되는 이런걸 만들고 싶었습니다.
하지만 흔히 이렇게 사용할 수 있으려면, 기본적으로 TestClass를 CreateInstance 내에서 알고 있어야 합니다. 
그래야 "TestClass" 라는 스트링을 parsing한 다음에 TestClass로 생성을 해줄 수가 있기 때문입니다.
그래서 대부분 이런 코딩을 하겠죠?


Object* CreateInstance(char* pClassName)
{
       :
        if(strcmp(pClassName,"TestClass")==0)
                return (Object*)new TestClass;
}

CreateInstance를 제너럴하게 만들고 싶어서 pClassName 으로 들어오는 class이름이 무엇이든간에 이에 맞는 class를 찾아서 있으면 해당 class의 instance를 생성해주고, 없으면 null 을 return하기를 원한다면? 어떻게 만들까? 음... class들을 관리하는 table과 class name,그리고 class generator을 만들어서 구현 할 수 있을것 입니다.

Object* CreateInstance(char* pClassName)
{
       :
       for(;;)
        if(strcmp(pClassName,gClassTable[i].szName)==0)
                return (Object*) gClassTable[i].Construct();
}

그런데, CreateInstance라는 함수를 만들때는 "TestClass라는 것이 없는데 , 앞으로 누군가가 만들것이다." 라고 한다면? 흠 흠.. 이경우는 난감한가요? 분명 이렇게 되어야 합니다. gClassTable 에 RegisterClass라는 API를 만들어서 이름과 생성자를 등록하여 사용할 수 있도록 해야합니다.

void RegisterClass(char* classname, Object *(*fpConstruct)())
{
      :
    gClassTable[i].szName = classname;
    gClassTable[i].Construct= fpConstruct;
}

가 있어야 되겠죠. 헌데 이렇게 되면 상당히 귀찮아지는 것이 fpConstruct를 만드는 일이 됩니다. 이럴때 나온 개념이 runtimeclass라는 넘이 됩니다. MFC의 CRuntimeClass를 살펴보면, 클레스 전체를 살펴보면 좋겠지만.. 대충 필요한 것들.. 핵심이 될만한 것들만 언급하자면,

struct CRuntimeClass
{
// Attributes
1) LPCSTR m_lpszClassName;
2) CRuntimeClass* m_pBaseClass;
3) CObject* CreateObject();
4) static CObject* PASCAL CreateObject(LPCWSTR lpszClassName);
5) CRuntimeClass* m_pNextClass;       // linked list of registered classes
}

아마 가장 핵심이 되는 것이 위의 1)~4) 까지의 내용일 겁니다. 왜냐? 다음 RuntimeClass를 만드는 메크로들을 보면 알 수 있습니다.

#define RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))
#define DECLARE_DYNAMIC(class_name) \
public: \
 static const CRuntimeClass class##class_name; \
 virtual CRuntimeClass* GetRuntimeClass() const; \

#define _DECLARE_DYNAMIC(class_name) \
public: \
 static CRuntimeClass class##class_name; \
 virtual CRuntimeClass* GetRuntimeClass() const; \

#define IMPLEMENT_RUNTIMECLASS(class_name) \
 const CRuntimeClass class_name::class##class_name = { \
  #class_name, sizeof(class class_name), \
   }; \  
 CRuntimeClass* class_name::GetRuntimeClass() const \
  { return RUNTIME_CLASS(class_name); } \

이런 메크로들이 있습니다. 약간 길죠?. IMPLEMENT_RUNTIMECLASS 는 설명하기 귀찮은 것들은 다 뺐습니다. 이렇게 메크로만 보면 "뭐하자는 거지?" 라고 의문이 드는 것들이 실제 사용하는 예를 보면 "아하!!" 라고 하게 됩니다.

in MyTestControl.hpp--------------- 
class MyTestControl
{
   _DECLARE_DYNAMIC(MyTestControl)   //<-- static const Runtimeclass  classMyTestControl 가
                                                            // MyTestControl class안에 정의된다.

   :
   :

};
in MyTestControl.cpp--------------- 
파일 맨 위에
IMPLEMENT_RUNTIMECLASS(class_name) // static 객체인 MyTestControl::classMyTestControl 를 초기화 한다.

in MyTestApp.cpp

void main(void)
{
   AfxInitClass(RUNTIME_CLASS(MyTestControl));
   
   CRuntimeClass::CreateObject("MyTestControl");
  
}

대충의 설명을 하자면 ,
1. Runtime class로 선언하고자 하는 class 내부에 DECLARE_DYNAMIC(classname) 을 해주고나면, static runtime class 하나가 생기는데 "class"+classname 의 형태로 된다.
2. 이 "classMyTestControl"라고 새로 만들어진 static runtimeclass 는 멤버함수인 3).의 CreateObject() 를 MyTestControl를 생성할 수 있는 함수로 만든다.
3. 그 형식은 아래와 같다.

CreateObject() 
{
  return new MyTestControl;
}

따라서 우리는 메크로에 의해 생성된 classMyTestControl 이라는 runtime class를 이용해서 MyTestControl이라는 class의 instance를 생성할 수 있게 됩니다.


 마지막으로 한가지 설명 안하고 넘어간 것이 있는데.

5) CRuntimeClass* m_pNextClass;       // linked list of registered classes

이 녀석에 대한 내용이다. 이게 왜 있는가? 제가 개발할때, 위와 같은 구현을 완료하고 나서 Register 단계( MFC에서는 AfxInitClass 단계일듯하다.)에서 결국 table을 만들고, table과 Runtime class를 묶는 작업을 하고, search하는 함수를 만들고... 등등을 작업했었다.

CSystemClassFactroy
{
 list runtimeClass;
 RegisterClass(CRuntimeCalss);
};

application에서 사용할때는 아래와 같이 register를 해야 되는 상황이 있었습니다.

main()
{
   // application 초기화
   Factroy.RegisterClass(MyTestControl);
    :
    :

}

이때 문득 MFC에서는 어떻게 하지? 라는 생각이 들어 이 RuntimeClass를 살펴본바... m_pNextClass 를 이용해서 각 register시에 RuntimeClass들을 줄줄이 사탕으로 엮어놓은 것이라 추측 할수 있었다.!!! 아하.!! 요렇게 하면 runtime class를 managing 하는 manager class가 필요 없겠구나.!! 하는 필(feel)을 받고, 제 코드도 요렇게 바꿨답니다. ㅎㅎ 



찾아보기 키워드!!! 

[SEAL Reflex] 
[LibReflection] 

[XCppRefl 라이브러리]

 
<참고 링크>
[MSDN : C++ 리플렉션 in Visual C++ ]http://msdn.microsoft.com/ko-kr/library/y0114hz2(VS.90).aspx


336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

MFC Grid control 2.27 ReadOnly, CheckBox Button





// Make cell row,col read-only

m_Grid.SetItemState(row, col, m_Grid.GetItemState(row, col) | GVIS_READONLY);





// Make cell row,col CheckBox Button

m_Grid.SetCellType(row, col, RUNTIME_CLASS(CGridCellCheck));











http://www.codeproject.com/Articles/8/MFC-Grid-control-2-27

How to Use MFC Grid control 2.27

Programming/MFCGridCtrl 2016. 8. 12. 16:13 Posted by TanSanC
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

How to Use MFC Grid control 2.27


http://www.codeproject.com/Articles/8/MFC-Grid-control-2-27

1. Download


MFC Grid control 2.27

6 May 2010 CPOL
A fully featured MFC grid control for displaying tabular data. The grid is a custom control derived from CWnd





2. Essential Include Files



Files

To use the Grid control in your project you will need to add a number of files to your project:

gridctrl.cpp, gridctrl.hMain grid control source and header files.
gridcellbase.cpp, gridcellbase.hMain grid cell base class.
gridcell.cpp, gridcell.hMain grid cell default class implementation.
CellRange.hDefinition of CCellID and CCellRange helper classes.
MemDC.hKeith Rule's memory DC helper class.
InPlaceEdit.cpp, InPlaceEdit.hIn-place edit windows source and header files.
GridDropTarget.cpp, GridDropTarget.hGrid control OLE drag and drop target. Only necessary if you don't define GRIDCONTROL_NO_DRAGDROP in gridctrl.h
Titletip.cpp, Titletip.h

Titletips for cells, from Zafir Anjum. Only necessary if you don't define GRIDCONTROL_NO_TITLETIPS in gridctrl.h



3. Essential Include Files Add to Project 







4. Custom Control Add to Dialog




ID : IDC_GRID


Class : MFCGridCtrl (No CGridCtrl)


if you use CGridCtrl, you can see this error








5. Make Member Variable m_Grid



Dlg.h


- Include


#include "GridCtrl.h"


Make Member Variable m_Grid


CGridCtrl m_Grid;




Dlg.cpp


- Include


#include "GridCtrl.h"





6. IDC_GRID Connect with Member Variable




DDX_GridControl(pDX, IDC_GRID, m_Grid);


DDX_GridControl Function defined in GridCtrl.h









336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

error C4996: 'xxx': deprecated로 선언되었습니다.



deprecated란

기존의 함수나 클래스가 필요없어져서 삭제하려고 할 때 이미 많은 곳에서 사용 중이라서 바로 삭제하기 까다로운 경우가 있다. 이런 경우 바로 삭제하지 않고 삭제할 함수나 클래스를 사용하지 않도록 유도한 후 사용하는 곳이 없어지는 시점이 왔을 때 삭제하는 방식을 사용할 수 있다. 이 때 사용할 수 있는 기능이 deprecated 기능이다.


    //함수
    __declspec(deprecated) void DeplacatedFunction()
    {
    }

    //구조체
    struct __declspec(deprecated) DeplacatedStruct
    {
    };

    //클래스
    class __declspec(deprecated) DeplacatedClass
    {
    };

     



    이렇게 설정하면 컴파일시 deprecated로 설정된 것이 사용된 곳에서 각각 다음과 같은 메시지가 출력된다.

    warning C4996: ‘DeplacatedFunction’: deprecated로 선언되었습니다.
    ‘DeplacatedFunction’ 선언을 참조하십시오.

    warning C4996: ‘DeplacatedStruct’: deprecated로 선언되었습니다.
    ‘DeplacatedStruct’ 선언을 참조하십시오.

    warning C4996: ‘DeplacatedClass’: deprecated로 선언되었습니다.
    ‘DeplacatedClass’ 선언을 참조하십시오.



    그러나 의도적으로 Deplacated 로 설정된것을 사용하고자 한다면



    #define _CRT_SECURE_NO_DEPRECATE


    #pragma warning(disable:4996)


    둘 중의 하나를 선언하면 된다.





    deprecated (C++)

    Visual Studio 2005

    (Microsoft specific) With the exceptions noted below, the deprecated declaration offers the same functionality as the deprecatedpragma:

    • The deprecated declaration lets you specify particular forms of function overloads as deprecated, whereas the pragma form applies to all overloaded forms of a function name.

    • The deprecated declaration lets you specify a message that will display at compile time. The text of the message can be from a macro.

    • Macros can only be marked as deprecated with the deprecated pragma.

    If the compiler encounters the use of a deprecated identifier, a C4996 warning is thrown.

    Example

    The following sample shows how to mark functions as deprecated, and how to specify a message that will be displayed at compile time, when the deprecated function is used.

    // deprecated.cpp
    // compile with: /W1
    #define MY_TEXT "function is deprecated"
    void func1(void) {}
    __declspec(deprecated) void func1(int) {}
    __declspec(deprecated("** this is a deprecated function **")) void func2(int) {}
    __declspec(deprecated(MY_TEXT)) void func3(int) {}
    
    int main() {
       func1();
       func1(1);   // C4996
       func2(1);   // C4996
       func3(1);   // C4996
    }
    

    The following sample shows how to mark classes as deprecated, and how to specify a message that will be displayed at compile time, when the deprecated class is used.

    // deprecate_class.cpp
    // compile with: /W1
    struct __declspec(deprecated) X {
       void f(){}
    };
    
    struct __declspec(deprecated("** X2 is deprecated **")) X2 {
       void f(){}
    };
    
    int main() {
       X x;   // C4996
       X2 x2;   // C4996
    }


    336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

    MFC Dialog 에 OnInitDialog 추가하기





    CDialog::OnInitDialog

    이 메서드를 호출 하에서 여 WM_INITDIALOG 메시지.

    virtual BOOL OnInitDialog( );
    

    Windows를 보냅니다는 WM_INITDIALOG 중 대화 상자에 메시지를 만들기CreateIndirect, 또는 DoModal 대화 상자를 바로 표시 되기 전에 발생 하는 호출을.

    대화 상자 초기화 될 때 특수 처리를 수행 하려는 경우이 메서드를 재정의 합니다. 재정의 된 버전에서 먼저 기본 클래스를 호출OnInitDialog 하지만 반환 값을 무시 합니다. 일반적으로 반환 합니다 TRUE 에서 메서드를 재정의 합니다.

    Windows 호출을 OnInitDialog 일반 표준 글로벌 대화 상자 프로시저 모든 Mfc 라이브러리 대화 상자를 사용 하 여 함수. 사용자 메시지 맵을 통해이 함수를 호출 하 고이 메서드에 대 한 메시지 맵 엔트리는 필요 하지 않습니다 따라서.



    Dialog 의 리소스뷰에서 OnInitDialog 를 추가 하려고 하면


    메시지와 컨트롤 이벤트에서는 보이지 않는다.



    불가능 한것이 아니고 다른 위치에서 하여야한다.




    클래스 뷰에서


    해당 다이얼로그의 클래스 함수를 선택 후


    속성창을 보면


    [재정의] 버튼이 있다.




    재정의 화면 안에


    OnInitDialog 가 존재한다.





    336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

    How to prevent MFC dialog closing on Enter and Escape keys?


    There is an alternative to the previous answer, which is useful if you wish to still have an OK / Close button. If you override the PreTranslateMessage function, you can catch the use of VK_ESCAPE / VK_RETURN like so:



    BOOL CMainDialog::PreTranslateMessage(MSG* pMsg)

    {


    if (pMsg->message == WM_KEYDOWN)

    {

    if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)

    {

    return TRUE;                // Do not process further

    }

    }


    return CDialogEx::PreTranslateMessage(pMsg);

    }




    이렇게 수정하여야 한다.




    PreTranslateMessage 함수를 생성하는 방법은


    1. Enter, ESC 키를 차단할 DialogClass 를 우클릭


    2. [클래스 마법사] 를 켠다.


    3. [가상 함수]


    4. 가상 함수 탭에서 PreTranslateMessage 를 선택


    5. [함수 추가]


    6. 추가된 함수에


    if (pMsg->message == WM_KEYDOWN)

    {

    if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)

    {

    return TRUE;                // Do not process further

    }

    }


    추가 작성




    336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

    C# Class Library


    VS2013


    새 프로젝트 -> Visual C# -> 클래스 라이브러리 -> 프로젝트 이름(Library 이름이 된다, 예제에서는 ClassLibrary2 이다.) -> 


    자동으로 Class1.cs 파일이 만들어진다.


    이 Class1.cs 가 DLL 에서 불러쓸 객체의 이름이 된다.



    참고 : https://support.microsoft.com/en-us/kb/828736




    Class1.cs 를 우클릭하여 이름바꾸기 원하는 객체 이름으로 바꾼다.




    예제에서는 SimpleCalc 로 진행한다.



    ----------------------------------------------------------------


    SimpleCalc.cs


    ----------------------------------------------------------------


    namespace ClassLibrary2

    {

        public class SimpleCalc

        {

        }

    }


    ----------------------------------------------------------------



    interface 를 추가 구현한다.

    // Interface declaration.
    public interface ICalculator
    {
        int Add(int Number1, int Number2);
    };



    ----------------------------------------------------------------


    SimpleCalc.cs


    ----------------------------------------------------------------


    namespace ClassLibrary2

    {

        // Interface declaration.

        public interface ICalculator

        {

            int Add(int Number1, int Number2);

        };

        public class SimpleCalc

        {

        }

    }



    ----------------------------------------------------------------


    interface를 상속 받고

    interface 로 부터 상속받은 메서드를 구현한다.


    // Interface implementation.
    public class ManagedClass:ICalculator
    {
        public int Add(int Number1,int Number2)
            {
                return Number1+Number2;
            }
    }




    ----------------------------------------------------------------


    SimpleCalc.cs


    ----------------------------------------------------------------


    namespace ClassLibrary2

    {

        // Interface declaration.

        public interface ICalculator

        {

            int Add(int Number1, int Number2);

        };

        public class SimpleCalc : ICalculator

        {

            public int Add(int Number1, int Number2)

            {

                return Number1 + Number2;

            }

        }

    }




    ----------------------------------------------------------------


    이제


    Properties 를 열어서


    AssemblyInfo.cs 를 열어보면


    [assembly: ComVisible(false)] 를 찾아서



    [assembly: ComVisible(true)]


    로 변경한다.



    [assembly: ComVisible(true)] 로 바꾸어야 ActiveX 로 사용이 가능하다.





    이제 빌드하면


    bin/Debug 폴더에


    ClassLibrary2.dll 파일이 만들어진다.



    궁극적으로 배포를 목적으로 하므로


    Release 모드로 바꾸어준다.




    빌드를 하게 되면


    ClassLibrary2.dll 파일이 만들어진다.



    하지만 클래스 내부의 구조가 보이게 하려면


    tlb 파일이 필요하다


    이 파일은


    ClassLibrary2 프로젝트이름을 더블클릭하면 뜨는 속성 창에서


    [빌드]


    COM Interop 등록 을 체크해준다.


    그러면 이제부터 빌드를 하면 tlb 파일도 같이 만들어진다.





    tlb 파일과 dll 파일을 C# DLL 을 사용할 프로젝트의 폴더로 복사한다.




    예제에서는 MFC 에서 해당 DLL 파일을 불러서 사용해보겠다.



    사용할 cpp 파일에서



    #import "ClassLibrary2.tlb" raw_interfaces_only

    using namespace ClassLibrary2;


    를 선언한다.





    그 후 사용을 원하는 함수에서




    HRESULT hr = CoInitialize(NULL);


    // Create the interface pointer.

    ICalculatorPtr pICalc(__uuidof(SimpleCalc));


    long lResult = 0;


    // Call the Add method.

    pICalc->Add(5, 10, &lResult);


    SetDlgItemInt(IDC_STERM, (int)lResult);


    // Uninitialize COM.

    CoUninitialize();





    이렇게 사용을 하면 된다.



    ICalculatorPtr 은 Interface 로 만든  ICalculator 의 스마트포인터이다


    ICalculator* 와 같다.





    pICalc-> 을 통해 내부에 있는 속성과 메서드에 접근이 가능하다.








    MFC 프로젝트에서 ATL 연동하기

    Programming/COM,ATL 2016. 3. 29. 11:44 Posted by TanSanC
    336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

    MFC 프로젝트에서 ATL 연동하기


    작업 환경 : VS2013


    일반 MFC 프로젝트를 만듭니다.




    2. 대화 상자 기반



    ActiveX 컨트롤 체크 확인



    만들어진 다이얼로그에서 ActiveX 컨트롤 추가



    추가하면 하얀 네모가 다이얼로그에 추가된다.



    ActiveX 컨트롤을 클릭한다음 우클릭하여 속성이 뜨고 번개모양 아이콘을 누르면 연결된 이벤트들이 확인된다.



    ATL 의 Property 와 Method 는 ActiveX 컨트롤 멤버변수 추가하여서 사용이 가능하다.



    예제로는 Ctrl 이라는 멤버 변수를 추가하였다.

    다음과 같이 h, cpp 파일이 만들어진다.



    내부에는 ATL 에서 구현한 Property 와 Method 가 보인다.



    ActiveX 컨트롤에서 이벤트 처리 함수를 추가하였다.



    이제 Ctrl 의 Property 와 Method 를 불러올 수 있다.



    336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

    ATL 프로젝트로 만든 DLL 을 MFC 프로젝트에서 사용하기



    ATL 프로젝트로 만든 DLL 이름을 ComServer.DLL 이라고 가정하겠습니다.


    ComServer 대신에 자신이 만든 DLL 을 쓰면 됩니다.



    사용하고자하는 ComServer.dll 파일을 프로젝트 디렉토리에 복사한다.


    stdafx.h 파일에 


    #import "ComServer.dll" no_namespace named_guids


    넣고


    빌드를 하게 되면


    빌드 폴더에 ComServer.tlh , ComServer.tli 가 생성된것을 확인 할 수 있습니다.



    ComServer.tlh 파일을 열어 둡니다.




    그다음 Dlg 의 OnInitDialog() 같은 곳에 아래의 코드를 삽입한다.


    ComTest 는 객체 이름입니다.


    try{


    UpdateData();


    HRESULT rc;


    IComTestPtr pComTest; //IComTest *pComTest 도 가능 !!! (IComTest 의 스마트포인터)


    rc = CoCreateInstance(CLSID_ComTest, NULL, CLSCTX_INPROC_SERVER, DIID_IComTest, (void**)&pComTest);


    if (FAILED(rc)){


    MessageBox("Failure in call to CoCreateInstance");


    return;


    }


    pComTest->(사용하고 싶은 속성이나 메서드);


    }


    catch (_com_error &e){


    CString strBuffer;


    strBuffer.Format("Code = %08lXnCode meaning = %snSource = %snDescription = %sn",

    e.Error(), e.ErrorMessage(), e.Source(), e.Description());

    AfxMessageBox(strBuffer);

    }






    'Programming > COM,ATL' 카테고리의 다른 글

    MFC 프로젝트에서 ATL 연동하기  (2) 2016.03.29
    ATL/COM 강좌  (0) 2016.03.25
    ATL 프로젝트에서 hWnd사용하기 #2  (0) 2016.03.25
    ATL 프로젝트에서 hWnd사용하기  (0) 2016.03.25
    ocx, dll 라이브러리 등록  (0) 2016.03.15

    MFC 시리얼 통신 클래스

    Programming/C,CPP,CS 2014. 3. 8. 15:39 Posted by TanSanC
    336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

    컴퓨터에서 시리얼 통신을 하려면 보통 터미널 프로그램을 사용하게 됩니다.

    하지만 이 경우 용도가 매우 제한 되고 활용도가 떨어지죠.

    이 시점에서 보통 Visual C++ MFC나 Visual Basic 쪽으로 눈을 돌려보게 되는데, 많은 DLL 파일들이나 프레임워크를 동반해야 되는 VB 프로젝트는 왠지 맘에 안들더군요. 

    시리얼 통신 클래스는 하나 포스트해 두려고 합니다.

    이 클래스는 몇년전에 인터넷 어디에서 구한 소스인데 프로젝트의 중요한 부분을 손데거나 클래스 내부에서 사용되는 변수들이 프로젝트 밖에 선언되어있는 경우가 있어서 나름 제 방식데로 수정한 버전입니다.

    현재 컴퓨터에 연결된 컴포트를 검색해 주는 함수도 하나 추가했구요. 출처가 기억이 안나서 출처를 쓸 수가 없네요;; 


    첨부된 Readme.txt 파일을 참고해서 사용하시면 되겠습니다. 

    위 파일은 이 클래스를 이용해 만들어 본 시리얼 통신 체팅 입니다. 컴두대를 이용해서 확인해보셔도 되고, 루프백 이용해서 확인해 보셔도 됩니다. 
    Visual Studio 2010 Pro 에서 컴파일 되었습니다.




    출처 : http://magicom9.tistory.com/54


    'Programming > C,CPP,CS' 카테고리의 다른 글

    아두이노와 연계한 CPP 시리얼 통신 응용  (0) 2014.03.08
    CString Convert 변환  (0) 2014.03.08
    아두이노 & CPP 시리얼 통신 연동  (0) 2014.03.02
    아두이노 기본 세팅  (0) 2014.03.02
    CPP 연산자 오버로딩  (0) 2014.01.16