보통 수정을 하지 않은 상태에서
MFC 에 있는 MessageBox 또는 AfxMessageBox 를 사용할 때
메세지박스의 제목(caption) 을 지정하지 않을 경우
실행 파일의 이름이나 처음 프로젝트 만들때 지정한 텍스트가 나오게 된다

더구나 그 제목에 표시되는 텍스트가 레지스트리/INI 에 저장할 때도 그대로 쓰이게 된다

이를 바꾸기 위해서는
1. 리소스 스트링 테이블에 AFX_IDS_APP_TITLE 이 있는 경우 해당 값을 바꾸면 되고
2. CWinApp 의 m_pszAppName 을 초기 코드에서 바꿔주면 된다

참고로 m_pszAppName 을 수정하기 할때 문자열이 지속적으로 메모리에 남아있도록 해야한다.

//First free the string allocated by MFC at CWinApp startup.
//The string is allocated before InitInstance is called.
free((void*)m_pszAppName);
//Change the name of the application file.
//The CWinApp destructor will free the memory.
m_pszAppName=_tcsdup(_T("호호호호"));


MFC 예제
Posted by 김모작자
TAG MFC

댓글을 달아 주세요

원본글에 있는 프로젝트를 받아 간단하게 함수 형태로 변환한 소스.
WOL 등에 필요한 Mac Address 를 구하기 위해.

원본글 : 찾아가기
----------------------------------

#include
#pragma comment(lib, "iphlpapi.lib")
CString GetMacByIP(const CString& strIP)
{
       CAsyncSocket sock;
       sock.Create(1000, SOCK_DGRAM);
       sock.SendTo(&sock, 1, 1000, strIP);

       CString strMAC;
       PMIB_IPNETTABLE pIPNetTable;
       pIPNetTable = (MIB_IPNETTABLE*) malloc( sizeof( MIB_IPNETTABLE) );

       DWORD dwSize = 0, dwRetVal=0;
       if ( (dwRetVal=GetIpNetTable(pIPNetTable, &dwSize, 0)) == ERROR_INSUFFICIENT_BUFFER)
       {
               free( pIPNetTable );
               pIPNetTable = (MIB_IPNETTABLE *) malloc ( dwSize );
       }
       else
       {
               CString strErr;
               LPTSTR lpMsgBuf;
               FormatMessage(                         FORMAT_MESSAGE_ALLOCATE_BUFFER |
                                                               FORMAT_MESSAGE_FROM_SYSTEM |
                                                               FORMAT_MESSAGE_IGNORE_INSERTS,
                                                               NULL,
                                                               WSAGetLastError(),
                                                               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                                                               (LPTSTR) &lpMsgBuf,
                                                               0,
                                                               NULL );

               OutputDebugString(lpMsgBuf);
               LocalFree( lpMsgBuf );
       }

       // Make a second call to GetIpAddrTable to get the
       // actual data we want
       if ( (dwRetVal = GetIpNetTable( pIPNetTable, &dwSize, 0 )) == NO_ERROR )
       {
               for (UINT i=0;idwNumEntries;i++)
               {
                       if ((pIPNetTable->table[i].dwAddr) == inet_addr(strIP))
                       {
                               BYTE *pt = (BYTE*)&pIPNetTable->table[i].bPhysAddr;
                               for (int j=0;j<6;j++)
                                       strMAC.AppendFormat(_T("%02X"),*pt++);
                               break;
                       }
               }
       }
       //Cleanup
       if(pIPNetTable)
       {
               free( pIPNetTable );
               pIPNetTable = NULL;
       }
       return strMAC;
}
Posted by 김모작자
TAG mac, MFC

댓글을 달아 주세요

항상 잊을만 하면 쓸 필요가 생기는 코드.

내부적으로 trace 를 구현할 때 참 유용하다.
특히 MFC 의 TRACE 는 유니코드 문자열을 지원하지 못하기 때문에 MFC 로 유니코드 어플리케이션을 만들때 急 필요한 코드 조각이다.

기왕이면 아래 1024 바이트를 스택에 만드는 것보다 스레드 별로 TLS 를 만드는 편이 더 낫겠다는 생각이 글 쓰면서 들었다 -_-

// 1. 일반적인 코딩
void _DBGTRACE(TCHAR* format, ...)
{
       TCHAR buf[1024];
       va_list        marker;
       va_start(marker, format);
       _vstprintf(buf, format, marker);
       va_end(marker);

       OutputDebugString(buf);
}

// 2. 안전+LFH힙을 이용한 문자열 포맷팅
 LPCTSTR HFormat(LPCTSTR format, ...)
 {
  va_list        marker;
  va_start(marker, format);

  int len = _vsctprintf( format, marker ) + 1;
  LPTSTR buf = (LPTSTR)Alloc(len);
  _vstprintf_s(buf, len, format, marker);

  va_end(marker);

  return buf;
 }

문자열의 경우 LFH(Low Fragment Heap) 을 사용하면 이득을 볼 수 있기 때문에 Alloc 에 해당하는 함수에서 적절히(?) 처리해주고.. _s 계열 함수를 이용해 버퍼 오버런에 대응할 수 있도록 한다..

Posted by 김모작자
TAG MFC, Trace

댓글을 달아 주세요

  1. 해보리 2009.02.17 19:53  댓글주소  수정/삭제  댓글쓰기

    vsprintf()에서 char 형변환 때문에 문제가 생기지 않았는지 궁금하네요...
    유니코드로 하면 함수 자체는 char*를 받아가는 거라... 오류가 발생할텐데요...

실제 표시되는 다이얼로그


CredUIPromptForCredentials - creates and displays a configurable dialog box that accepts credentials information from a user.

예)

#include <WinCred.h>
#pragma comment(lib, "Credui.lib")

...
       TCHAR name[100] = _T("화면에 미리 표시될 이름");
       TCHAR passwd[100] = _T("화면에 미리 표시될 비밀번호");
       BOOL save = FALSE;

       CREDUI_INFO info;
       info.cbSize = sizeof(CREDUI_INFO);
       info.hwndParent = NULL;
       info.pszCaptionText = _T("제목!");
       info.pszMessageText = _T("물어볼 메세지");
       info.hbmBanner = NULL;

       DWORD v = CredUIPromptForCredentials(&info, _T("."), NULL, 0, name, 99, passwd, 99, &save, 0);

리턴된 v 가 NO_ERROR 인 경우 name, passwd 에 해당 ID, 비밀번호가 들어가 있다

Posted by 김모작자

댓글을 달아 주세요

허구언날 돌아댕기는 소스..
간혹 유용하더라..

하지만 2008년 이 글을 옮기는 시점까지 이 소스 한번 써봤다는거...

void CMainFrame::ChangeView(CMainFrame::MakerViewMode viewmode)
{
       CString         szFrameTitle = _T("");
   CRuntimeClass*  pNewViewClass;
   CView*          pActiveView = GetActiveView();
   INT             nViewIndex;

   switch(viewmode)
   {
   case 1:
       nViewIndex = 2;
       pNewViewClass = RUNTIME_CLASS(CViewSwitchingView);
       break;
   case 2:
       nViewIndex = 2;
       pNewViewClass = RUNTIME_CLASS(CSecondView);
       break;
   }

   CView* pNewView;
   if(m_pViewArray[nViewIndex] == NULL)
   {
       CCreateContext context;
       context.m_pNewViewClass = pNewViewClass;
       context.m_pCurrentDoc   = GetActiveDocument();
       pNewView = STATIC_DOWNCAST(CView, CreateView(&context));        

       m_pViewArray[nViewIndex] = pNewView;
   }

   pNewView = m_pViewArray[nViewIndex];

   pActiveView->ShowWindow(SW_HIDE);
   SetActiveView(pActiveView,false); // 기능정지

   pNewView->ShowWindow(SW_SHOW);
   pNewView->OnInitialUpdate();

   SetActiveView(pNewView,true);
   RecalcLayout();
}
Posted by 김모작자
TAG MFC

댓글을 달아 주세요

선언부에
       // editbox
       CContainedWindow        m_EditCtrl;

추가
생성자에 추가로
       :m_EditCtrl(_T("EDIT"), this, 1)
해서 초기화 하고

ALT_MSG_MAP(1)
  WM_IME_CHAR 추가
여기서 1은 위에 1과 같은 번호이다

나머지 코드는...
LRESULT CMyCompositeControl::OnEditImeChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
       static char kk[3];

       kk[0] = (char) (wParam & 0xff);
       kk[1] = (char) (wParam >> 8);
       m_EditCtrl.SendMessage(EM_SETSEL, 0, -1);
       m_EditCtrl.SendMessage(EM_SETSEL, -1, 0);
       m_EditCtrl.SendMessage(EM_REPLACESEL, FALSE, (LPARAM) kk);
       bHandled = TRUE;
       return 0;
}
Posted by 김모작자

댓글을 달아 주세요