HINSTANCE CreateInstanceFromDll(LPCTSTR lpDllName, REFCLSID rclsid, REFIID riid, LPVOID * ppv)
{
 (*ppv) = NULL;

 HINSTANCE hDll = LoadLibrary( lpDllName );
 if ( NULL == hDll )
 {
  return NULL;
 }

 typedef HRESULT (__stdcall *GETCLASS_PROC)(REFCLSID,REFIID,LPVOID*);

 GETCLASS_PROC procGetClassObject = (GETCLASS_PROC)GetProcAddress( hDll, "DllGetClassObject" );

 if( procGetClassObject )
 {
  IClassFactory* pFactory = NULL;

  HRESULT hr = procGetClassObject(rclsid, IID_IClassFactory, (void**)&pFactory);
  if( pFactory )
  {
   hr = pFactory->CreateInstance( NULL, riid, ppv);

   pFactory->Release();
   pFactory = NULL;

   if( NULL == *ppv )
   {
    FreeLibrary( hDll );
    return NULL;
   }
  }
  else
  {
   FreeLibrary( hDll );
   return NULL;
  }
 }
 else
 {
  FreeLibrary( hDll );
  return NULL;
 }

 return hDll;
}

Posted by 셈말짓기 :

// wf1.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using System.Drawing;
using System.Drawing.Imaging;

public partial class wf1 : System.Web.UI.Page
{
    private const int    IMAGE_WIDTH  = 320;
    private const int    IMAGE_HEIGHT = 240;
    private const string IMAGE_FORMAT = "image/gif";

    private Bitmap     _bitmap;
    private Graphics   _graphics;
    private Font       _font      = new Font ("굴림", 8);
    private SolidBrush _fontBrush = new SolidBrush(Color.Black);
    private SolidBrush _fillBrush = new SolidBrush(Color.Yellow);
    private string     _label     = "테스트";

    protected void Page_Load(object sender, EventArgs e)
    {
        _bitmap = new Bitmap(IMAGE_WIDTH, IMAGE_HEIGHT, PixelFormat.Format32bppArgb);

        _graphics = Graphics.FromImage(_bitmap);

        _graphics.FillRectangle(_fillBrush, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
        _graphics.DrawString   (_label, _font, _fontBrush, 10, 10);

        Response.ContentType = IMAGE_FORMAT;
        _bitmap.Save(Response.OutputStream, ImageFormat.Gif);
    }
}

Posted by 셈말짓기 :

class CMainFrame :

        public CFrameWindowImpl<CMainFrame>,

        public CUpdateUI<CMainFrame>,

        public CMessageFilter, public CIdleHandler

{

public:

 

DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)

 

BEGIN_MSG_MAP(CMainFrame)

 

        MESSAGE_HANDLER    ( WM_CREATE        , OnCreate       )

        MESSAGE_HANDLER    ( WM_DESTROY       , OnDestroy      )

        MESSAGE_HANDLER    ( WM_DROPFILES     , OnDropFile     )

        COMMAND_ID_HANDLER ( ID_SELECTFOLDER  , OnSelectFolder )

        COMMAND_ID_HANDLER ( ID_FILE_OPEN     , OnFileOpen     )

        COMMAND_ID_HANDLER ( ID_FILE_SAVE     , OnFileSave     )

        ...

END_MSG_MAP()

 

LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)

{

        ...

        DragAcceptFiles (TRUE);

 

        return 0;

}

 

LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)

{

        DragAcceptFiles (FALSE);

        ...

}

 

LRESULT OnDropFile (UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)

{

        HDROP  hDrop = (HDROP) wParam;    

 

        TCHAR filePath [MAX_PATH];

        int   fileCount;

        int   index;

 

        fileCount = DragQueryFile (hDrop, -1, NULL, NULL);

        if (fileCount > 0)

        {

               for (index=0; index<fileCount; index++)

               {

                       if (DragQueryFile (hDrop, index, filePath, sizeof(filePath)))

                       {

                              ATLTRACE (_T("OnDropFile(): %s \r\n"), filePath);

                       }

               }

        }

 

        DragFinish(hDrop);

 

        return 0;

}

 

LRESULT OnSelectFolder (WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)

{

        BROWSEINFO   bi = { 0 };

        LPITEMIDLIST pidl;

        TCHAR        path[MAX_PATH] = { 0 };

 

        ZeroMemory (&bi,sizeof(BROWSEINFO));

 

        bi.ulFlags        = 0;

        bi.lpszTitle      = NULL;

        bi.pszDisplayName = path;

        pidl              = SHBrowseForFolder ( &bi );

 

        if ( pidl != 0 )

        {

               if (SHGetPathFromIDList (pidl, path))

               {

                       ATLTRACE (_T("OnSelectFolder(): %s \r\n"), path);

               }

 

               // free memory used

               IMalloc * imalloc = 0;

               if ( SUCCEEDED( SHGetMalloc ( &imalloc )) )

               {

                       imalloc->Free ( pidl );

                       imalloc->Release ( );

               }

        }

 

        return 0;

}

 

LRESULT OnFileSave(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)

{

        CFileDialog FileOpenDilaog

        (

               FALSE,

               _T("bin"),

               _T("default.bin"),         

               OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,

               _T("Binary Files (*.bin)\0*.bin\0All Files (*.*)\0*.*\0"),

               m_hWnd

        );

 

 

        if (FileOpenDilaog.DoModal() == IDOK)

        {

               ATLTRACE (_T("OnFileSave(): %s \r\n"), FileOpenDilaog.m_szFileName);

        }

 

        return 0;

}

 

LRESULT OnFileOpen(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)

{

        CFileDialog FileOpenDilaog

        (

                TRUE,

               _T("bin"),

               NULL,

               OFN_HIDEREADONLY,

               _T("Binary Files (*.bin)\0*.bin\0All Files (*.*)\0*.*\0"),

               m_hWnd

        );

 

        if (FileOpenDilaog.DoModal() == IDOK)

        {

               ATLTRACE (_T("OnFileOpen(): %s \r\n"), FileOpenDilaog.m_szFileName);

        }

 

        return 0;

}

 

};

 

Posted by 셈말짓기 :

 

LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)

{

        // . . .

 

        // delete memuitems

        CMenuHandle menu     = m_CmdBar.GetMenu();

        CMenuHandle menuFile = menu.GetSubMenu (0);

       

        menuFile.RemoveMenu (ID_FILE_NEW,           MF_BYCOMMAND);

        menuFile.RemoveMenu (ID_FILE_OPEN,          MF_BYCOMMAND);

        menuFile.RemoveMenu (ID_FILE_SAVE,          MF_BYCOMMAND);

        menuFile.RemoveMenu (ID_FILE_SAVE_AS,       MF_BYCOMMAND);

        menuFile.RemoveMenu (0,                     MF_SEPARATOR);

        menuFile.RemoveMenu (ID_FILE_PRINT,         MF_BYCOMMAND);

        menuFile.RemoveMenu (ID_FILE_PRINT_PREVIEW, MF_BYCOMMAND);

        menuFile.RemoveMenu (ID_FILE_PRINT_SETUP,   MF_BYCOMMAND);

        menuFile.RemoveMenu (0,                     MF_SEPARATOR);

 

        CMenuHandle menuWindow = menu.GetSubMenu (3);

        menuWindow.RemoveMenu (ID_WINDOW_CLOSE,      MF_BYCOMMAND);

        menuWindow.RemoveMenu (ID_WINDOW_CLOSE_ALL,  MF_BYCOMMAND);

        menuWindow.RemoveMenu (0,                    MF_SEPARATOR);

       

        menu.DeleteMenu (1,MF_BYPOSITION); // EDIT menu

        m_CmdBar.AttachMenu (menu);

       

        // delete buttons of toolbar

        CToolBarCtrl toolbar;

       

        toolbar.Attach (hWndToolBar);

 

        toolbar.DeleteButton (0); // NEW

        toolbar.DeleteButton (0); // OPEN

        toolbar.DeleteButton (0); // SAVE

        toolbar.DeleteButton (0); // -

        toolbar.DeleteButton (0); // CUT

        toolbar.DeleteButton (0); // COPY

        toolbar.DeleteButton (0); // PASTE

        toolbar.DeleteButton (0); // -

        toolbar.DeleteButton (0); // PRINT

       

        toolbar.Detach ();

       

        return 0;

}

 

Posted by 셈말짓기 :


1. C Code로 저장 가능
2. 넓이가 16/8 pixel인 font 지원
Posted by 셈말짓기 :

요즘 다 Win32 API와 MSVC C Runtime Library만 불러다쓰니 어느게 표준 함수인지 모르겠다.
그래서, 표준함수를 찾아 보았다.

표준 함수 목록

------------------------------------------------------------------------------------
C89
------------------------------------------------------------------------------------
assert.h
assert()

ctype.h
isalnum() isalpha() iscntrl() isdigit() isgraph() 
islower() isprint() ispunct() isspace() isupper() 
isxdigit() tolower() toupper()

locale.h
localeconv() setlocale()

math.h
acos() asin() atan() atan2() ceil() 
cos() cosh() exp() fabs() floor() 
fmod() frexp() ldexp() log() log10() 
modf() pow() sin() sinh() sqrt() 
tan()

setjmp.h
longjmp() setjmp()

signal.h
raise() signal()

stdarg.h
va_arg() va_end() va_start()

stddef.h
offsetof()

stdio.h
clearerr() fclose() feof() ferror() fflush() 
fgetc() fgetpos() fgets() fopen() fprintf() 
fputc() fputs() fread() freopen() fscanf() 
fseek() fsetpos() fwrite() getc() getchar() 
gets() main() perror() printf() putc() 
putchar() puts() remove() rename() rewind() 
scanf() setbuf() setvbuf() sprintf() sscanf()
tmpfile() tmpnam() ungetc() vfprintf() vprintf() 
vsprintf()

stdlib.h
abort() abs() atexit() atof() atoi() 
atol() bsearch() calloc() div() exit() 
free() ftell() getenv() labs() ldiv() 
malloc() mblen() mbstowcs() mbtowc() qsort() 
rand() realloc() sizeof() srand() strtod() 
strtol() strtoul() system() wctomb() wcstombs()

string.h
memchr() memcmp() memcpy() memmove() memset() 
strcat() strchr() strcmp() strcoll() strcpy() 
strcspn() strerror() strlen() strncat() strncmp() 
strncpy() strpbrk() strrchr() strspn() strstr() 
strtok() strxfrm()

time.h
asctime() clock() ctime() difftime() gmtime() 
localtime() mktime() strftime() 


------------------------------------------------------------------------------------
C99
------------------------------------------------------------------------------------
complex.h
cabs() cabsf() cabsl() cacos() cacosf() 
cacosl() cacosh() cacoshf() cacoshl() carg() 
cargf() cargl() casin() casinf() casinl() 
casinh() casinhf() casinhl() catan() catanf() 
catanl() catanh() catanhf() catanhl() conj() 
conjf() conjl() ccos() ccosf() ccosl() 
ccosh() ccoshf() ccoshl() cproj() cprojf() 
cprojl() cexp() cexpf() cexpl() cimag()
cimagf() cimagl() clog() clogf() clogl()
cpow() cpowf() cpowl() creal() crealf()
creall() csin() csinf() csinl() csinh()
csinhf() csinhl() csqrt() csqrtf() csqrtl()
ctan() ctanf() ctanl() ctanh() ctanhf()
ctanhl()
 
ctype.h
isblank()

fenv.h
feclearexcept() feholdexcept() fegetenv() fegetexceptflag() fegetround()
feraiseexcept() fesetenv() fesetexceptflag() fesetround() fetestexcept()
feupdateenv()

inttypes.h
imaxabs() imaxdiv() strtoimax() strtoumax()  wcstoimax() 
wcstoumax()

math.h
acosf() acosl() acosh() acoshf() acoshl()
asinf() asinl() asinh() asinhf() asinhl()
atanf() atanl() atanh() atanhf() atanhl()
atan2f() atan2l() cbrt() cbrtf() cbrtl()
ceilf() ceill() cosf() cosl() coshf()
coshl() copysign() copysignf() copysignl() erf() 
erff() erfl() erfc() erfcf() erfcl() 
expf() expl() exp2() exp2f() exp2l()
expm1() expm1f() expm1l() fabsf() fabsl()
floorf() floorl() fdim() fdimf() fdiml()
fma() fmaf() fmal() fmax() fmaxf()
fmaxl() fmin() fminf() fminl() fmodf()
fmodl() frexpf() frexpl() hypot() hypotf()
hypotl() ilogb() ilogbf() ilogbl() ldexpf()
ldexpl() lgamma() lgammaf() lgammal() llrint()
llrintf() llrintl() llround() llroundf() llroundl()
logf() logl() logb() logbf() logbl()
log10f() log10l() logp1() logp1f() logp1l()
log2() log2f() log2l() lrint() lrintf()
lrintl() lround() lroundf() lroundl() modff()
modfl() nan() nanf() nanl() nearbyint() 
nearbyintf() nearbyintl() nextafter() nextafterf() nextafterl()
nexttoward() nexttowardf() nexttowardl() powf() powl()
remainder() remainderf() remainderl() remquo() remquof() 
remquol() rint() rintf() rintl() round() 
roundf() roundl() scalbln() scalblnf() scalblnl()
scalbn() scalbnf() scalbnl() sinf() sinl()
sinhf() sinhl() sqrtf() sqrtl() tanf()
tanl() tanhf() tanhl() tgamma() tgammaf()
tgammal() trunc() truncf() truncl()

stdarg.h
va_copy()

stdio.h
fgetpos() fgets() fopen() fprintf() fputs() 
fread() freopen() fscanf() fwrite() printf()
scanf() setbuf() setvbuf() snprintf() sprintf() 
sscanf() vfprintf() vfscanf() vprintf() vscanf()
vsnprintf() vsprintf() vsscanf()

stdlib.h
atoll() _Exit() llabs() lldiv() mbstowcs() 
mbtowc() strtod() strtof() strtol() strtold() 
strtoll() strtoul() strtoull() wcstombs()

string.h
memcpy() strcat() strcpy() strncat() strncpy() 
strtok() strxfrm()

time.h
mkxtime() strftime() strfxtime() zonetime()

wchar.h
btowc() fgetwc() fgetws() fputwc()fputws() 
fwide() fwprintf() fwscanf() getwc() getwchar()
mbrlen() mbrtowc() mbsinit() mbsrtowcs() putwc() 
putwchar() swprintf() swscanf() ungetwc() vfwprintf() 
vfwscanf() vswprintf() vswscanf() vwprintf() vwscanf() 
wcrtomb() wcsftime() wcsrtombs() wcstod() wcstof() 
wcstol() wcstold() wcstoll() wcstoul() wcstoull() 
wcscat() wcschr() wcscmp() wcscoll() wcscpy() 
wcscspn() wcslen() wcsncat() wcsncmp() wcsncpy() 
wcspbrk() wcsrchr() wcsspn() wcsstr() wcstok()
wcsxfrm() wctob() wmemchr() wmemcmp() wmemcpy() 
wmemmove() wmemset() wprintf() wscanf()

wctype.h
iswalnum() iswalpha() iswblank() iswcntrl() iswctype()
iswdigit() iswgraph() iswlower() iswprint() iswpunct() 
iswspace() iswupper() iswxdigit() towctrans() towlower()
towupper() wctrans() wctype()


참고자료:
http://www.utas.edu.au/infosys/info/documentation/C/CStdLib.html
http://www.esnips.com/doc/46e78cce-ef6e-47c4-b828-82fa1f88ea81/A-Dictionary-of-ANSI-Standard-C-Function-Definitions

 
Posted by 셈말짓기 :

EnumChildWindows

2009. 7. 3. 12:07 from 셈말짓기/옹알이

Child Window 순회 함수...
그런데... MS가 만든게 있었네 =_=;
 
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
 CWindow wnd (hwnd);
 wnd.SetFont ((HFONT)lParam);

 return TRUE;
}

BOOL myEnumChildWindows (HWND hParent, WNDENUMPROC lpEnumProc, LPARAM lParam)
{
 HWND hEnum;
 BOOL bContinue = TRUE;

 TCHAR szCaption[256];

 hEnum = ::GetWindow (hParent, GW_CHILD);
 while (NULL!=hEnum && TRUE==bContinue)
 {
  ::GetWindowText (hEnum, szCaption, 256);
  ATLTRACE (_T("Child=%08x,%s \r\n"), hEnum, szCaption);

  bContinue = lpEnumProc (hEnum, lParam);

  if (NULL!=::GetWindow (hEnum, GW_CHILD))
  {
   if (TRUE==bContinue)
    bContinue=EnumChildWindows (hEnum, lpEnumProc, lParam);
  }

  hEnum = ::GetNextWindow (hEnum, GW_HWNDNEXT);
 }

 return bContinue;
}

Posted by 셈말짓기 :




wince에서는 CreateRoundRectRgn()함수가 지원이 안되서 구글 힘을 빌려 만들어 봤습니다. 원본소스는 
http://www.ocera.org/archive/upvlc/public/components/sa-rtl/sa-rtl-2.2-pre2/mw/mwin/winrgn.c
에 있는 일부분을 참고해서 만들었습니다.

 
// TestCEGraphView.h : interface of the CTestCEGraphView class
//
/////////////////////////////////////////////////////////////////////////////

#pragma once

#include <vector>

HRGN CreateRoundRectRgn (int left, int top, int right, int bottom, int ellipse_width, int ellipse_height )
{
 HRGN              hrgn = 0;
 int               asq, bsq, d, xd, yd;
 RECT              rect;
 std::vector<RECT> rects;

 if (ellipse_width == 0 || ellipse_height == 0)
  return CreateRectRgn( left, top, right, bottom );

 /* Make the dimensions sensible */
 if (left > right ) { int tmp = left; left = right;  right  = tmp; }
 if (top  > bottom) { int tmp = top;  top  = bottom; bottom = tmp; }

 ellipse_width  = abs(ellipse_width);
 ellipse_height = abs(ellipse_height);

 /* Check parameters */
 if (ellipse_width  > right-left) ellipse_width  = right-left;
 if (ellipse_height > bottom-top) ellipse_height = bottom-top;

 /* Ellipse algorithm, based on an article by K. Porter */
 /* in DDJ Graphics Programming Column, 8/89 */
 asq = ellipse_width  * ellipse_width  / 4; /* a^2 */
 bsq = ellipse_height * ellipse_height / 4; /* b^2 */
 if (asq == 0) asq = 1;
 if (bsq == 0) bsq = 1;
 d  = bsq - asq * ellipse_height / 2 + asq / 4; /* b^2 - a^2b + a^2/4 */
 xd = 0;
 yd = asq * ellipse_height;                     /* 2a^2b */

 rect.left   = left + ellipse_width  / 2;
 rect.right  = right - ellipse_width / 2;

 rects.reserve (ellipse_height);

 /* Loop to draw first half of quadrant */
 while (xd < yd)
 {
  /* if nearest pixel is toward the center */
  if (d > 0) 
  {
   /* move toward center */
   rect.top    = top++;
   rect.bottom = rect.top + 1;
   rects.push_back (rect);

   rect.top    = --bottom;
   rect.bottom = rect.top + 1;
   rects.push_back (rect);

   yd -= 2*asq;
   d  -= yd;
  }
  /* next horiz point */
  rect.left --;       
  rect.right++;
  xd += 2*bsq;
  d  += bsq + xd;
 }

 /* Loop to draw second half of quadrant */
 d += (3 * (asq-bsq) / 2 - (xd+yd)) / 2;
 while (yd >= 0)
 {
  /* next vertical point */
  rect.top    = top++;
  rect.bottom = rect.top + 1;
  rects.push_back (rect);

  rect.top    = --bottom;
  rect.bottom = rect.top + 1;
  rects.push_back (rect);

  /* if nearest pixel is outside ellipse */
  if (d < 0)  
  {
   /* move away from center */
   rect.left --;    
   rect.right++;
   xd += 2*bsq;
   d  += xd;
  }
  yd -= 2*asq;
  d  += asq - yd;
 }

 /* Add the inside rectangle */
 if (top <= bottom)
 {
  rect.top    = top;
  rect.bottom = bottom;
  //rects.push_back (rect);
  rects.insert (rects.begin(), rect);
 }
 
 static int count=0;
 std::vector<RECT>::iterator i;
 for (i=rects.begin(); i!=rects.end(); i++)
 {
  ATLTRACE (_T("[%d]%3d,%3d:%3d,%3d \r\n"), ++count,
   (*i).top,
   (*i).bottom,
   (*i).left,
   (*i).right
   );
 }
 if (rects.empty())
  return NULL;

 RGNDATAHEADER* pRgnData;
 UINT           RgnDataSize;
 UINT           RgnRectCount;
 LPRECT         pRect;

 RgnRectCount = rects.size();
 RgnDataSize  = sizeof(RGNDATAHEADER) + sizeof(RECT)*RgnRectCount;
 pRgnData     = (RGNDATAHEADER*)new BYTE[ RgnDataSize ];
 if (pRgnData==NULL)
  return NULL;

 pRgnData->dwSize         = sizeof(RGNDATAHEADER);
 pRgnData->iType          = RDH_RECTANGLES;
 pRgnData->nCount         = RgnRectCount;
 pRgnData->rcBound.left   = 0;
 pRgnData->rcBound.top    = 0;
 pRgnData->rcBound.right  = 0;
 pRgnData->rcBound.bottom = 0;

 pRect = (LPRECT) ( (LPBYTE) pRgnData + sizeof(RGNDATAHEADER) );

 memcpy (pRect, &*rects.begin(), RgnRectCount*sizeof(RECT));

 hrgn = ExtCreateRegion(NULL, RgnDataSize, (LPRGNDATA)pRgnData);

 delete pRgnData;

 return hrgn;
}

class CTestCEGraphView : public CWindowImpl<CTestCEGraphView>
{
public:
 DECLARE_WND_CLASS(NULL)

 BOOL PreTranslateMessage(MSG* pMsg)
 {
  pMsg;
  return FALSE;
 }

 BEGIN_MSG_MAP(CTestCEGraphView)
  MESSAGE_HANDLER(WM_PAINT, OnPaint)
 END_MSG_MAP()

// Handler prototypes (uncomment arguments if needed):
// LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
// LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
// LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
 
 LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
 { 
  CPaintDC dc(m_hWnd);
  CBrush brush[3];

  brush[0].CreateSolidBrush (RGB(0xff,0x00,0x00));
  brush[1].CreateSolidBrush (RGB(0x00,0xff,0x00));
  brush[2].CreateSolidBrush (RGB(0x00,0x00,0xff));
  
  HRGN hrgn;
  
  hrgn = CreateRoundRectRgn (10,10,200,100,200,200);
  dc.FillRgn (hrgn , brush[0]);
  DeleteObject (hrgn);

  hrgn = CreateRoundRectRgn (10,150,200,250,20,50);
  dc.FillRgn (hrgn , brush[1]);
  DeleteObject (hrgn);

  hrgn = CreateRoundRectRgn (10,300,200,400,20,20);
  dc.FillRgn (hrgn , brush[2]);
  DeleteObject (hrgn);

  return 0;
 }
};

Posted by 셈말짓기 :
http://www.codeproject.com/KB/cpp/cppproperties.aspx
에 있는걸 참고해서 문제가 있었던 object1.prop = object2.prop의 문제를 수정하였으나
그 이외에도 문제가 많다.


#include <stdio.h>
#include <atlbase.h>
#include <iostream>

/////////////////////////////////////////////////////////////////////////////
//
// Interface of the CProperty<TContainer,TValue> class
//    Ref=http://www.codeproject.com/KB/cpp/cppproperties.aspx
//        
/////////////////////////////////////////////////////////////////////////////
template<typename TContainer, typename TValue>
class CProperty
{
public:
    typedef TValue (TContainer::*SETPROC)(TValue value);
    typedef TValue (TContainer::*GETPROC)(void) const;

private:
    TValue      m_Value;
    SETPROC     m_pSetProc;
    GETPROC     m_pGetProc;
    TContainer* m_pContainer;

public:
    CProperty() :
        m_pSetProc  (NULL),
        m_pGetProc  (NULL),
        m_pContainer(NULL)
    {
    }

    CProperty(const CProperty& o)
    {
        m_Value = o.Get();
    }

public:
    void Bind (TContainer* container, GETPROC getproc, SETPROC setproc)
    {
        m_pContainer = container;
        m_pGetProc   = getproc;
        m_pSetProc   = setproc;
    }

    CProperty<TContainer,TValue> operator = (const CProperty& rhs)
    {
        Set(rhs.Get());
    
        return *this;
    }

    TValue Get (void) const
    {
        ATLASSERT(m_pContainer != NULL);
        ATLASSERT(m_pGetProc   != NULL);

        return (m_pContainer->*m_pGetProc)();
    }

    TValue Set (const TValue& value)
    {
        ATLASSERT(m_pContainer != NULL);
        ATLASSERT(m_pSetProc   != NULL);

        return (m_pContainer->*m_pSetProc)(value);    
    }

    operator TValue (void) const
    {
        return Get ();
    }

    TValue operator = (const TValue& value)
    {
        return Set (value);
    }
};

/////////////////////////////////////////////////////////////////////////////
//
// Interface of the CProperties class
//
/////////////////////////////////////////////////////////////////////////////
class CProperties
{
private:
    int m_Count;

public:
    CProperty<CProperties,int> Count;

public:
    CProperties () : m_Count(0)
    {
        Count.Bind (this, &CProperties::get_Count, &CProperties::set_Count);
    }

public:
    int get_Count (void) const
    {
        printf ("\t\t%08x::get_Count()=%d\r\n", this, m_Count);

        return m_Count;
    }

    int set_Count (int n)
    {
        m_Count = n;

        printf ("\t\t%08x::set_Count(%d)\r\n", this, m_Count);

        return m_Count;
    }
};

/////////////////////////////////////////////////////////////////////////////
//
// Test
//
/////////////////////////////////////////////////////////////////////////////
static int Test (void)
{
    CProperties prop;
    
    prop.Count = 100;

    return prop.Count;
}

/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
    CProperties Properties1, Properties2;

    printf ("\t\tProperties1=%08x\r\n", &Properties1);
    printf ("\t\tProperties2=%08x\r\n", &Properties2);

    printf ("-------------------------------------------------------------\r\n");

    printf ("Test()=%d\r\n", Test());

    printf ("-------------------------------------------------------------\r\n");

    Properties1.Count = 200;

    Properties2.Count = Properties1.Count;

    Properties1.Count = 100;

    std::cout << "Properties1.Count=" <<Properties1.Count << std::endl;
    std::cout << "Properties2.Count=" <<Properties2.Count << std::endl;

    printf ("-------------------------------------------------------------\r\n");

    int n=Properties2.Count;

    printf ("printf() n     =%d\r\n",n);
    printf ("printf() cast  =%d\r\n",(int)Properties2.Count);
    printf ("printf() nocast=%d\r\n",Properties2.Count); // 방법없음

    return 0;
}

Posted by 셈말짓기 :

cpp2html

2009. 1. 29. 09:05 from 셈말짓기/터놓은글


아래와 같이 명령을 하면 도움말을 볼 수가 있습니다.

E:\>cpp2html.exe -h

  ***I tweeked the original source code to get it to compile  on
 Windows 2000.  The original source code requires Cygnus.dll. This
 version does not.  The original Credits and Authors are down below.
 You can get the source code from http://www.gnu.org

                                         - mdevi@liu.edu
       *************************************
 Usage
cpp2html only does a lexical analisys of the source code, so the
C++ program is assumed to be correct !
here's how to run it:

cpp2html --input <file (a C++ prog)> --output <file (an html)>
If you do not specify the name of the output file, the name will
be the one of the source file with a .html appended.
if you want a real html document, specify --doc option at the
end.Otherwise you just get some text to copy and paste in you
own html pages. If you choose -doc option the page will have a
white background and your source file name as title. --tab n option
apply a substitution of tab characters with n spaces. You also may
want to specify the title of the page with --title "my title"
option (this implies -doc). Now you can also generate an html with
CSS format, by using --css "url of .css" (try some .css files
included in the package). The order of the options is not relevant.
Here are some links to some of the sources of cpp2html colored with
cpp2html itself:

main.cc.html
generators.cc.html
tags.cc.html
messages.cc.html
These files have been generated with the following commands:
cpp2html --doc main.cc
cpp2html --doc generators.cc
cpp2html --doc tags.cc
cpp2html --doc messages.cc
Obviosly it works with C files as well:
cmdline.c.html
Created with the command:
cpp2html -i cmdline.c -o cmdline.c.html --css="cpp2html.css"
And obviously it works with header files as well (which we colored in
black and white :-)
main.h.html
decorators.h.html
generators.h.html
list.h.html
tags.h.html
cmdline.h.html
created with the command:
cpp2html *.h --css="mono.css"
And here's the output of `cpp2html -help`

Usage: cpp2html [OPTION]... [INPUT-FILE]...
       cpp2html < INPUT-FILE > OUTPUT-FILE [OPTION]...

given a source C/C++ file, produces an html source with syntax highlighting.

  -v, --verbose           verbose mode on
  -d, --doc               creates html with title, header...
  -c, --css=URL           use a css for formatting (implies --doc)
  -T, --title=TITLE       give title to the html (implies --doc)
  -i, --input=FILE        input file (default standard input)
  -o, --output=FILE       output file (default standard output)
  -t, --tab=TABLEN        specify tab length (default 8)
  -V, --version           print version
As it handles standard output and input you may also run it like
cat MyFile.cpp | cpp2html | lpr
You may want to specify your options for syntax highlighting in the file
tags.j2h. If this file is not present in the current directory, some
default colors will be used. Here's the tags.j2h file that comes with
this distribution:

keyword blue b ;
type green ;
string red ;
comment brown i ;
number purple ;
as you might see the syntax of this file is quite straightforward:
b = bold
i = italics
u = underline

You may also specify more than on of these options separated by commas
e.g.
keyword blue u, b ;
you may see all possible colors in the file colors.html

if something goes wrong with your options try to run cpp2html with --verbose opt
ion enabled.

Credits
These people helped me with java2html, and I used such features in cpp2html
as well, so:
Marcus G. Daniels <marcusd@gnu.org> who gave me some good advices about GNU stan
dards,
Osvaldo Pinali Doederlein <osvaldo@visionnaire.com.br> for tab option idea,
Richard Freedman <rich_freedman@chiinc.com> for feed back and bugs signalations

John Constantine <John.Constantine@mail.cc.trincoll.edu> for some great suggesti
ons I'll surely apply.
Raymond Lambe <rlambe@morgan.ucs.mun.ca>, for quotation bug signalation
Robert J. Clark <clark@klgroup.com> for adding -input, -output, -title options
Hans-Peter Bischof <hpb@cs.rit.edu> for suggestions (to apply).
Luc Maisonobe <Luc.Maisonobe@cnes.fr> for the patch for const char * in order to
 make it work under gcc 2.95
Jari Korva <jari.korva@iki.fi> for the bug of " inside a string and & treatme nt
, and especially for adding CSS options and handling
Kaloian Doganov <kaloian@stones.com> for .css suggestion and for providing some
nice .css files
Ziv Caspi <zivc@peach-networks.com> found the bug of \ in chars
Chris Mason <cjmaso@essex.ac.uk> found the darkgreen bug, and that --tab was not
 documented


                                  ****  Have Fun - mdevi@liu.edu

E:\>

Posted by 셈말짓기 :
색상에 이름을 표시 해주는 셈글

ColorTable.zip



색상의 이름 이나 색상의 RGB값을 Double-Click하면 해당 문자가 Clipboard로 복사됩니다.

첨부 File에는 WTL기반으로 된 Source Code와 Program이 있습니다.


Posted by 셈말짓기 :

#include <stdio.h>
#include <tchar.h>

///////////////////////////////////////////////////////////////////////////////
struct Operand1
{
    int GetOp1()
    {
        return 2;
    }

    int GetOp2()
    {
        return 3;
    }
};

struct Operand2
{
    int GetOp1()
    {
        return 3;
    }

    int GetOp2()
    {
        return 4;
    }
};

///////////////////////////////////////////////////////////////////////////////
template<class T> 
struct CalcEngine1
{
    int Calc(void)
    {
        T* pThis= (T*)this;
        return pThis->GetOp1() / pThis->GetOp2();
    }
};

template<class T> 
struct CalcEngine2
{
    double Calc(void)
    {
        T* pThis= (T*)this;
        return pThis->GetOp1() / (double) pThis->GetOp2();
    }
};

///////////////////////////////////////////////////////////////////////////////
template
<
    class                            OperandPolicy,
    template<class CalcEngine> class CalcEnginePolicy
>
class Calculator : 
    public OperandPolicy,
    public CalcEnginePolicy<OperandPolicy>
{
public:
    void Show (void)
    {
        printf ("Show()=%f\r\n", CalcEnginePolicy<OperandPolicy>::Calc() );
    }
};

///////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
    Calculator <Operand1,CalcEngine1> a;
    Calculator <Operand1,CalcEngine2> b;
    Calculator <Operand2,CalcEngine1> c;
    Calculator <Operand2,CalcEngine2> d;

    a.Show();
    b.Show();
    c.Show();
    d.Show();

    return 0;
}

Posted by 셈말짓기 :

// MetaProgramming.cpp : Defines the entry point for the console application.
//

#include <stdio.h>
#include <tchar.h>

template <unsigned long N>
struct binary
{
    static unsigned const value =
        binary<N/10>::value*2 + N%10;
};

template <>
struct binary<0>
{
    static unsigned const value = 0;
};

int _tmain(int argc, _TCHAR* argv[])
{
    unsigned const one   = binary<   1>::value;
    unsigned const two   = binary<  10>::value;
    unsigned const three = binary<  11>::value;
    unsigned const four  = binary< 100>::value;
    unsigned const seven = binary< 111>::value;
    unsigned const nine  = binary<1001>::value;

    printf (" one   =%d\n", one  );
    printf (" two   =%d\n", two  );
    printf (" three =%d\n", three);
    printf (" four  =%d\n", four );
    printf (" seven =%d\n", seven);
    printf (" nine  =%d\n", nine );

    return 0;
}
Posted by 셈말짓기 :

ZLib

2009. 1. 7. 09:32 from 셈말짓기/터놓은글

- 첨부파일 내용
  1. ZLib123 (http://www.zlib.net/)
  2. WCE ARMV4I, W32 x86 Lib
  3. VS2005 Project

- Memory 압축/해제 주요 함수
ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
                                 const Bytef *source, uLong sourceLen));
/*
     Compresses the source buffer into the destination buffer.  sourceLen is
   the byte length of the source buffer. Upon entry, destLen is the total
   size of the destination buffer, which must be at least the value returned
   by compressBound(sourceLen). Upon exit, destLen is the actual size of the
   compressed buffer.
     This function can be used to compress a whole file at once if the
   input file is mmap'ed.
     compress returns Z_OK if success, Z_MEM_ERROR if there was not
   enough memory, Z_BUF_ERROR if there was not enough room in the output
   buffer.
*/

ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
                                   const Bytef *source, uLong sourceLen));
/*
     Decompresses the source buffer into the destination buffer.  sourceLen is
   the byte length of the source buffer. Upon entry, destLen is the total
   size of the destination buffer, which must be large enough to hold the
   entire uncompressed data. (The size of the uncompressed data must have
   been saved previously by the compressor and transmitted to the decompressor
   by some mechanism outside the scope of this compression library.)
   Upon exit, destLen is the actual size of the compressed buffer.
     This function can be used to decompress a whole file at once if the
   input file is mmap'ed.

     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
   enough memory, Z_BUF_ERROR if there was not enough room in the output
   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
*/

Posted by 셈말짓기 :

ASCII Table

2009. 1. 6. 17:52 from 셈말짓기/헤아림

ASCII - 1

10진수

16진수

ASCII

10진수

16진수

ASCII

10진수

16진수

ASCII

10진수

16진수

ASCII

0

0x00

NULL

32

0x20

SP

64

0x40

@

96

0x60

.

1

0x01

SOH

33

0x21

!

65

0x41

A

97

0x61

a

2

0x02

STX

34

0x22

"

66

0x42

B

98

0x62

b

3

0x03

ETX

35

0x23

#

67

0x43

C

99

0x63

c

4

0x04

EOT

36

0x24

$

68

0x44

D

100

0x64

d

5

0x05

ENQ

37

0x25

%

69

0x45

E

101

0x65

e

6

0x06

ACK

38

0x26

&

70

0x46

F

102

0x66

f

7

0x07

BEL

39

0x27

'

71

0x47

G

103

0x67

g

8

0x08

BS

40

0x28

(

72

0x48

H

104

0x68

h

9

0x09

HT

41

0x29

)

73

0x49

I

105

0x69

i

10

0x0A

LF

42

0x2A

*

74

0x4A

J

106

0x6A

j

11

0x0B

VT

43

0x2B

+

75

0x4B

K

107

0x6B

k

12

0x0C

FF

44

0x2C

'

76

0x4C

L

108

0x6C

l

13

0x0D

CR

45

0x2D

-

77

0x4D

M

109

0x6D

m

14

0x0E

SO

46

0x2E

.

78

0x4E

N

110

0x6E

n

15

0x0F

SI

47

0x2F

/

79

0x4F

O

111

0x6F

o

16

0x10

DLE

48

0x30

0

80

0x50

P

112

0x70

p

17

0x11

DC1

49

0x31

1

81

0x51

Q

113

0x71

q

18

0x12

SC2

50

0x32

2

82

0x52

R

114

0x72

r

19

0x13

SC3

51

0x33

3

83

0x53

S

115

0x73

s

20

0x14

SC4

52

0x34

4

84

0x54

T

116

0x74

t

21

0x15

NAK

53

0x35

5

85

0x55

U

117

0x75

u

22

0x16

SYN

54

0x36

6

86

0x56

V

118

0x76

v

23

0x17

ETB

55

0x37

7

87

0x57

W

119

0x77

w

24

0x18

CAN

56

0x38

8

88

0x58

X

120

0x78

x

25

0x19

EM

57

0x39

9

89

0x59

Y

121

0x79

y

26

0x1A

SUB

58

0x3A

:

90

0x5A

Z

122

0x7A

z

27

0x1B

ESC

59

0x3B

;

91

0x5B

[

123

0x7B

{

28

0x1C

FS

60

0x3C

< 

92

0x5C

\

124

0x7C

|

29

0x1D

GS

61

0x3D

=

93

0x5D

]

125

0x7D

}

30

0x1E

RS

62

0x3E

> 

94

0x5E

^

126

0x7E

~

31

0x1F

US

63

0x3F

?

95

0x5F

_

127

0x7F

DEL

 

ASCII - 2

 10진수

16진수

ASCII

10진수

16진수

ASCII

 10진수

16진수

ASCII

10진수

16진수

ASCII

128

0x80

?

160

0xA0

192

0xC0

À

224

0xE0

à

129

0x81

?

161

0xA1

¡

193

0xC1

Á

225

0xE1

á

130

0x82

?

162

0xA2

194

0xC2

Â

226

0xE2

â

131

0x83

?

163

0xA3

195

0xC3

Ã

227

0xE3

ã

132

0x84

?

164

0xA4

¤

196

0xC4

Ä

228

0xE4

ä

133

0x85

165

0xA5

197

0xC5

Å

229

0xE5

å

134

0x86

166

0xA6

¦

198

0xC6

Æ

230

0xE6

æ

135

0x87

167

0xA7

§

199

0xC7

Ç

231

0xE7

ç

136

0x88

?

168

0xA8

¨

200

0xC8

È

232

0xE8

è

137

0x89

169

0xA9

201

0xC9

É

233

0xE9

é

138

0x8A

?

170

0xAA

ª

202

0xCA

Ê

234

0xEA

ê

139

0x8B

?

171

0xAB

203

0xCB

Ë

235

0xEB

ë

140

0x8C

Œ

172

0xAC

204

0xCC

Ì

236

0xEC

ì

141

0x8D

?

173

0xAD

­

205

0xCD

Í

237

0xED

í

142

0x8E

?

174

0xAE

®

206

0xCE

Î

238

0xEE

î

143

0x8F

?

175

0xAF

¯

207

0xCF

Ï

239

0xEF

ï

144

0x90

?

176

0xB0

°

208

0xD0

Ð

240

0xF0

ð

145

0x91

177

0xB1

±

209

0xD1

Ñ

241

0xF1

ñ

146

0x92

178

0xB2

²

210

0xD2

Ò

242

0xF2

ò

147

0x93

179

0xB3

³

211

0xD3

Ó

243

0xF3

ó

148

0x94

180

0xB4

´

212

0xD4

Ô

244

0xF4

ô

149

0x95

?

181

0xB5

μ

213

0xD5

Õ

245

0xF5

õ

150

0x96

?

182

0xB6

214

0xD6

Ö

246

0xF6

ö

151

0x97

?

183

0xB7

·

215

0xD7

×

247

0xF7

÷

152

0x98

?

184

0xB8

¸

216

0xD8

Ø

248

0xF8

ø

153

0x99

185

0xB9

¹

217

0xD9

Ù

249

0xF9

ù

154

0x9A

?

186

0xBA

º

218

0xDA

Ú

250

0xFA

ú

155

0x9B

?

187

0xBB

219

0xDB

Û

251

0xFB

û

156

0x9C

œ

188

0xBC

¼

220

0xDC

Ü

252

0xFC

ü

157

0x9D

?

189

0xBD

½

221

0xDD

Ý

253

0xFD

ý

158

0x9E

?

190

0xBE

¾

222

0xDE

Þ

254

0xFE

þ

159

0x9F

?

191

0xBF

¿

223

0xDF

ß

255

0xFF

ÿ

 

 

SOH - start of heading

 STX - start of text

 ETX - end of text

 EOT - end of transmission

 ENQ - enquiry

 ACK - acknowledge

 BEL - bell

 BS  - backspac

HT  - horizontal tab

 LF  - NL line feed, new line

 VT  - vertical tab

FF  - NP form feed, new page

 CR  - carriage return

 SO  - shift out

 SI  - shift in

 DLE - data link escape

 DC1 - device control 1

 DC2 - device control 2

 DC3 - device control 3

 DC4 - device control 4

NAK - negative acknowledge

 SYN - synchronous idle

 ETB - end of trans. block

 CAN - cancel

 EM  - end of medium

 SUB - substitute

 ESC - escape

 FS  - file separator

 GS  - group separator

 RS  - record separator

 US  - unit separator

 

Posted by 셈말짓기 :
Posted by 셈말짓기 :



위의 레지스트리 파일을 추가하면된다.

내용은 아래와 같다.

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

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\Text Editor]
"Guides"="RGB(204,204,204) 77"

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

77컬럼이외에 더 추가하려면 아래와 같이 추가하면된다.
"Guides"="RGB(204,204,204) 4 77 79"

원본:
http://minjang.egloos.com/2055072

Posted by 셈말짓기 :
[0000 0000 ~ 0000 03ff] WM_NULL, WM_CREATE, ...   : Messages reserved for use by the system.
[0000 0400 ~ 0000 07ff] WM_USER ~ WM_USER+0x03ff : Integer messages for use by private window classes.
[0000 0800 ~ 0000 bfff] WM_APP  ~ WM_APP +0x03ff : Messages available for use by applications
[0000 c000 ~ 0000 ffff] RegisterWindowMessage()  : String messages for use by applications.
[0001 0000 ~ ffff ffff] Reserved by the system.



WM_USER
WM_APP 
WM_reg 
WM_sys 

Posted by 셈말짓기 :

PostThreadMessage()를 이용한 쓰레드에 메세지 전송

● 알아두어야 할 사항
1. 윈도우 OS시스템에서는 자동적으로(GetMessage()호출시?) 메세지 큐를 각각 쓰레드마다 생성한다.
2. Posted Message를 위한 메세지 큐의 크기는 Windows 2000이나 XP인경우
   10000이다. (최소 값: 4000) 이 값은 아래 윈도우즈 레지스트리에
   HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Windows/
     USERPostMessageLimit
   정의 한다.
3. PostThreadMessage()로 보내어지는 메세지는 윈도우와 관련이 없다.


● 결론
1. 간단한 메세지만 전송받아 처리 하는 쓰레드인 경우는 큐만든다고 삽질하지 말자.
2. 기본에 충실하자.
3. 옛날에 삽질한게 억울하다.

// --------------------------------------------------------------------------
//  예제
// --------------------------------------------------------------------------
CAppModule _Module;

DWORD WINAPI BackgroundThread (LPVOID param)
{
 MSG msg;

 while (GetMessage(&msg, NULL, 0, 0))
 {
  ATLTRACE (_T("hwnd    = %x \r\n"),    msg.hwnd    );
  ATLTRACE (_T("message = %x \r\n"),    msg.message );
  ATLTRACE (_T("wParam  = %x \r\n"),    msg.wParam  );
  ATLTRACE (_T("lParam  = %x \r\n"),    msg.lParam  );
  ATLTRACE (_T("time    = %d \r\n"),    msg.time    );
  ATLTRACE (_T("pt      = %d %d \r\n"), msg.pt.x, msg.pt.y);
  ATLTRACE (_T("\r\n"));

  Sleep (1000);

  while (::PeekMessage (&msg, NULL, WM_USER, WM_USER+5, PM_REMOVE));
 }

 ATLTRACE (_T("BackgroundThread(): End \r\n"));

 return msg.wParam;
}

int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWNORMAL)
{
 CMessageLoop theLoop;
 _Module.AddMessageLoop(&theLoop);

 CMainFrame wndMain;

 DWORD  dwThreadId  = 0;
 HANDLE hThread     = CreateThread (NULL, 0, BackgroundThread, NULL, 0, &dwThreadId);
 wndMain.m_ThreadId = dwThreadId;

 if(wndMain.CreateEx() == NULL)
 {
  ATLTRACE(_T("Main window creation failed!\n"));
  return 0;
 }
 
 wndMain.ShowWindow(nCmdShow);

 int nRet = theLoop.Run();

 _Module.RemoveMessageLoop();

 WaitForSingleObject (hThread, INFINITE);
 CloseHandle (hThread);

 return nRet;
}
// --------------------------------------------------------------------------

LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
 ...
 SetTimer (1, 10);

 return 0;
}

LRESULT CMainFrame::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
 bHandled = FALSE;
 KillTimer (1);
 PostThreadMessage (m_ThreadId, WM_QUIT, 0, 0);

 return 0;
}

LRESULT CMainFrame::OnTimer (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
 static int i = 0;

 PostThreadMessage (m_ThreadId, WM_USER+(++i%5), 1, 2);

 return 0;
}
// --------------------------------------------------------------------------
// 출력결과
// --------------------------------------------------------------------------
hwnd    = 0
message = 403
wParam  = 1
lParam  = 2
time    = 73702525
pt      = 0 0

hwnd    = 0
message = 400
wParam  = 1
lParam  = 2
time    = 73703559
pt      = 0 0

hwnd    = 0
message = 400
wParam  = 1
lParam  = 2
time    = 73704571
pt      = 0 0

hwnd    = 0
message = 403
wParam  = 1
lParam  = 2
time    = 73705596
pt      = 0 0

hwnd    = 0
message = 403
wParam  = 1
lParam  = 2
time    = 73706642
pt      = 0 0

hwnd    = 0
message = 400
wParam  = 1
lParam  = 2
time    = 73707702
pt      = 0 0

hwnd    = 0
message = 403
wParam  = 1
lParam  = 2
time    = 73708749
pt      = 0 0

hwnd    = 0
message = 400
wParam  = 1
lParam  = 2
time    = 73709776
pt      = 0 0

CMessageLoop::Run - exiting
BackgroundThread(): End
'BackgroundThread' (0x8706cf42) 스레드가 0 (0x0) 코드에서 끝났습니다.
모듈 언로드: commctrl.dll
모듈 언로드: oleaut32.dll
모듈 언로드: ole32.dll
모듈 언로드: rpcrt4.dll
모듈 언로드: lpcrt.dll
'[6702ec62] Test.exe' 프로그램이 1 (0x1) 코드에서 끝났습니다.

 

 

Posted by 셈말짓기 :

 typedef struct _PRIORITY_LEVEL
 {
  int   priority;
  TCHAR name[32];
 } PRIORITY_LEVEL;

 PRIORITY_LEVEL Priority_Levels[] =
 {
  { THREAD_PRIORITY_TIME_CRITICAL , _T("THREAD_PRIORITY_TIME_CRITICAL") },
  { THREAD_PRIORITY_HIGHEST       , _T("THREAD_PRIORITY_HIGHEST      ") },
  { THREAD_PRIORITY_ABOVE_NORMAL  , _T("THREAD_PRIORITY_ABOVE_NORMAL ") },
  { THREAD_PRIORITY_NORMAL        , _T("THREAD_PRIORITY_NORMAL       ") },
  { THREAD_PRIORITY_BELOW_NORMAL  , _T("THREAD_PRIORITY_BELOW_NORMAL ") },
  { THREAD_PRIORITY_LOWEST        , _T("THREAD_PRIORITY_LOWEST       ") },
  { THREAD_PRIORITY_ABOVE_IDLE    , _T("THREAD_PRIORITY_ABOVE_IDLE   ") },
  { THREAD_PRIORITY_IDLE          , _T("THREAD_PRIORITY_IDLE         ") }
 };
 HANDLE Current_Thread = GetCurrentThread();
 int    Current_Priority;
 int    i;

 for (i=0; i<sizeof(Priority_Levels)/sizeof(PRIORITY_LEVEL); i++)
 {
  SetThreadPriority (Current_Thread, Priority_Levels[i].priority);
  Current_Priority = CeGetThreadPriority (Current_Thread);
 
  ATLTRACE (_T("SetThreadPriority(%d:%s) => CeGetThreadPriority()=%d \r\n"),
  Priority_Levels[i].priority,
  Priority_Levels[i].name,
  Current_Priority);

 }
---------------------------------------------------------------------------------------------- SetThreadPriority(0:THREAD_PRIORITY_TIME_CRITICAL) => CeGetThreadPriority()=248
 SetThreadPriority(1:THREAD_PRIORITY_HIGHEST      ) => CeGetThreadPriority()=249
 SetThreadPriority(2:THREAD_PRIORITY_ABOVE_NORMAL ) => CeGetThreadPriority()=250
 SetThreadPriority(3:THREAD_PRIORITY_NORMAL       ) => CeGetThreadPriority()=251
 SetThreadPriority(4:THREAD_PRIORITY_BELOW_NORMAL ) => CeGetThreadPriority()=252
 SetThreadPriority(5:THREAD_PRIORITY_LOWEST       ) => CeGetThreadPriority()=253
 SetThreadPriority(6:THREAD_PRIORITY_ABOVE_IDLE   ) => CeGetThreadPriority()=254
 SetThreadPriority(7:THREAD_PRIORITY_IDLE         ) => CeGetThreadPriority()=255

Posted by 셈말짓기 :

비디오 포맷

2008. 9. 22. 12:20 from 셈말짓기/헤아림

# 아날로그 비디오 포맷
1. Composite : NTSC, PAL
2. S-Video(Y+C)
3. 아날로그 RGB: D-Sub 모니터
4. YPbPr

# 디지털 비디오 포맷
1. CCIR 656 (H/V Sync포함)
2. CCIR 601
2. YCrCb
3. YUV
4. RGB
Posted by 셈말짓기 :

[가수 변환식] (가수 범위= +1.0 > x > -1.0 )

아래 Code에서 xbits는 부호비트를 포함한 값이다.
-----------------------------------------------------------------------------
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include <tchar.h>

DWORD ConvertMantissaToXBits (double value, DWORD xbits=24)
{
 if (xbits>31 || xbits<12)
  return 0;

 static const DWORD MASK[33] =
 {
  /* 00 */ 0x00000000,
  /* 01 */ 0x00000001,/* 02 */ 0x00000003,/* 03 */ 0x00000007,/* 04 */ 0x0000000f,
  /* 05 */ 0x0000001f,/* 06 */ 0x0000003f,/* 07 */ 0x0000007f,/* 08 */ 0x000000ff,
  /* 09 */ 0x000001ff,/* 10 */ 0x000003ff,/* 11 */ 0x000007ff,/* 12 */ 0x00000fff,
  /* 13 */ 0x00001fff,/* 14 */ 0x00003fff,/* 15 */ 0x00007fff,/* 16 */ 0x0000ffff,
  /* 17 */ 0x0001ffff,/* 18 */ 0x0003ffff,/* 19 */ 0x0007ffff,/* 20 */ 0x000fffff,
  /* 21 */ 0x001fffff,/* 22 */ 0x003fffff,/* 23 */ 0x007fffff,/* 24 */ 0x00ffffff,
  /* 25 */ 0x01ffffff,/* 26 */ 0x03ffffff,/* 27 */ 0x07ffffff,/* 28 */ 0x0fffffff,
  /* 29 */ 0x1fffffff,/* 30 */ 0x3fffffff,/* 31 */ 0x7fffffff,/* 32 */ 0xffffffff
 };

 DWORD  result = 0;
 DWORD  h      = 0;
 double m      = 0.0;

 if (value>=1.0 || value<-1.0)
  return MASK[xbits] & (~(1<<(xbits-1)));

 //m = pow (2.0, double(xbits-1)) * value;
 m = (1<<(xbits-1)) * value;
 h = DWORD (m);

 result = h&MASK[xbits];

 return result;
}

double ConvertXBitsToMantissa (DWORD value, DWORD xbits=24)
{
 if (xbits>31 || xbits<12)
  return 0.0;

 double     result  = 0.0;
 signed int n       = 0;

 n = value<<(32-xbits);
 n = n    >>(32-xbits); // no moved signal flag

 //result = n/pow (2.0, double(xbits-1));
 result = double(n)/(1<<(xbits-1));

 return result;
}

int _tmain(int argc, _TCHAR* argv[])
{
 DWORD  bits = 24;
 double v;
 DWORD  h;
 double f;
 int    i;
 double s;

 v = -1;
 s =  0.1;
 for (i=0; i<22; i++)
 {
  h = ConvertMantissaToXBits(v,bits);
  f = ConvertXBitsToMantissa(h,bits);

  printf ("Mant->xBits(%+.3f)= 0x%08x : ",  v, h);
  printf ("xBits->Mant(0x%08x)= %+.3f\r\n", h, f);

  v = v+s;
 }

 return 0;
}
-----------------------------------------------------------------------------
Mant->xBits(-1.000)= 0x00800000 : xBits->Mant(0x00800000)= -1.000
Mant->xBits(-0.900)= 0x008ccccd : xBits->Mant(0x008ccccd)= -0.900
Mant->xBits(-0.800)= 0x0099999a : xBits->Mant(0x0099999a)= -0.800
Mant->xBits(-0.700)= 0x00a66667 : xBits->Mant(0x00a66667)= -0.700
Mant->xBits(-0.600)= 0x00b33334 : xBits->Mant(0x00b33334)= -0.600
Mant->xBits(-0.500)= 0x00c00000 : xBits->Mant(0x00c00000)= -0.500
Mant->xBits(-0.400)= 0x00cccccd : xBits->Mant(0x00cccccd)= -0.400
Mant->xBits(-0.300)= 0x00d9999a : xBits->Mant(0x00d9999a)= -0.300
Mant->xBits(-0.200)= 0x00e66667 : xBits->Mant(0x00e66667)= -0.200
Mant->xBits(-0.100)= 0x00f33334 : xBits->Mant(0x00f33334)= -0.100
Mant->xBits(-0.000)= 0x00000000 : xBits->Mant(0x00000000)= +0.000
Mant->xBits(+0.100)= 0x000ccccc : xBits->Mant(0x000ccccc)= +0.100
Mant->xBits(+0.200)= 0x00199999 : xBits->Mant(0x00199999)= +0.200
Mant->xBits(+0.300)= 0x00266666 : xBits->Mant(0x00266666)= +0.300
Mant->xBits(+0.400)= 0x00333333 : xBits->Mant(0x00333333)= +0.400
Mant->xBits(+0.500)= 0x003fffff : xBits->Mant(0x003fffff)= +0.500
Mant->xBits(+0.600)= 0x004ccccc : xBits->Mant(0x004ccccc)= +0.600
Mant->xBits(+0.700)= 0x00599999 : xBits->Mant(0x00599999)= +0.700
Mant->xBits(+0.800)= 0x00666666 : xBits->Mant(0x00666666)= +0.800
Mant->xBits(+0.900)= 0x00733333 : xBits->Mant(0x00733333)= +0.900
Mant->xBits(+1.000)= 0x007fffff : xBits->Mant(0x007fffff)= +1.000
Mant->xBits(+1.100)= 0x007fffff : xBits->Mant(0x007fffff)= +1.000

Posted by 셈말짓기 :

#include <stdio.h>
#include <tchar.h>
#include <math.h>

#define LENGTH       32
#define SIGN_BIT     31
#define EXPONENT_MSB 30
#define EXPONENT_LSB 23
#define MANTISSA_MSB 22
#define MANTISSA_LSB  0

float hex_to_float (unsigned int value)
{
 int   sign;
 int   exp;
 int   man;
 float result;

 sign = (value & (1 << SIGN_BIT)) != 0;
#pragma warning( push )
#pragma warning( disable : 4307 ) // '-' : integral constant overflow.
 exp  = ((value & ( (2<<EXPONENT_MSB) - (1<<EXPONENT_LSB) )) >> EXPONENT_LSB)
  - (1 << (EXPONENT_MSB - EXPONENT_LSB))
  - (MANTISSA_MSB - MANTISSA_LSB);
#pragma warning( pop )

 man  = ((value & ( (2<<MANTISSA_MSB) - (1<<MANTISSA_LSB) )) >> MANTISSA_LSB)
  + (2 << (MANTISSA_MSB - MANTISSA_LSB));

 result = man * pow((float)2, (float)exp) * (sign ? -1 : 1);

 return result;
}

int _tmain(int argc, _TCHAR* argv[])
{
 union
 {
  unsigned int n;
  float        f;
 } value;

 int   i;
 float f;


 value.f =(float)   0;
 f       =(float)-1.1;

 for (i=0; i<10; i++)
 {
  printf ("%+e=0x%08x:hex_to_float()=%+e \r\n", value.f, value.n, hex_to_float(value.n));
  value.f += f;
 }

 return 0;
}
-----------------------------------------------------------------------------
+0.000000e+000=0x00000000:hex_to_float()=+0.000000e+000
-1.100000e+000=0xbf8ccccd:hex_to_float()=-1.100000e+000
-2.200000e+000=0xc00ccccd:hex_to_float()=-2.200000e+000
-3.300000e+000=0xc0533334:hex_to_float()=-3.300000e+000
-4.400000e+000=0xc08ccccd:hex_to_float()=-4.400000e+000
-5.500000e+000=0xc0b00000:hex_to_float()=-5.500000e+000
-6.600000e+000=0xc0d33333:hex_to_float()=-6.600000e+000
-7.700000e+000=0xc0f66666:hex_to_float()=-7.700000e+000
-8.800000e+000=0xc10ccccd:hex_to_float()=-8.800000e+000
-9.900001e+000=0xc11e6667:hex_to_float()=-9.900001e+000


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

부동소수점 표현의 국제표준은 IEEE 754입니다.

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

< float >
C의 float타입은 IEEE 754의 single precision 플로팅포인트를 구현한 것으로,
다음과 같은 포맷을 가집니다.
sign : bit31 (1비트)
exponent : bit30~bit23 (8비트)
mantissa : bit22~bit0 (23비트)

이때, 가수부(만티사)는 정수부분을 1로 정규화한 2진소수표현이며, 지수부(exponent)는
원래 지수에 바이어스 127을 더한 값입니다.
부호비트는 0이면 양수, 1이면 음수입니다.

가수부의 23비트가 100 0000 0000 0000 0000 0000 이라면, 이때 이 부동소수의 가수는
2진소수로 1.1이 되어, 10진법으로는 1 + 1/2 = 1.5가 됩니다.

지수부의 표현이 1000 0000 이라면, 이 값은 바이어스 127, 즉 111 1111이 더해진 수
이므로 실제 지수는 128 - 127 = 1이 됩니다.

따라서, 0 100 0000 100 0000 0000 0000 0000 0000 으로 표현되는 부동소수는
따라서, [0] [100 0000 0] [100 0000 0000 0000 0000 0000] 으로 표현되는 부동소수는
1.5 * 2^1 = 3.0 을 표현하게 됩니다.

single precision의 유효숫자는 가수의 비트길이 (정수부분 포함)24에 의해 결정되며,
2^24 은 약 10^7.2 이므로, 유효숫자는 약 7자리가 됩니다.

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

< double >
C의 double타입은 IEEE 754의 double precision 플로팅포인트를 구현한 것으로,
다음과 같은 포맷을 가집니다.
sign : bit63 (1비트)
exponent : bit62~bit52 (11비트)
mantissa : bit51~bit0 (52비트)

이때, single precision과는 지수부의 바이어스가 1023이라는 것만 다르고, 나머지
표현방법은 동일합니다.

double precision의 유효숫자 역시 정수부분을 포함한 가수의 비트길이 53에 의해 결정되며,
2^53 은 약 10^15.9 이므로, 유효숫자는 약 약 15자리가 됩니다.

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

< 예외 정의 >
1. 플로팅포인트 표현에서 모든 비트가 0인 수는 0으로 정의합니다.
2. 지수부의 모든 비트가 0인 수는 가수의 정수부분을 0으로 계산합니다.
3. 지수부의 모든 비트가 1이고, 가수부의 모든 비트가 0이면 무한대로 정의합니다.
4. 지수부의 모든 비트가 1이고, 가수부가 0이 아니면 NaN (Not a Number)로 정의하여
   예외를 발생하게 됩니다.


Posted by 셈말짓기 :
2008/08/04~2008/08/25

GoF's Design Patterns를 다시 공부하면서 그 동안 만들어 놓은 Sample들이다.

UML로 표시된 구조를 가급적 맞추려고 노력해서 실제 Pattern들이 의미하는 바를 표현하기에는 역부족이다.

Sample Code를 보면서 구조는 쉽게 이해는 할 수 있을지 몰라도 Pattern들의 실제적인 의미나 사용을 하기
위해서는 책을 참고하는 것이 도움이 될 것 이다.


Posted by 셈말짓기 :

행위패턴-Interpreter

2008. 8. 25. 16:32 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Interpreter]
의도:
어떤 언어는 문법에 대한 표현을 정의하면서 그 언어로 기술된 문장을 해석하는 기법을 표현하기
위해서 인터프리터도 함께 정의하는 경우가 있다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Interpreter
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <string>
#include <list>
#include <deque>
#include <vector>
#include <map>
#include <iostream>


/////////////////////////////////////////////////////////////////////////////
//
// Interpreter
//
//
/////////////////////////////////////////////////////////////////////////////
class Context
{
public:
 std::map<std::string, bool> Variables_;
};

class AbstractExpression
{    
public:
 virtual bool Interpret(Context&) = 0;
};

class TerminalExpression_Variable: public AbstractExpression
{    
public:
 explicit TerminalExpression_Variable (std::string n) : Name_(n)
 {
 }

public:
 virtual bool Interpret(Context& context)
 {   
  return context.Variables_[Name_];
 }

private:
 std::string Name_;
};

class NonterminalExpression_And: public AbstractExpression
{
public:
 NonterminalExpression_And (AbstractExpression* p1, AbstractExpression* p2) :
  Operand1_(p1),
  Operand2_(p2)
 {
 }

public:
 virtual bool Interpret(Context& context)
 {
  return Operand1_->Interpret(context) && Operand2_->Interpret(context);
 }

private:
 AbstractExpression* Operand1_;
 AbstractExpression* Operand2_;
};

class NonterminalExpression_Or: public AbstractExpression
{
public:
 NonterminalExpression_Or (AbstractExpression* p1, AbstractExpression* p2) :
  Operand1_(p1),
  Operand2_(p2)
 {
 }

public:
 virtual bool Interpret(Context& context)
 {
  return Operand1_->Interpret(context) || Operand2_->Interpret(context);
 }

private:
 AbstractExpression* Operand1_;
 AbstractExpression* Operand2_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
bool _tmain(bool argc, _TCHAR* argv[])
{
 Context context;

 context.Variables_["A"] = 1;
 context.Variables_["B"] = 1;
 context.Variables_["C"] = 0;


 TerminalExpression_Variable a("A");
 TerminalExpression_Variable b("B");
 TerminalExpression_Variable c("C");


 NonterminalExpression_Or  exp1 (&a,    &b);
 NonterminalExpression_And exp2 (&exp1, &c);


 bool result = exp2.Interpret(context);

 std::cout << "result=" << result << std::endl;

 return 0;
};
-----------------------------------------------------------------------------
result=0

Posted by 셈말짓기 :

생성패턴-Singleton

2008. 8. 23. 19:22 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Singleton]
의도:
클래스에서 만들 수 있는 인스턴스가 오직 하나일 경우에 이에 대한 접근은 어디에서든지
하나로만 통일하여 제공한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A creational part of GoF's Design Patterns
//
// - Singleton
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Singleton
//
//
/////////////////////////////////////////////////////////////////////////////
class Singleton
{
protected:
 Singleton () {}
public:
 virtual ~Singleton() {}

public:
 static Singleton& Instance(void)
 {
  if (Instance_.get() == 0)
  {
   Instance_.reset( new Singleton() );
  }

  return *Instance_;
 }

private:
 static std::auto_ptr<Singleton> Instance_;

public:
 void Operation (void)
 {
  std::cout << "Singleton::Operation()" << std::endl;
 }
};

std::auto_ptr<Singleton> Singleton::Instance_;


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Singleton::Instance().Operation();

 return 0;
}
-----------------------------------------------------------------------------
Singleton::Operation()

Posted by 셈말짓기 :

생성패턴-Prototype

2008. 8. 23. 18:52 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Prototype]
의도:
견본적(prototypical) 인스턴스를 사용하여 생성할 객체의 종류를 명시하고 이렇게 만들어진
견본을 복사해서 새로운 객체를 생성한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A creational part of GoF's Design Patterns
//
// - Prototype
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>



/////////////////////////////////////////////////////////////////////////////
//
// Prototype
//
//
/////////////////////////////////////////////////////////////////////////////
class Product
{
public:
 Product()          {}
 virtual ~Product() {}

public:
 virtual Product* Clone (void) = 0;
 virtual void     Show  (void) = 0;
};

class ConcreteProductA : public Product
{
public:
 explicit ConcreteProductA(int v) : Value_(v) {}
 virtual ~ConcreteProductA() {}

public:
 virtual Product* Clone (void)
 {
  return new ConcreteProductA(Value_);
 }
 virtual void Show (void)
 {
  std::cout << "ConcreteProductA::Show(): " << Value_ << std::endl;
 }

private:
 int Value_;
};

class ConcreteProductB : public Product
{
public:
 explicit ConcreteProductB(int v) : Value_(v) {}
 virtual ~ConcreteProductB() {}

public:
 virtual Product* Clone (void)
 {
  return new ConcreteProductB(Value_);
 }
 virtual void Show (void)
 {
  std::cout << "ConcreteProductB::Show(): " << Value_ << std::endl;
 }

private:
 int Value_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Factory
//
//
/////////////////////////////////////////////////////////////////////////////
class ProductFactory
{
public:
 ProductFactory()
 {
  ProductA_.reset ( new ConcreteProductA(100) );
  ProductB_.reset ( new ConcreteProductB(200) );
 }

public:
 Product* CreateA (void)
 {
  return ProductA_->Clone();
 }

 Product* CreateB (void)
 {
  return ProductB_->Clone();
 }

private:
 std::auto_ptr<Product> ProductA_;
 std::auto_ptr<Product> ProductB_;
};
 


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 std::auto_ptr<Product>  p;
 ProductFactory          f;


 p.reset ( f.CreateA() );
 p->Show();

 std::cout << std::endl;

 p.reset ( f.CreateB() );
 p->Show();
 
 return 0;
}
-----------------------------------------------------------------------------
ConcreteProductA::Show(): 100

ConcreteProductB::Show(): 200

Posted by 셈말짓기 :

-----------------------------------------------------------------------------
[Factory Method]
의도:
객체를 생성하기 위해 인터페이스를 정의하지만, 어떤 클래스의 인스턴스를 생성할지에 대한
결정은 서브클래스에서 이루어지도록 Factory Method 패턴은 서브클래스에게 인스턴스 생성의
책임을 미룬다.

다른 이름:
Virtual Constructor
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A creational part of GoF's Design Patterns
//
// - Factory Method
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Product
//
//
/////////////////////////////////////////////////////////////////////////////
class Product
{
public:
 Product()          {}
 virtual ~Product() {}

public:
 virtual void Operation (void) = 0;
};

class ConcreteProductA : public Product
{
public:
 ConcreteProductA(){}
 virtual ~ConcreteProductA() {}

public:
 virtual void Operation (void)
 {
  std::cout << "ConcreteProductA::Operation()" << std::endl;
 }
};

class ConcreteProductB : public Product
{
public:
 ConcreteProductB(){}
 virtual ~ConcreteProductB() {}

public:
 virtual void Operation (void)
 {
  std::cout << "ConcreteProductB::Operation()" << std::endl;
 }
};

class ConcreteProductB_2 : public Product
{
public:
 ConcreteProductB_2(){}
 virtual ~ConcreteProductB_2() {}

public:
 virtual void Operation (void)
 {
  std::cout << "ConcreteProductB_2::Operation()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Factory Method
//
//
/////////////////////////////////////////////////////////////////////////////
enum ProductID
{
 Id_ConcreteProductA,
 Id_ConcreteProductB
};

class Createor
{
public:
 virtual ~Createor() {}

public:
 virtual std::auto_ptr<Product> Create (ProductID id)
 {
  if (Id_ConcreteProductA==id)
   return std::auto_ptr<Product> ( new ConcreteProductA() );

  if (Id_ConcreteProductB==id)
   return std::auto_ptr<Product> ( new ConcreteProductB() );

  return std::auto_ptr<Product>();
 }
};

class ConcreteCreateor : public Createor
{
public:
 virtual std::auto_ptr<Product> Create (ProductID id)
 {
  if (Id_ConcreteProductB==id)
   return std::auto_ptr<Product> ( new ConcreteProductB_2() );

  return Createor::Create(id);
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 std::auto_ptr<Createor> c;
 std::auto_ptr<Product>  p;


 std::cout << "Created by Createor()" << std::endl;
 c.reset ( new Createor() );

 p = c->Create ( Id_ConcreteProductA );
 p->Operation ();

 p = c->Create ( Id_ConcreteProductB );
 p->Operation ();
 std::cout << std::endl;


 std::cout << "Created by ConcreteCreateor()" << std::endl;
 c.reset ( new ConcreteCreateor() );

 p = c->Create ( Id_ConcreteProductA );
 p->Operation ();

 p = c->Create ( Id_ConcreteProductB );
 p->Operation ();
 std::cout << std::endl;

 return 0;
}
-----------------------------------------------------------------------------
Created by Createor()
ConcreteProductA::Operation()
ConcreteProductB::Operation()

Created by ConcreteCreateor()
ConcreteProductA::Operation()
ConcreteProductB_2::Operation()



Posted by 셈말짓기 :

#include <windows.h>
#include <tchar.h>


#include <iostream>
#include <memory>

class o_1
{
public:
 o_1 () : a_ (0) { std::cout << "o_1()"  << std::endl; }
 virtual ~o_1( ) { std::cout << "~o_1()" << std::endl; }
public:
 virtual void show (void)
 {
  std::cout << "o_1::show("<< a_ <<")" << std::endl;
 }
public:
 int a_;
};

class o_2 : public o_1
{
public:
 o_2 () : o_1(), b_(0) { std::cout << "o_2()"  << std::endl; }
 virtual ~o_2()        { std::cout << "~o_2()" << std::endl; }
public:
 virtual void show (void)
 {
  std::cout << "o_2::show("<< b_ <<")" << std::endl;
 }
public:
 int b_;
};

class o_3 : public o_2
{
public:
 o_3 () : o_2(), c_(0) { std::cout << "o_3()"  << std::endl; }
 virtual ~o_3()        { std::cout << "~o_3()" << std::endl; }
public:
 virtual void show (void)
 {
  std::cout << "o_3::show("<< c_ <<")" << std::endl;
 }
public:
 int c_;
};

unsigned int vftable_of____o_1;
unsigned int vftable_of____o_2;
unsigned int vftable_of____o_3;

unsigned int get__vfp  (void* p)
{
 unsigned int __vfp = 0;

 memcpy (&__vfp, p, 4);

 return __vfp;
}

#pragma warning( push )
#pragma warning( disable: 4313 )
// C4313: 'printf' : '%x' in format string conflicts with argument 1 of type 'xxx'

void init (void)
{
 o_1 *o1=new o_1();
 o_2  o2;
 o_3 *o3=new o_3();

 memcpy (&vftable_of____o_1,  o1, 4);
 memcpy (&vftable_of____o_2, &o2, 4);
 memcpy (&vftable_of____o_3,  o3, 4);

 printf (" \r\n");
 printf ("# o_1::vftable_of____o_1=0x%08x \r\n", vftable_of____o_1);
 printf ("# o_2::vftable_of____o_2=0x%08x \r\n", vftable_of____o_2);
 printf ("# o_3::vftable_of____o_3=0x%08x \r\n", vftable_of____o_3);
 printf (" \r\n");

 delete o1;
 delete o3;
}

void test (void)
{
 o_3 *o = new o_3();
 o_1 *p = o;

 o->a_ = 100;
 o->b_ = 200;
 o->c_ = 300;

 printf (" p    's address=0x%08x \r\n", p);
 printf (" p->a_'s address=0x%08x \r\n", &o->a_);
 printf (" p->b_'s address=0x%08x \r\n", &o->b_);
 printf (" p->c_'s address=0x%08x \r\n", &o->c_);
 p->show ();

 printf (" \r\n");
 printf ("# p's __vfp 0x%08x \r\n", get__vfp(p));
 printf (" \r\n");
 printf ("# p->~o_1() \r\n");
 p->~o_1();
 printf (" \r\n");
 printf ("# p's __vfp 0x%08x \r\n", get__vfp(p));
 printf (" \r\n");
 p->show ();

 printf (" \r\n");
 printf ("# let's get fun! \r\n");
 memcpy (p, &vftable_of____o_3, 4); p->show ();
 memcpy (p, &vftable_of____o_2, 4); p->show ();
 memcpy (p, &vftable_of____o_1, 4); p->show ();


 int   v;
 char *member_variable_ptr;

 member_variable_ptr = (char*)p;

 v = 99;
 member_variable_ptr += 4;
 printf (" \r\n");
 printf ("# one more time! (member_variable_ptr=0x%08x) \r\n", member_variable_ptr);
 memcpy (member_variable_ptr, &v, 4);
 memcpy (p, &vftable_of____o_3, 4); p->show ();
 memcpy (p, &vftable_of____o_2, 4); p->show ();
 memcpy (p, &vftable_of____o_1, 4); p->show ();

 v = 98;
 member_variable_ptr+= 4;
 printf (" \r\n");
 printf ("# one more time! (member_variable_ptr=0x%08x) \r\n", member_variable_ptr);
 memcpy (member_variable_ptr, &v, 4);
 memcpy (p, &vftable_of____o_3, 4); p->show ();
 memcpy (p, &vftable_of____o_2, 4); p->show ();
 memcpy (p, &vftable_of____o_1, 4); p->show ();

 v = 97;
 member_variable_ptr+= 4;
 printf (" \r\n");
 printf ("# one more time! (member_variable_ptr=0x%08x) \r\n", member_variable_ptr);
 memcpy (member_variable_ptr, &v, 4);
 memcpy (p, &vftable_of____o_3, 4); p->show ();
 memcpy (p, &vftable_of____o_2, 4); p->show ();
 memcpy (p, &vftable_of____o_1, 4); p->show ();


 printf (" \r\n");
 printf ("# last time ! \r\n");
 memcpy (p, &vftable_of____o_3, 4);

 delete p;
}

#pragma warning( pop )


int _tmain(int argc, _TCHAR* argv[])
{
 std::cout << "==============================================================" <<std::endl;
 std::cout << "init()" <<std::endl;
 std::cout << "==============================================================" <<std::endl;
 init ();
 std::cout << "==============================================================" <<std::endl;
 std::cout <<std::endl;
 std::cout <<std::endl;
 std::cout <<std::endl;


 std::cout << "==============================================================" <<std::endl;
 std::cout << "test()" <<std::endl;
 std::cout << "==============================================================" <<std::endl;
 test ();
 std::cout << "==============================================================" <<std::endl;
 std::cout <<std::endl;
 std::cout <<std::endl;
 std::cout <<std::endl;

 return 0;
}
-----------------------------------------------------------------------------
==============================================================
init()
==============================================================
o_1()
o_1()
o_2()
o_1()
o_2()
o_3()

# o_1::vftable_of____o_1=0x00418890
# o_2::vftable_of____o_2=0x004188c4
# o_3::vftable_of____o_3=0x004188f4

~o_1()
~o_3()
~o_2()
~o_1()
~o_2()
~o_1()
==============================================================


==============================================================
test()
==============================================================
o_1()
o_2()
o_3()
 p    's address=0x003a6858
 p->a_'s address=0x003a685c
 p->b_'s address=0x003a6860
 p->c_'s address=0x003a6864
o_3::show(300)

# p's __vfp 0x004188f4

# p->~o_1()
~o_3()
~o_2()
~o_1()

# p's __vfp 0x00418890

o_1::show(100)

# let's get fun!
o_3::show(300)
o_2::show(200)
o_1::show(100)

# one more time! (member_variable_ptr=0x003a685c)
o_3::show(300)
o_2::show(200)
o_1::show(99)

# one more time! (member_variable_ptr=0x003a6860)
o_3::show(300)
o_2::show(98)
o_1::show(99)

# one more time! (member_variable_ptr=0x003a6864)
o_3::show(97)
o_2::show(98)
o_1::show(99)

# last time !
~o_3()
~o_2()
~o_1()

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

Posted by 셈말짓기 :

파괴자를 직접 부르면 어떻게 될까?

object o;

o.~object();

궁금해졌다.

-----------------------------------------------------------------------------
#include <windows.h>
#include <tchar.h>

#include <iostream>

class o_1
{
public:
 o_1 ()         { std::cout << "o_1()"  << std::endl; }
 virtual ~o_1() { std::cout << "~o_1()" << std::endl; }
};

class o_2 : public o_1
{
public:
 o_2 () : o_1() { std::cout << "o_2()"  << std::endl; }
 virtual ~o_2() { std::cout << "~o_2()" << std::endl; }
};

class o_3 : public o_2
{
public:
 o_3 () : o_2() { std::cout << "o_3()"  << std::endl; }
 virtual ~o_3() { std::cout << "~o_3()" << std::endl; }
};

void test1 (void)
{
 o_3  o;

 o_1* p = &o;

 std::cout << "-----------" <<std::endl;
 p->~o_1 ();
 std::cout << "-----------" <<std::endl;
}

void test2 (void)
{
 o_1* p = new o_3 ();

 std::cout << "-----------" <<std::endl;
 p->~o_1 ();
 std::cout << "-----------" <<std::endl;

 delete p;
}

void test3 (void)
{
 o_1* p = new o_3 ();

 std::cout << "-----------" <<std::endl;
 //p->~o_1 ();
 std::cout << "-----------" <<std::endl;

 delete p;
}

int _tmain(int argc, _TCHAR* argv[])
{
 std::cout << "###########" <<std::endl;
 test1();
 std::cout << "###########" <<std::endl;
 test2();
 std::cout << "###########" <<std::endl;
 test3();
 std::cout << "###########" <<std::endl;

 return 0;
}
-----------------------------------------------------------------------------
###########
<- test1() 함수: 잘된다...
o_1()
o_2()
o_3()
-----------
~o_3()
~o_2()
~o_1()
-----------
~o_3()
~o_2()
~o_1()
########### <- test2() 함수: 무엇인가 이상하다???
o_1()
o_2()
o_3()
----------- <- p->~o_1 (); 호출 부분... 부모 클래스 파괴자를 호출한다.
~o_3()
~o_2()
~o_1()
----------- <- delete p; 가 이상하다 = _=??? 무엇일까...
~o_1()
########### <- test3() 함수:
o_1()
o_2()
o_3()
-----------
<- //p->~o_1 ();
-----------   
주석처리 했더니 delete p; 가 제대로 동작한다.
~o_3()
~o_2()
~o_1()
###########
계속하려면 아무 키나 누르십시오 . . .
-----------------------------------------------------------------------------
디버깅을 해보았다.

p->~o_1(); 호출하기전 __vfptr(virtual fucntion pointer) 녀석은 이렇게 가리키고 있었다.

사용자 삽입 이미지

하지만, p->~o_1();을 호출하니 __vfptr 녀석은 이렇게 바뀌어 버렸다.
사용자 삽입 이미지

         test1()역시 p->~o_1();를 수행하면 p의 __vfptr 값도 동일하게 바뀌었다.               


고심끝에 내린 결론은

test1()에서 Stack에 생성된 객체는 파괴될때 가상함수-파괴자를 사용하지 않고 파괴 되므로
위와같은 결과를 얻었고,

test2()에서 Heap에 생성된 객체는 파괴되기전에 직접 p->~o_1(); 호출 하여 __vfptr이
변경됨으로서 delete p;에서 가상함수-파괴자를 이용한 파괴자 호출이 제대로 되지 못하는
것이다.

__vfptr이 변경 되므로 가상함수들이 제대로 동작을 안할 것이라 판단 되었다.
그래서, 소스 코드를 수정해서 다시 테스트 해보았다.
-----------------------------------------------------------------------------
#include <windows.h>
#include <tchar.h>

#include <iostream>

class o_1
{
public:
 o_1 ()         { std::cout << "o_1()"  << std::endl; }
 virtual ~o_1() { std::cout << "~o_1()" << std::endl; }
public:
 virtual void show (void)
 {
  std::cout << "o_1::show()" << std::endl;
 }

};

class o_2 : public o_1
{
public:
 o_2 () : o_1() { std::cout << "o_2()"  << std::endl; }
 virtual ~o_2() { std::cout << "~o_2()" << std::endl; }
public:
 virtual void show (void)
 {
  std::cout << "o_2::show()" << std::endl;
 }

};

class o_3 : public o_2
{
public:
 o_3 () : o_2() { std::cout << "o_3()"  << std::endl; }
 virtual ~o_3() { std::cout << "~o_3()" << std::endl; }
public:
 virtual void show (void)
 {
  std::cout << "o_3::show()" << std::endl;
 }

};

void test1 (void)
{
 o_3  o;

 o_1* p = &o;

 std::cout << "-----------" <<std::endl;
 p->show ();
 o.show();
 std::cout << "-----------" <<std::endl;
 p->~o_1 ();
 std::cout << "-----------" <<std::endl;
 p->show ();
 o.show();
 std::cout << "-----------" <<std::endl;
}

void test2 (void)
{
 o_1* p = new o_3 ();

 std::cout << "-----------" <<std::endl;
 p->~o_1 ();
 std::cout << "-----------" <<std::endl;

 delete p;
}

void test3 (void)
{
 o_1* p = new o_3 ();

 std::cout << "-----------" <<std::endl;
 //p->~o_1 ();
 std::cout << "-----------" <<std::endl;

 delete p;
}

int _tmain(int argc, _TCHAR* argv[])
{
 std::cout << "###########" <<std::endl;
 test1();
 std::cout << "###########" <<std::endl;
 test2();
 std::cout << "###########" <<std::endl;
 test3();
 std::cout << "###########" <<std::endl;

 return 0;
}
-----------------------------------------------------------------------------
########### <- test1() 함수: 잘되는게 아니었다.
o_1()
o_2()
o_3()
-----------
o_3::show() <- p->show (); 정상이다.
o_3::show() <- o.show();   정상이다.
-----------
~o_3()
~o_2()
~o_1()
-----------
o_1::show() <- p->show ();      __vfptr이 변경되었으므로 제대로 동작을 못한다.     
o_3::show() <- o.show();
-----------
~o_3()
~o_2()
~o_1()
########### <- test2() 함수:
o_1()
o_2()
o_3()
-----------
~o_3()
~o_2()
~o_1()
-----------
~o_1()
########### <- test3() 함수:
o_1()
o_2()
o_3()
-----------
-----------
~o_3()
~o_2()
~o_1()
###########
계속하려면 아무 키나 누르십시오 . . .

-----------------------------------------------------------------------------
처음에는 컴파일러 버그라고 생각되었지만 곰곰히 따져보니 아닌 것 같다.
설마, 진짜 컴파일러 버그는 아니겠지... = _ =;

[사용 컴파일러]
Microsoft Visual Studio 2005
Version 8.0.50727.762  (SP.050727-7600)
Microsoft .NET Framework
Version 2.0.50727 SP1

Installed Edition: Professional

-----------------------------------------------------------------------------
추가:
데브피아에 올렸보았었는데 오해하실 수 있는 부분 있는거 같아서 추가합니다.

제가 말하고 싶었던것은 소멸자를 직접 호출했을경우 vftable을 가리키는 __vfptr이
변경된다는 걸 말하고 싶었던겁니다.

좀 더 부연설명을 하자면 메모리 풀 같은 걸 만들때 메모리 풀에서 받은 객체를 사용하고 삭제
후 그대로 또 사용했을 경우 일어나는 현상이 어떻게 될것인가 따져보는 의미입니다.

위의 코드는 일종의 toy code입니다.


제가 컴파일러 버그가 아닐까라고 생각한 부분은 직접 파괴자(소멸자)가 호출된다고 해서
메모리에서 실제로 delete가 일어나는 건 아니기 때문에 vftable을 가리키는 __vfptr가
변경되는게 맞는건지 아닌지
잘 판단이 안되었기 때문에 적어 놓은겁니다.


 

Posted by 셈말짓기 :