대부분 모달(Modal)은 스택으로 생성을 합니다.
그리고 모달리스(Modeless)는 힙을 사용해서 동적으로 사용을 많이 합니다.
이럴때 모달리스 다이알로그를 종료시키고 다시 실행시켜도 안나타날때가 있습니다.
이건 대부분 힙으로 할당한 모달리스 다이알로그를 해제 안해줘서 그렇습니다.
모달리스 다이알로그의 CWnd::PostNcDestroy()의 가상함수를 만들어서 그 안에서
메모리를 해제 시켜 주면 됩니다.
PostNcDestory() 함수는 윈도우가 소멸된 후 OnNcDestroy함수에 의하여 불려지는 함수입니다.

ps. 모달리스 다이알로그 종료시 메모리 해제 방법은 아래와 같이 해주시면 됩니다.

void CXXXXXXDlg::OnClose() 
{ 
        // TODO: Add your message handler code here and/or call default 
        DestroyWindow(); 
       //CDialog::OnClose(); 
} 

posted by 뚱2
warning C4013: 'XXXXX' undefined; assuming extern returning int
요로코롬 생긴 warning이 뜰때가 있습니다. 뭐 컴파일 제대로 되고 실행시켜도 제대로 됩니다.
그렇지만 warning!! 이게 찝찝하죠... ^^;

우선 warning은 외부 어딘가에 선언은 되어 있는데 선언을 안하고 사용해서 그렇습니다.
그래서 선언이 없어니까 컴파일러가 알아서 대~~~충 int return 한다고 가정하는
것입니다.

대부분의 경우는 선언된 .h파일이 인클루드 되어 있는지 확인해 보면은 인클루드가 안되있는
경우입니다.
posted by 뚱2

저는 MFC에서 폼베이스로 작업할때 주로 리소스 창에서 컨트롤 대충 그려넣고
서브클래싱할 클래스 하나씩 만들어주고
컨트롤 클래스의 SubClassDlgItem() 함수를 이용해서 서브클래싱합니다.
오늘 아주 간단한 리스트컨트롤을 클릭하면 세부내용을 다른 에디트 컨트롤에
뿌려주는 부분을 작성했습니다.
서브클래싱한 컨트롤의 OnClick을 잡고서 아래와 같이 코딩했습니다.

void CSMSList::OnClick(NMHDR* pNMHDR, LRESULT* pResult) 
{
    // TODO: Add your control notification handler code here
    NM_LISTVIEW *pList = (NM_LISTVIEW*)pNMHDR;
    int nIndex = pList->iItem;
    *pResult = 0;
}


분명히 리스트에서 클릭한 아이템의 인덱스를 가져와야 하는데 이상하게 자꾸 -1로
나오더군요.. ㅠㅠ

그러다 알아냈습니다.
네~~~ 맞습니다. 결국 또 저에 실수 입니다.

서브클래싱한 컨트롤의 PreSubclassWindow() 에서 아래와 같이 코딩해주니 바로 해결
됬습니다.

void CSMSList::PreSubclassWindow() 
{
    // TODO: Add your specialized code here and/or call the base class
    SetExtendedStyle(LVS_EX_FULLROWSELECT);
    CListCtrl::PreSubclassWindow();
}



PreSubclassWindow() 함수는 SubClassDlgItem()으로 서브클래싱 했을때 초기화 해주는
멤버 함수입니다.
SetExtendedStyle() 함수는 확장 스타일 함수로 LVS_EX_FULLROWSELECT를 인자로
클릭시 리스트 한줄전체(Row)가 선택되어 집니다.

위와 같이 코딩했더니 OnClick함수에서 제대로 인텍스를 얻어왔습니다.
아~!! 오늘도 하나 실수했고 한가지 배웠습니다.

posted by 뚱2

윈도우의 일반적인 컨트롤은 기능에 중점을 준것이기 때문에
모양새가 별로이다.
그럴때 색상을 변경할때 많이 사용하는게 WM_CTRCOLOR 이다.
static, Edit의 배경색을 바꿀때 요긴하다.

WM_CTLCOLOR 메세지는 컨트롤의 부모가 받는다.

조건 : 바꾸고자 하는 Edit의 ID --> IDC_EDIT_USERID
         컨트롤의 부모는           --> CDemoDlg

1. 부모인 CDemoDlg의 WM_CTLCOLOR을 등록한다.
2. 메세지 핸들러를 클래스 위져드로 등록하면 컨트롤의 부모는

HBRUSH CDemoDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
 
    // TODO: Change any attributes of the DC here
    // 새로 작성한 부분
    if ( pWnd->GetDlgCtrlID() == IDC_EDIT_USERID )
    {
        pDC->SetBkColor( RGB(249, 225, 155) );
        pDC->SetBkMode( OPAQUE );

        return m_brText;
    }
    // TODO: Return a different brush if the default is not desired
    return hbr;
}


특이한것은 변경하고자 하는 컨트롤의 리턴 HBRUSH는 hbr과 다른 것을
리턴해야 한다.
그렇지 않고 그냥 return hbr 을 리턴하면 색상이 변경되지 않는다.

ps. m_brText는 CBrush로 생성자에서 m_brText.CreateSolidBrush( RGB(249, 225, 155) )로
     생성해줬습니다.

posted by 뚱2
보통 메뉴는 CMainFrame에 있습니다.
그래서 클래스 위져드에서 UPDATE_COMMAND_UI를 이용해서
만들어 주면은 아래와 같은 모양의 함수가 생성됩니다.

OnUpdateXXXXXXXX(CCmdUI* pCmdUI) { }

보통 위 합수에서
OnUpdateXXXXXXXX(CCmdUI* pCmdUI) { pCmdUI->Enable( TRUE ); // 활성화 pCmdUI->Enable( FALSE ); // 비활성화 }

해주면 메뉴의 항목이 활성/비활성 되는데

제가 이번에 만든건 특수하게 CTreeCtrl을 상속받아서 만든 객체에서 팝업메뉴를
만들었더니 'pCmdUI->Enable( FALSE );'를 아무리 해도 안되더라구요
CMenu::EnableMenuItem  함수를 사용해서 활성/비활성을 해줬습니다.
함수의 자세한 사용법은 아래에 ^^;

ps. EnableMenuItem() 함수는 TrackPopupMenu() 함수 전에 호출해 줘야 합니다.

CMenu::EnableMenuItem

UINT EnableMenuItem( UINT nIDEnableItem, UINT nEnable );

Return Value

Previous state (MF_DISABLED, MF_ENABLED, or MF_GRAYED) or –1 if not valid.

Parameters

nIDEnableItem

Specifies the menu item to be enabled, as determined by nEnable. This parameter can specify pop-up menu items as well as standard menu items.

nEnable

Specifies the action to take. It can be a combination of MF_DISABLED, MF_ENABLED, or MF_GRAYED, with MF_BYCOMMAND or MF_BYPOSITION. These values can be combined by using the bitwise OR operator. These values have the following meanings:

  • MF_BYCOMMAND   Specifies that the parameter gives the command ID of the existing menu item. This is the default.

  • MF_BYPOSITION   Specifies that the parameter gives the position of the existing menu item. The first item is at position 0.

  • MF_DISABLED   Disables the menu item so that it cannot be selected but does not dim it.

  • MF_ENABLED   Enables the menu item so that it can be selected and restores it from its dimmed state.

  • MF_GRAYED   Disables the menu item so that it cannot be selected and dims it.

Remarks

Enables, disables, or dims a menu item. The CreateMenu, InsertMenu, ModifyMenu, and LoadMenuIndirect member functions can also set the state (enabled, disabled, or dimmed) of a menu item.

Using the MF_BYPOSITION value requires an application to use the correct CMenu. If the CMenu of the menu bar is used, a top-level menu item (an item in the menu bar) is affected. To set the state of an item in a pop-up or nested pop-up menu by position, an application must specify the CMenu of the pop-up menu.

When an application specifies the MF_BYCOMMAND flag, Windows checks all pop-up menu items that are subordinate to the CMenu; therefore, unless duplicate menu items are present, using the CMenu of the menu bar is sufficient.


posted by 뚱2

이번에 프로그램 개발하면서 2주동안 삽질 한 것 입니다. ㅡㅡ;
분명히 Dialog 에서는 잘 되는 TVN_BEGINDRAG 메세지가
FormView에서만 하면 메세지가 먹통이 되는 것입니다.
그리고 컨트롤의 SubclassDlgItem 함수도 안되구요.....
그래서 엄청 삽질 하다가 제가 결정적 실수 한걸 알았습니다.

Dialog에서는 대부분 OnInitDialog에서 컨트롤을 초기화 해줍니다.
그런데 FormView에서는 OnInitDialog가 없어서 전 OnCreate에서 작업해 줬습니다.
이게 문제였던 것입니다.
아직 FormView의 모든것이 생성되기도 전에 안에서 자식 컨트롤들의 작업을 했던게
문제가 발생한 원인이었습니다. (네 ~~~~ 저 초보 맞습니다. ㅠㅠ)

결론으로 해결책은 FormView에서는 OnInitUpdate라는 함수가 있습니다.
여기에서 각각의 컨트롤 들을 초기화 해주면 Dialog와 같이 사용 하실수 있습니다.

ps. SubclassDlgItem을 이용해서 서브클래싱을 하면 서브클래싱한 컨트롤 클래스는
     PreSubclassWindow 에서 초기화 작업을 해주셔야 합니다.
posted by 뚱2

1. SS_NOTIFY (Static의 인자)
   : 서브 클래싱한 컨트롤 클래스에 SS_NOTIFY를 지정하면 해당 컨트롤이 메세지를 받을수
   있습니다.
   SS_NOTIFY를 추가하는 방법은 Resource View에서 컨트롤 속성 --> Style --> Notify를
   체크해도 되고
   PreSubclassWindow() 함수를 오버라이드 해서
   ::SetWindowLong()함수를 사용해서 설정을 변경해 주어도 됩니다.

2. Reflection Message
  : 대부분의 컨트롤은 컨트롤의 배경이나 색상을 부모 윈도우가 변경할 수 있도록 통지 메세지를
    부모윈도우에게 보낸다.
    그런데 MFC4.0부터 이러한 통지 메세지를 부모 윈도우뿐만 아니라 컨트롤 자체에서 처리 할
    수 있도록 추가된 기능이다.
    클래스 위져드를 띄워보면 =WS_XXXX 란 메세지가 Reflection Message 이다.


참고자료 : MFC 정복

posted by 뚱2
이번 회사 프로젝트 진행중 스레드 안에서 컨트롤을 생성해야 하는 일이 생겼는데
해결도 못하는 시스템 오류가 ㄷㄷㄷ....

결국 사용자 정의 메세지를 사용하기로 했습니다.

1. 메세지를 정의한다
:
 윈도우 자체적으로 WM_USER 라는 사용자가 정의해서 사용 할 수 있는 메세지가 있습니다.
 WM_USER+1, WM_USER+2 이렇게 사용합니다.
 그렇지만 좀더 멋드러지게 사용하고 싶다면...
#define WM_MY_MESSAGE     WM_USER+1

  
이렇게 정의해서 사용하시면 좀더 폼납니다. ^^;
메세지는 보통 따로 헤더파일을 연결해서 사용하기도 하고
전역적으로 사용하고 싶으면 StdAfx.h에 선언합니다.

2. 실제 사용할 윈도우 객체의 메세지 멤버함수를 정의합니다.
:

 
 //{{AFX_MSG(CThreadDlg)
 // Generated message map functions
virtual BOOL OnInitDialog();
 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
 afx_msg void OnPaint();
 afx_msg HCURSOR OnQueryDragIcon();
 afx_msg void OnDestroy();
 afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
 afx_msg void OnClose();
 //}}AFX_MSG
afx_msg LONG OnMyMessage(UINT wParam, LONG lParam);
 DECLARE_MESSAGE_MAP()

위에 보시면 헤당 .h 파일의 클래스 안에 선언해 줍니다.
//{{AFX_MSG(CThreadDlg)
...
//}}AFX_MSG
위 안에는 선언하지 마세요 주석으로 보이지만 이건 클래스 위져드가 사용하는
코드입니다. 여기 잘 못 선언해 주시면 클래스 위져드가 알아져 지우거나 위져드 상에서
다른 코드들이 안보이는 불상사가 발생합니다.
그래서 저 같은 경우는
//}}AFX_MSG 여기 다음줄에 선언해 줍니다.
그리고 .cpp 파일에 위에서 선언한 사용자 정의 함수를 정의해 줍니다.

3. .cpp 파일의 메세지 맵에서 연결해 줍니다.

BEGIN_MESSAGE_MAP(CThreadDlg, CDialog)
 //{{AFX_MSG_MAP(CThreadDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_WM_DESTROY()
 ON_WM_LBUTTONDOWN()
 ON_WM_CLOSE()
 //}}AFX_MSG_MAP
 ON_MESSAGE(WM_CREATEVS, OnCreateVS)
END_MESSAGE_MAP()

보시면 알겠지만 2번과 같이 여기도  //}}AFX_MSG_MAP 다음에 선언해주세요

4. 실제 사용은 SendMessage() 함수나, PostMessage() 함수를 이용해서 해주시면 됩니다.



  
posted by 뚱2

이번에 프로젝트를 하면서 전역객체를 사용할 일이 생겼었습니다.
전역객체로 진행하던중 이왕이면 디자인패턴을 사용해보자!!!
그래서 싱글턴을 이용해 보려고 합니다.

* Singleton Patterns ::
   해당 클래스의 인스턴스가 한개만 생성해서 그 인스턴스를 전역객체 처럼 어디서든지
   사용 할 수 있게 하는 디자인패턴입니다.

// Singleton.h
class CSingleton
{
private:
    static CSingleton * m_pUniqueInst;
    CSingleton();

public:
    ~CSingleton();
    static CSingleton & GetInstance();
};

// Singleton.cpp
#include "Singleton.h"

// static 초기화
CSingleton* CSingleton::m_pUniqueInst = NULL;

CSingleton::CSingleton()
{
}
CSingleton::~CSingleton()
{
    if (m_pUniqueInst)
        delete m_pUniqueInst;
}
CSingleton & CSingleton::GetInstance()
{
    if (m_pUniqueInst == NULL)
        m_pUniqueInst = new CSingleton;

    return *m_pUniqueInst;
}



간단하게 만들어본 싱클턴입니다.
GetInstance() 멤버 함수가 static으로 선언되어 있기 때문에 아무곳에서나
호출 가능합니다. 그리고 생성자가 private로 선언되어 있기때문에 CSingleton의
인스턴스를 만들려고 하면은 컴파일 에러가 발생합니다.


ps. 위 싱글턴은 싱글스레드 용입니다. 멀티스레드에서는 문제가 생길수 있습니다.

posted by 뚱2

이번에 개발하는 프로그램에서 Log 파일을 기록하려고 CLogFile이라는 클래스를 하나
만들었습니다.
그런데 이 클래스는 스레드문제로 인해서 제가 생성자에서 InitializeCriticalSection(&m_csKey)
소멸자에서 DeleteCriticalSection(&m_csKey)을 호출 합니다.
그리고 생성자에서 여러가지 작업을 해야 합니다.
그러니까 생성자 소멸자는 전역적으로 한번만 호출하고 실제 로그 파일을 기록하는 멤버 함수
SetLog() 함수만 필요한 곳에서 호출 하는 방법 입니다.
그렇게 위해서는 결국 전역 적으로 클래스의 인스턴스를 생성해야 했습니다.

그래서 결국 쓴 방법이

StdAfx.h 에서
extern CLogFile g_LogFile;
이라고 선언해 줬습니다.

그리고
StdAfx.cpp에서
CLogFile g_LogFile
이렇게 정의 해주고

필요한 곳의 파일마다 StdAfx.h을 인클루드 해서 사용하는 방법으로 해결봤습니다.
우선 테스트 하기로는 잘 되네요

ps. 조금 불편하더라도 StdAfx.h StdAfx.cpp에서 작성하는게 찜찜하다면 해당 .cpp
      파일에서 CLogFile g_LogFile; 해주시고 사용하실려는 .cpp 파일에서
      extern CLogFile g_LogFile이라고 해주셔도 됩니다.

posted by 뚱2

MFC에서 자동으로 소스를 생성하다보면 .h 파일에

#if !defined(AFX_SVRRSDLG_H__B0E12C65_26A3_4782_8556_8AE0D6107F9C__INCLUDED_)
#define AFX_SVRRSDLG_H__B0E12C65_26A3_4782_8556_8AE0D6107F9C__INCLUDED_

// 소스 ...

#endif


위와 같은 소스 비스무리하게 생긴다..
위 예제에서 defined를 찾아볼수 있는데 defined는 #define 되어 있는지 확인하는 연산자이다.
대부분 중복 컴파일 방지를 위해서 사용한다.

posted by 뚱2

[MFC] HitTest()

C/C++/VC++ / MFC 2008. 3. 3. 11:05

대부분 끌어서 놓기 동작(Drag And Drop)을 수행할 때에 끌기(Drag) 대상 항목을
현재 위치에 사용할 수 있는지를 결정하는 용도로 가장 많이 사용됩니다.

MFC의 컨트롤 중에 HitTest() 메소드가 있는 컨트롤들이 있습니다.
현재 선택된 항목(찍힌 위치의 대상)의 정보를 알수 있는 용도로 사용합니다.

각 컨트롤 마다 HitTest()의 세부 항목이 다르기 때문에 자세한 사항은 MSDN 참고하면
됩니다.

posted by 뚱2

사용자 삽입 이미지















CTreeView와 CTreeCtrl의 Hierarchy Chart 입니다.

CTreeView 안에는 CTreeCtrl& GetTreeCtrl( ) const; 로선언된 클래스 멤버 함수가
있습니다. 결국 CTreeCtrl 클래스를 Document-View 구조에서 CTreeCtrl의 사용을 쉽게
해주는 클래스 입니다.

CTreeView 클래스를 사용하기 위해서는
#include <afxcview.h>를 인클루드 해야 합니다.
posted by 뚱2

Visual C++ 6.0 에서 .dsw 파일을 오픈하는데 발생했습니다.

실제 프로젝트에 영향이 있는것은 아니었는데

신경이 쓰여서 ^^ 암튼.... 대처방법은

저 메세지 창이 뜨면 살포시 클릭하고 모든 열여있는 문서를 닫고

워크스페이스도 종료합니다.

다시 .dsw 파일로 오픈하면 에러메세지가 없어집니다.


참고 http://support.microsoft.com/kb/q202817/

'C/C++ > VC++ / MFC' 카테고리의 다른 글

[MFC] HitTest()  (0) 2008.03.03
[MFC] CTreeView와 CTreeCtrl의 관계  (0) 2008.02.25
[MFC] PreCreateWindow()  (1) 2008.02.20
[VC++ 6.0] resource 파일 Load Failed 메세지  (0) 2008.02.20
상호 참조  (4) 2008.02.20
posted by 뚱2

[MFC] PreCreateWindow()

C/C++/VC++ / MFC 2008. 2. 20. 18:51


윈도우 생성 전에 미리 호출 되는 가상함수 입니다.
인자로 받는 CREATESTRUCT& cs 의 값을 수정해서
반영시킬수 있습니다.

ps. 다만 CDialog 에서는 수정이 안된다.

posted by 뚱2
지금도 초보 이지만 초보일때 겪었는데 .rc 파일을 오픈한 상태로 리소스 창에서
오픈할려면 'resource 파일 LoadFailed' 에러 메세지가 나타납니다.

CloseAll Window 라는 메뉴를 선택후에 다시 리소스 뷰를 확인해 보시면 됩니다.
posted by 뚱2

상호 참조

C/C++/VC++ / MFC 2008. 2. 20. 18:34
C++로 프로그래밍을 작성 하다 보면은 심심치 않게 상호참조가 일어납니다.

예) 1. A와 B라는 클래스가 있습니다.
    2. 각 파일은 분리컴파일을 위해서 A.h, A.cpp, B.h, B.cpp 이렇게 선언과 정의를 분리해 있습니다.
    3. 각 파일들은 모두 같은 폴더에 위치합니다.
//A.h
#include "B.h"
class A {
    A();
    ~A();
    B b;
};

//A.cpp
#include "A.h"
A::A() {
}
A::~A() {
}

//B.h
#include "A.h"
class B {
    B();
    ~B();
    A a;
};
//B.cpp
#include "B.h"
B::B() {
}
B::~B() {
}

위와 같이 하면은 상호 참조로 인하여 에라!!!!! 가 발생합니다.
이때 해결책은
//A.h
class B;
class A {
    A();
    ~A();
    B b;
};

//A.cpp
#include "A.h"
#include "B.h"
A::A() {
}
A::~A() {
}

//B.h
class A;
class B {
    B();
    ~B();
    A a;
};

//B.cpp
#include "B.h"
#include "A.h"
B::B() {
}
B::~B() {
}


위와 같이 해주시면 간단하게 해결됩니다.
posted by 뚱2

1>d:\_work.svn\_RgnLib.h(65) : warning C4996: 'strcpy'이(가) deprecated
로 선언되었습니다.
1>        C:\Program Files\Microsoft Visual Studio 8
\VC\include\string.h(73) : 'strcpy' 선언을 참조하십시오.
1>        메시지: 'This function or variable may be unsafe. Consider using
strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'



위 경고는 2005로 오면서, 인터넷 프로그램,일반 응용프로그램의 골격을 동일한 환경에서
동작시키게 하기 위해서 조정하다보니, 보안관련한 기능이 추가되어서 나오는 경고 메세지 라고 하는군요.

해결 방법은
1. Debug/Release 모드 전처리기 선언에 _CRT_SECURE_NO_DEPRECATE 를 추가
2. 코드 최 상단에
   #define _CRT_SECURE_NO_DEPRECATE
  또는
   #pragma warning(disable:4996) 입력해 주면 됩니다.

그렇지만 위에 방법은 경고를 보이지 않게 하는것이지 문제를 해결한 것은 아닙니다.

'C/C++ > VC++ / MFC' 카테고리의 다른 글

[VC++ 6.0] resource 파일 Load Failed 메세지  (0) 2008.02.20
상호 참조  (4) 2008.02.20
오버로딩과 오버라이딩의 차이  (0) 2008.02.20
#pragma comment  (0) 2008.02.20
#pragma once  (0) 2008.02.20
posted by 뚱2
1. 오버로딩(OverLoading)

오버로딩(중복정의)이라는 것은 하나의 클래스 내에서 같은 이름을 가지는 메서드가
여러개 정의되는 것을 말합니다.
물론 생성자 뿐만 아니라 다른 메서드들도 오버로딩이 가능합니다.
이것은 컴파일시 컴파일러에 의해 각 메서드들이 구별되며 여기서 기준은 인자가
됩니다.

* 메서드 오버로딩의 특징은 다음과 같습니다.
  - 동일 클래스에서 메서드 이름을 재사용 할 수 있다. (객체지향의 특성)
  - 접근제한자는 동일하거나 동일하지 않아도 된다.
  - 리턴타입도 동일하거나 동일하지 않아도 된다.
  - 메서드 이름은 반드시 동일해야 한다.
  - 메서드의 매개인자들은 순서, 개수, 타입이 반드시 달라야 한다.


2. 오버라이딩(OverRiding)

부모 클래스에서 구현한 메서드와 동일한 헤더를 갖는 메서드를 정의하여 대체하는
개념을 의미합니다.
한마디로 메서드 재정의라 할 수 있습니다.

* 메서드 오버라이드의 특징은 다음과 같습니다.
  - 접근제한자는 달라도 되지만 부모클래스의 접근범위보다 좁으면 안된다.
  - 리턴타입은 동일해야한다.
  - 메서드 이름도 동일해야한다.
  - 메서드 매개인자의 타입, 순서, 개수 모두 동일해야 한다.
  - throws 예외 클래스 선언시 선언을 오버라이드 하지 않거나, 부모 클래스에서
   선언한
예외 클래스보다 상위 클래스로 선언하면 안된다.

'C/C++ > VC++ / MFC' 카테고리의 다른 글

상호 참조  (4) 2008.02.20
[Visual Studio 2005] warning C4996: 'strcpy'이(가) deprecated로 선언되었습니다.  (0) 2008.02.20
#pragma comment  (0) 2008.02.20
#pragma once  (0) 2008.02.20
#pragma pack  (0) 2008.02.20
posted by 뚱2

#pragma comment

C/C++/VC++ / MFC 2008. 2. 20. 17:21

주로 링크를 걸때 많이 사용합니다.
형식은

#pragma comment("comment-type" [,, commentstring])

이고 comment-type에는 compiler, exestr, lib. linker, user 등이 올 수 있습니다.
Visual Studio 2005 에서는 '프로젝트 속성--> 링커 --> 입력 --> 추가 종속성' 에서
설정 할 수 있지만 다른 코드와 호완을 생각한다면 #pragma comment을 사용하는게
좋다고 생각합니다.
posted by 뚱2

#pragma once

C/C++/VC++ / MFC 2008. 2. 20. 17:21
A.h라는 헤더 파일이 있습니다.
이 파일 제일 상단에 '#pragma once'라고 표기해주면
컴파일이 한번만 됩니다.

다른 방법으로는
#ifndef __SAMPLE__H__
#    define __SAMPLE__H__

// 한번만 컴파일 할 코드 내용

#endif// #ifndef __SAMPLE__H__

해도 됩니다.
그렇지만은 한번에 하는 #pragma once가 낫겠지요 ^^

ps. #ifndef __SAMPLE__H__는 '__SAMPLE__H__'가 정의되지 않았다면 실행하라는 말입니다.
posted by 뚱2

#pragma pack

C/C++/VC++ / MFC 2008. 2. 20. 17:19
32bit 운영체제 일때

struct A
{
     BYTE  a;  // 1Byte
     WORD  b;  // 2Byte
     DWORD c;  // 4Byte
};
A test;


1+2+4 = 7 총 7Byte라고 생각하는데
실제  sizeof(test) 해보면 12Byte로 나옵니다.
이유는 운영체제가 32bit일때 4Byte에 최적화 되어 있어서
structure가 4Byte가 아니면 4Byte로 맞추는 경향이 있습니다.
이런걸 padding이라고 하는데
이럴대는 padding을 1Byte로 맞추면 됩니다.
방법은
#pragma pack(push, 1)
struct A
{
     BYTE  a;    // 1Byte
     WORD  b;    // 2Byte
     DWORD c;    // 4Byte
};
#pragram pack(pop)


이렇게 하고 다시 sizeof로 확인해 보면은 제대로 7Byte로 나타납니다.

ps. #pragma pack 컴파일러 명령은 구조체 단위로 멤버 정렬 방식을 설정할 때 사용합니다.
posted by 뚱2
Visual Studio 2005을 처음 사용하다 보면은 자주 나타나는 에러입니다.
2005 는 기본적으로 유니코드 입니다. 그래서 변환시 에러가 발생합니다.

방법은
1. (LPTSTR)(LPCTSTR)로 강제 형변환
2. CString str;
   str.GetBuffer(str.GetLength());
   해주시면 char *을 리턴합니다.

사용예
1번의 경우는 스트링을 읽는 목적으로만 사용할때 요긴합니다.
2번의 경우는 스트링을 수정해야 할때 사용하면 편합니다.


ps. 위 두가지 방법중에 2번을 추천합니다.
      그리고 GetBuffer를 사용하시면 ReleaseBuffer()를 사용해서 해제해 주셔야합니다.

'C/C++ > VC++ / MFC' 카테고리의 다른 글

[Visual Studio 2005] warning C4996: 'strcpy'이(가) deprecated로 선언되었습니다.  (0) 2008.02.20
오버로딩과 오버라이딩의 차이  (0) 2008.02.20
#pragma comment  (0) 2008.02.20
#pragma once  (0) 2008.02.20
#pragma pack  (0) 2008.02.20
posted by 뚱2