레이블이 MFC인 게시물을 표시합니다. 모든 게시물 표시
레이블이 MFC인 게시물을 표시합니다. 모든 게시물 표시

2017년 4월 18일 화요일

MFC ListCtrl Header back color

1.1 CHeaderCtrl를 상속받은 클래스를 생성한다.
1.2 Class view에서 OnEraseBkgnd, OnNMCustomdraw를 추가한다.
1.3 OnEraseBkgnd는 return FALSE; 한다.

2.1 CListCtrl를 상속받은 클래스를 생성한다.
2.2 PreSubclassWindow()를 추가한다.
2.3 2.1에서 만든 클래스에 1.1에서 만든 크래스를 멤버 변수로 추가한다.
2.4 2.2함수에 m_listHeader.SubclassWindow(::GetDlgItem(m_hWnd, 0)); 요로코롬 추가한다.

3.1 1.2 에서 만든 OnNMCustomdraw() 함수에 그리기를 한다.

MyListHeader.h/MyListHeader.cpp

[참조]http://pingfan.egloos.com/7450045

2017년 4월 17일 월요일

MFC Modeless delete

Ddialog를 지역변수로 Modeless로 생성할때 삭제를 하려면

1. OnClose()를 추가
CDialog::OnClose(); 요건 지움
void CTestDlg::OnClose()
{
  // TODO: Add your message handler code here and/or call default
if( m_hWnd )
{
DestroyWindow();
}
//CDialog::OnClose();
}

2. PostNcDestroy()를 추가
void CTestDlg::PostNcDestroy()
{
// TODO: Add your specialized code here and/or call the base class
delete this;
CDialog::PostNcDestroy();
}
를 하면 됩니다.

2017년 2월 19일 일요일

Gidplus를 사용한 MFC 버튼 이미지( Select, Disable, Mousehover, MouseLeave)

Gdiplus를 사용해서 resource의 이미지를 가져와 버튼에 이미지를 올리는 클래스다.

GdiplusBitmapBtn.h/GdiplusBitmapBtn.cpp

Bitmap 변수가 NULL일때

  • 생성자에

GdiplusStartupInput gdiStartUp;
::GdiplusStartup( &m_gdiToken, &gdiStartUp,NULL);

  • 소멸자에

::GdiplusShutdown(m_gdiToken);

  • 해더에
ULONG_PTR m_gdiToken;


를 추가해 준다.

< 퍼갈땐 퍼간다고 남겨주세요. >

2017년 2월 8일 수요일

MFC에서 Add variable로 컨트롤의 변수나 클래스를 추가할때 스크립트 오류 메세지 발생시

DDX_ 가 호출되기 전에 DDV_가 작성되어 있으면 발생한다. DDX_가 먼저 작성되고 DDV_가 장성되도록 하자
ex) 이런 순서가 되도록
DDX_Text(pDX, IDC_EDIT, m_nInt);
DDV_inMaxUInt(pDX, m_nInt, 0, 1000);

2017년 1월 11일 수요일

4GB 이상 파일 포인터 지정( SetFilePointerEx )

4GB 이상의 파일의 파일포인터를 지정할때는 SetFilePointerEx를씀

int64_t llFileSeek (HANDLE hf, __int64 distance, DWORD MoveMethod)
{
LARGE_INTEGER li;
li.QuadPart = distance;
SetFilePointerEx(hf, li, &li, MoveMethod);
if (GetLastError() != NO_ERROR)
{
  li.QuadPart = -1;
}
    return li.QuadPart;
}


SetFilePointer를 쓸대는 QuadPart를 음수로 변환해서
난 잘 안되던데 왜인지.... 댓글좀
int64_t llFileSeek (HANDLE hf, __int64 distance, DWORD MoveMethod)
{
LARGE_INTEGER li;
li.QuadPart = -distance;
SetFilePointerEx(hf, li, &li, MoveMethod);
if (GetLastError() != NO_ERROR)
{
   li.QuadPart = -1;
}
    return li.QuadPart;
}

2016년 12월 5일 월요일

2016년 1월 12일 화요일

Invalid Address specified to RtlFreeHeap 에러 메세지

This may be due to a corruption of the heap, which indicates a bug in xxxx.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while xxxx.exe has focus.
The output window may have more diagnostic information.

이러한 에러가 나올때

http://egloos.zum.com/saintrv/v/1560122


위의 에러메세지가 호출될 경우,
New와 Delete 혹은 malloc과 free과 잘못 Match 되어 있을 가능성이 높다.
이는 DLL에서 지정한 메모리를 EXE에서 풀거나 할 때도 발생 된다.

이를테면 아래와 같은 소스의 경우

 uri = parser->getSubjectURI();

 if (uri)
 {
  fprintf(stdout, "-Subject URI: [%s]\n", (char*)uri);
  delete uri;
 }

내부에서 지정한 메모리를 외부에서 풀려고 하니 문제가 발생한다. (MultiThread 일 경우에 이 같은 현상이 나타나지 않아야 할 것 같은데 나타난다...)
이를 내부 메모리 해제 함수를 두어서 아래와 같이 수정할 경우

 uri = parser->getSubjectURI();

 if (uri)
 {
  fprintf(stdout, "-Subject URI: [%s]\n", (char*)uri);
  parser->freeliteral(uri);  
 }

해결된다. 


하지만 위의 방법으로 안될 경우에는 아래를 참고한다.

[펌]
Visual Studio를 사용하다 보면
Invalid Address specified to RtlFreeHeap와 같은 에러가 발생할 때가 있습니다.
주로 DLL을 이용한 프로그램을 만들때에 이런 에러가 발생하는데요.
이거가지고 삽질을 많이 하다가 해결 방법을 발견했습니다.

간단히 답만 말씀드리면
프로그램에서 사용하는 DLL들과 메인 프로그램 모두의 설정을 다음과 같이 바꿔주어야 합니다.

Setting -> C/C++ --> Code Generation --> MultiThreaded DLL (Debug모드일 경우 MultiThreaded DLL Debug)

그러면 위와 같은 에러가 없어집니다.
해결 방법은 여기에서 발견했습니다^^

2015년 5월 20일 수요일

MFC DLL에서 Dialog생성시 Assert Err

MFC에서는 메인의 리소스핸들을 사용하는대 DLL에서 다이얼로그를 생성하려면 DLL의 리소스 핸들이 필요하다.
때문에, DLL의 리소스 핸들로 바꾸어줘야한다.
생성전에 AFX_MANAGE_STATE(AfxGetStaticModuleState( )); 메크로 추가해야한다.
이거때문에 먼 삽질인가 



2015년 2월 4일 수요일

SetStretchBltMode(HDC, OPTION)

StretchDIBits으로 그림(사진)의 크기를 변경하여 그릴때 그림이 뭉게 지는것을 막기 위해 사용한다.
StretchDIBits() 함수를 실행하기 전에 사용하면 되겠다.

ex) SetStretchBltMode(cdc->m_hDC, HALFTONE);


https://msdn.microsoft.com/ko-kr/library/windows/desktop/dd145089(v=vs.85).aspx

2014년 12월 30일 화요일

ON_CONTROL_RANGE

ON_CONTROL_RANGE
여러개의 컨트롤을 하나의 함수로 맵핑 시켜 준다.
ON_CONTROL_RANGE(wNotifyCode, id1, id2, memberFxn );
http://msdn.microsoft.com/en-us/library/e3sz709f(VS.80).aspx

2014년 11월 30일 일요일

C++/C 문자열 출력 형식 'Format Specifier'

MFC에서 CString 형식을 %s로 문자열을 출력하려고 할때 간혹 프로그램이 죽는 경우가 있다. 이럴때는 LPCTSTR, LPCSTR 이딴걸로 구글링 해보자.
기타 출력형식은 아래 블로그를 참고 할까나
http://mwultong.blogspot.com/2006/09/cperl-printf-s-d-format-specifier.html

2014년 8월 26일 화요일

윈도우 크게에 따라 컨트롤 크기를 동적으로 변화 시키기

1. 최초 윈도우와 컨트롤들의 넓이와 높이의 비율계산
2. 윈도우의 크기에 계산된 비율을 적용하여 컨트롤 크기 변화

ex)
void dlg::CalSizeRate(void)
{
   CRect rect;
   GetClientRect(rect); //윈도우의 크기
 
   m_widthRatio = width / rect.right;
   m_heightRatio = height / rect.bottom
}

void dlg::OnSIze(UINT nType, int cx, int cy)
{
   _ctrl.GetWindowRect(&rect);
   ScreenToClient(&rect);
   rect.right = rect.left+(cx*m_widthRatio);
   rect.bottom = rect.top+(cy*m_heightRatio);
   _ctrl.MoveWindow(&rect, FALSE);
}

dll을 통하여 다이얼로그 생성[Create()]시 invalid dialog template name

dll프로젝트를 생성 할때 Use MFC in a Static Library로 생성해야 한다.

2014년 7월 29일 화요일

[MFC] 버튼에 이미지(비트맵) 입히기 CBitmapButton

MFC에서 버튼에 그림을 입힐 수 있다.
보통 사용하는 CButton을 대신해 CBitmapButton으로 변수를 선언하여 주면 버튼에 이미지를 입히는것이 가능하며, 버튼의 상태(눌렀을때, 포커스가 갔을때 등)에 따라 이미지를 달리 줄 수 있다.
버튼에 이미지를 입힐때는 LoadBitmaps()를 사용하면 된다.
LoadBitmaps는 4가지 Argument를 사용한다.

  cbitmapButton.LoadBitmaps(일반, 눌렀을때, 포커스가 갔을때, 사용안함일때)

MSDN(http://msdn.microsoft.com/ko-kr/library/6y6acs49.aspx)

2014년 7월 24일 목요일

[MFC] 화면다시그리기(갱신?): Invalidate()

강제로 화면을 다시 그리는 함수다.

 Invalidate(TRUE)   //화면전체
 Invalidate(FALSE) //변경된 부분만

컨트롤의 이동이나 크기의 변경이 있을때는 그뒤에 추가해주자

MSDN

[MFC] 컨트롤 크기, 위치 변경

MFC에서 컨트롤을 생성하고 컨트롤의 위치를 변경하고 싶을경우 MoveWindow() 함수를 사용한다.(http://msdn.microsoft.com/ko-kr/library/5bc5w1zz.aspx)
msdn에 위 함수를 사용할때 필요한 매개변수들이 설명되 있다.
나는 CRect()을 사용해서 위치와 크기를 변경하는것을 선호한다. 왠지 이게 편하다.

MovieWindow(CRect(Cpoint(p_x, p_y),CSize(width, height)));

이렇게 하면 컨트롤의 왼쪽 가장위 모서리를(Cpoint)로 위치를 결정하고 폭과 높이(CSize)를 통해 크기를 결정한다.

MFC에서 다이얼로그에 컨트롤를 생성할때 쉽게 Toolbox에서 Drag&Drop해서 직접 크기와 위치를 정해줄 수 있지만 Code에서 MovieWindow()같은 함수를 사용하여 크기와 위치를 정의하는 것이 더 좋을것같다.

그리고 컨트롤의 위치와 크기를 변경한 후에는 Invalidate();를 마지막에 해주자

2014년 7월 18일 금요일

[MFC] Plug-In 만들기1

MFC에 Add-In(Plug-In)기능을 만들어 보자.
MFC로 개발하면서 이클립스 같은 Plug-In기능을 구현해 보려고 한다.

http://www.codeproject.com/Articles/2489/Plug-In-framework-using-DLLs
에 올라온 예제 코드를 참조하여 구현해 볼것이다. 설명도 제법 잘 써놨다. 10년도 더된 코드지만 아무것도 모르는 나에게는 매우 유용한 소스코드다.
위에 따르면 프로그램은 다음과 같은 과정을 거친다.
  1. The main app is initialized (i.e. started)
  2. The DLLs/Plug-Ins are searched in the directory (may be pre-determined)
  3. Once "valid" DLLs are found, all or selected DLLs are loaded
  4. "Init" function is invoked on all loaded DLLs
  5. The instance and the DLL name/path are cached for future use (method invocation)
  6. User uses the functionality of the DLLs (using GUI interfaces provided by the DLLs)
  7. Once done, the main application invokes "Destroy" function of the DLLs one by one to free resources
  8. The main application exits
마지막에 하는 말이 간단하다고 한다..ㅡㅡ 난 왜이리 낯설고 어렵운지 MFC의 경험이 많지 않아서 (C++ 포함) 그런지 매우어렵다. 프로그램이 대충 어찌 돌아야 하는지 알았으니 예제 따라 구현해봐야지~~

2014년 7월 17일 목요일

[MFC] SDI 에서 (MENU) 없에기


BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWndEx::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
//  the CREATESTRUCT cs
cs.style &= ~FWS_ADDTOTITLE;
cs.hMenu = NULL; //요놈을 추가한다.
return TRUE;
}

'cs.hMenu = NULL;'을 추가하고 디버깅시 assertion failed이 날때

ON_WM_CREATE()

static UINT indicators[] =
{
ID_SEPARATOR,           // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};

if (!m_wndstatusbar.create(this))
{
trace0("failed to create status bar\n");
return -1;      // fail to create
}
m_wndstatusbar.setindicators(indicators, sizeof(indicators)/sizeof(uint));

위의 코드들을 주석또는 삭제