home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / general / dlgtempl / itemtemp.cpp < prev    next >
C/C++ Source or Header  |  1998-03-26  |  8KB  |  218 lines

  1. // itemtemp.cpp
  2. //
  3.  
  4. // This is a part of the Microsoft Foundation Classes C++ library.
  5. // Copyright (C) 1992-1998 Microsoft Corporation
  6. // All rights reserved.
  7. //
  8. // This source code is only intended as a supplement to the
  9. // Microsoft Foundation Classes Reference and related
  10. // electronic documentation provided with the library.
  11. // See these sources for detailed information regarding the
  12. // Microsoft Foundation Classes product.
  13.  
  14. #include "stdafx.h"
  15.  
  16. #include "itemtemp.h"
  17. #include "resource.h"
  18.  
  19. #define SETRECT(rect, l, t, r, b) \
  20.     rect.left = l; \
  21.     rect.top = t; \
  22.     rect.right = r; \
  23.     rect.bottom = b;
  24.  
  25.  
  26. CMyDialogTemplate::CMyDialogTemplate()
  27. {
  28.     // initialize the 3 dialog items
  29.  
  30.     CRect   rect(10, 10, 80, 35);  // Set default postions for the buttons
  31.     m_rgDlgItem[IBUTTON].Initialize(CDialogItem::BUTTON, IDC_MYBUTTON, &rect, _T("Dummy Button"));
  32.     SETRECT(rect, 100, 10, 250, 35);
  33.     m_rgDlgItem[ISTATICTEXT].Initialize(CDialogItem::STATICTEXT, IDC_MYSTATICTEXT, &rect, _T("Static Text of your choice here."));
  34.     SETRECT(rect, 70, 50, 250, 135);
  35.     m_rgDlgItem[IEDITCONTROL].Initialize(CDialogItem::EDITCONTROL, IDC_MYEDITCONTROL, &rect,
  36.         _T("This is a multiline edit control.  CMyDialogItem::DemoIt holds the essential code of this sample."));
  37.  
  38.     // now initialize the DLGTEMPLATE structure
  39.     m_dlgTempl.cx = 280;  // 4 horizontal units are the width of one character
  40.     m_dlgTempl.cy = 160;  // 8 vertical units are the height of one character
  41.     m_dlgTempl.style = WS_CAPTION | WS_VISIBLE | WS_DLGFRAME | WS_POPUP | DS_MODALFRAME | DS_SETFONT;
  42.     m_dlgTempl.dwExtendedStyle = 0;
  43.     m_dlgTempl.x = 0;
  44.     m_dlgTempl.y = 0;
  45.     m_dlgTempl.cdit = 3;  // 3 dialog items in the dialog
  46. }
  47.  
  48. void CMyDialogTemplate::DemoIt()
  49. {
  50.     // The first step is to allocate memory to define the dialog.  The information to be
  51.     // stored in the allocated buffer is the following:
  52.     //
  53.     // 1.  DLGTEMPLATE structure
  54.     // 2.    0x0000 (Word) indicating the dialog has no menu
  55.     // 3.    0x0000 (Word) Let windows assign default class to the dialog
  56.     // 4.    (Caption)  Null terminated unicode string
  57.     // 5.    0x000B  (size of the font to be used)
  58.     // 6.    "Arial"  (name of the typeface to be used)
  59.     // 7.  DLGITEMTEMPLATE structure for the button  (HAS TO BE DWORD ALIGNED)
  60.     // 8.    0x0080  to indicate the control is a button
  61.     // 9.    (Title). Unicode null terminated string with the caption
  62.     // 10.    0x0000   0 extra bytes of data for this control
  63.     // 11.  DLGITEMTEMPLATE structure for the Static Text  (HAS TO BE DWORD ALIGNED)
  64.     // 12.    0x0081 to indicate the control is static text
  65.     // 13.   (Title). Unicode null terminated string with the text
  66.     // 14     0x0000.  0 extra bytes of data for this control
  67.     // 15. DLGITEMTEMPLATE structure for the Edit Control (HAS TO BE DWORD ALIGNED)
  68.     // 16.   0x0082 to indicate an Edit control
  69.     // 17.   (Text) - Null terminated unicode string to appear in the edit control
  70.     // 18.   0x0000. 0 extra bytes of data for this control
  71.  
  72.     WCHAR szBoxCaption[] = L"Dialog Template Sample -  PRESS <ESC> TO CLOSE THIS DIALOG";
  73.     WCHAR szFontName[] = L"ARIAL";
  74.  
  75.     // will first convert the control captions to UNICODE
  76.     int     nTotalLength = 0;
  77.     int     i;
  78.  
  79.     TRY  // catch memory exceptions and don't worry about allocation failures
  80.     {
  81.         // The following expressions have unnecessary parenthesis trying to make the
  82.         // comments more clear.
  83.         int nBufferSize =  sizeof(DLGTEMPLATE) + (2 * sizeof(WORD))/*menu and class*/ + sizeof(szBoxCaption);
  84.         nBufferSize += sizeof(WORD) + sizeof(szFontName); /* font information*/ +
  85.  
  86.         nBufferSize = (nBufferSize + 3) & ~3;  // adjust size to make first control DWORD aligned
  87.  
  88.         for (i = 0; i < TOTALITEMS; i++)
  89.         {
  90.             int nItemLength = sizeof(DLGITEMTEMPLATE) + 3 * sizeof(WORD);
  91.             nItemLength += (m_rgDlgItem[i].m_strCaption.GetLength() + 1) * sizeof(WCHAR);
  92.  
  93.             if (i != TOTALITEMS -1 )   // the last control does not need extra bytes
  94.                 nItemLength = (nItemLength + 3) & ~3;  // take into account gap so next control is DWORD aligned
  95.  
  96.             nBufferSize += nItemLength;
  97.         }
  98.  
  99.  
  100.         HLOCAL hLocal = LocalAlloc(LHND, nBufferSize);
  101.         if (hLocal == NULL)
  102.             AfxThrowMemoryException();
  103.  
  104.         BYTE*   pBuffer = (BYTE*)LocalLock(hLocal);
  105.         if (pBuffer == NULL)
  106.         {
  107.             LocalFree(hLocal);
  108.             AfxThrowMemoryException();
  109.         }
  110.  
  111.         BYTE*   pdest = pBuffer;
  112.         // transfer DLGTEMPLATE structure to the buffer
  113.         memcpy(pdest, &m_dlgTempl, sizeof(DLGTEMPLATE));
  114.         pdest += sizeof(DLGTEMPLATE);
  115.         *(WORD*)pdest = 0; // no menu
  116.         *(WORD*)(pdest + 1) = 0;  // use default window class
  117.         pdest += 2 * sizeof(WORD);
  118.         memcpy(pdest, szBoxCaption, sizeof(szBoxCaption));
  119.         pdest += sizeof(szBoxCaption);
  120.         *(WORD*)pdest = 11;  // font size
  121.         pdest += sizeof(WORD);
  122.         memcpy(pdest, szFontName, sizeof(szFontName));
  123.         pdest += sizeof(szFontName);
  124.  
  125.         // will now transfer the information for each one of the item templates
  126.         for (i = 0; i < TOTALITEMS; i++)
  127.         {
  128.             pdest = (BYTE*)(((DWORD)pdest + 3) & ~3);  // make the pointer DWORD aligned
  129.             memcpy(pdest, (void *)&m_rgDlgItem[i].m_dlgItemTemplate, sizeof(DLGITEMTEMPLATE));
  130.             pdest += sizeof(DLGITEMTEMPLATE);
  131.             *(WORD*)pdest = 0xFFFF;  // indicating atom value
  132.             pdest += sizeof(WORD);
  133.             *(WORD*)pdest = m_rgDlgItem[i].m_controltype;    // atom value for the control
  134.             pdest += sizeof(WORD);
  135.  
  136.             // transfer the caption even when it is an empty string
  137.             WCHAR*  pchCaption;
  138.             int     nChars, nActualChars;
  139.  
  140.             nChars = m_rgDlgItem[i].m_strCaption.GetLength() + 1;
  141.             pchCaption = new WCHAR[nChars];
  142.             nActualChars = MultiByteToWideChar(CP_ACP, 0, m_rgDlgItem[i].m_strCaption, -1, pchCaption, nChars);
  143.             ASSERT(nActualChars > 0);
  144.             memcpy(pdest, pchCaption, nActualChars * sizeof(WCHAR));
  145.             pdest += nActualChars * sizeof(WCHAR);
  146.             delete pchCaption;
  147.  
  148.             *(WORD*)pdest = 0;  // How many bytes in data for control
  149.             pdest += sizeof(WORD);
  150.         }
  151.         ASSERT(pdest - pBuffer == nBufferSize); // just make sure we did not overrun the heap
  152.  
  153.         CDialog dlg;
  154.         dlg.InitModalIndirect((DLGTEMPLATE*)pBuffer);
  155.         dlg.DoModal();  // tadaaa!  this is the line everyone's been waiting for!!!
  156.  
  157.         LocalUnlock(hLocal);
  158.         LocalFree(hLocal);
  159.     }
  160.     CATCH(CMemoryException, e)
  161.     {
  162.         MessageBox(NULL, _T("Memory allocation for dialog template failed.  Demo aborted!"),
  163.             _T("Allocation Failure"), MB_ICONEXCLAMATION | MB_OK);
  164.     }
  165.     END_CATCH
  166. }
  167.  
  168. CDialogItem::CDialogItem(enum CDialogItem::controltype ctrlType)
  169. {
  170.     m_controltype = ctrlType;
  171. }
  172.  
  173.  
  174. void CDialogItem::Initialize(enum controltype ctrltype, UINT nID, CRect* prect, LPCTSTR lpszCaption)
  175. {
  176.     // first fill in the type, location and size of the control
  177.     m_controltype = ctrltype;
  178.     if (prect != NULL)
  179.     {
  180.         // disable warning on conversion from long to short
  181. #pragma warning(disable : 4244)
  182.         m_dlgItemTemplate.x = prect->left;
  183.         m_dlgItemTemplate.y = prect->top;
  184.         m_dlgItemTemplate.cx = prect->Width();
  185.         m_dlgItemTemplate.cy = prect->Height();
  186. #pragma warning(default : 4244)
  187.     }
  188.     else
  189.     {
  190.         m_dlgItemTemplate.x = 0;
  191.         m_dlgItemTemplate.y = 0;
  192.         m_dlgItemTemplate.cx = 10;  // some useless default
  193.         m_dlgItemTemplate.cy = 10;
  194.     }
  195.  
  196.     m_dlgItemTemplate.dwExtendedStyle = 0;
  197.     m_dlgItemTemplate.id = nID;
  198.  
  199.     // the styles below are hard coded.  In a real life application you might want to use variables to
  200.     // define the sytle.
  201.     switch(m_controltype)
  202.     {
  203.     case BUTTON:
  204.         m_dlgItemTemplate.style = WS_CAPTION | WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_PUSHBUTTON;
  205.         break;
  206.     case EDITCONTROL:
  207.         m_dlgItemTemplate.style = WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_MULTILINE | ES_LEFT;
  208.         break;
  209.     case STATICTEXT:
  210.         m_dlgItemTemplate.style = WS_CHILD | WS_VISIBLE | SS_LEFT;
  211.         break;
  212.     default:
  213.         ASSERT(FALSE);  // should never get here, anyway.
  214.     }
  215.  
  216.     m_strCaption = (lpszCaption != NULL)? lpszCaption : _T("");
  217. }
  218.