home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / ole / wordpad / buttondi.cpp next >
C/C++ Source or Header  |  1998-03-26  |  10KB  |  361 lines

  1. // buttondi.cpp : implementation file
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include "stdafx.h"
  14. #include "resource.h"
  15. #include "buttondi.h"
  16. #include "strings.h"
  17. #include "wordpad.h"
  18.  
  19. #ifdef _DEBUG
  20. #undef THIS_FILE
  21. static char BASED_CODE THIS_FILE[] = __FILE__;
  22. #endif
  23.  
  24. #ifndef DS_CONTEXTHELP
  25. #define DS_CONTEXTHELP 0x2000L
  26. #endif
  27.  
  28. static const int nFontSize = 10;
  29.  
  30. /////////////////////////////////////////////////////////////////////////////
  31. // CButtonDialog dialog
  32.  
  33. int CButtonDialog::DisplayMessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption,
  34.     LPCTSTR lpszButtons, WORD wStyle, int nDef, int nCancel,
  35.     DWORD* pHelpIDs, CWnd* pParentWnd)
  36. {
  37.     CButtonDialog dlg(lpszText, lpszCaption, lpszButtons, wStyle, pHelpIDs,
  38.         pParentWnd);
  39.     dlg.SetDefault(nDef);
  40.     dlg.SetCancel(nCancel);
  41.     return dlg.DoModal();
  42. }
  43.  
  44. CButtonDialog::CButtonDialog(LPCTSTR lpszText, LPCTSTR lpszCaption,
  45.     LPCTSTR lpszButtons, WORD wStyle, DWORD* pHelpIDs ,
  46.     CWnd* pParentWnd) : CCSDialog()
  47. {
  48.  
  49.     ASSERT(lpszText != NULL);
  50.     ASSERT(lpszCaption != NULL);
  51.     if (HIWORD(lpszText) == NULL)
  52.         VERIFY(m_strText.LoadString(LOWORD((DWORD)lpszText)));
  53.     else
  54.         m_strText = lpszText;
  55.     if (HIWORD(lpszCaption) == NULL)
  56.         VERIFY(m_strCaption.LoadString(LOWORD((DWORD)lpszCaption)));
  57.     else
  58.         m_strCaption = lpszCaption;
  59.     if (lpszButtons != NULL)
  60.         AddButtons(lpszButtons);
  61.  
  62.     m_pParentWnd = pParentWnd;
  63.     m_nDefButton = 0;
  64.     m_nCancel = -1;
  65.     m_pButtons = NULL;
  66.     m_wStyle = wStyle;
  67.     m_nBaseID = nFontSize; // don't use IDOK, IDCANCEL, etc
  68.     m_hDlgTmp = NULL;
  69.  
  70.     LOGFONT lf;
  71.     memcpy(&lf, &theApp.m_lf, sizeof(LOGFONT));
  72.     lf.lfHeight = -nFontSize;
  73.     lf.lfWidth = 0;
  74.     lf.lfWeight = FW_NORMAL;
  75.     VERIFY(m_font.CreateFontIndirect(&lf));
  76.  
  77. //  m_font.CreateFont(-nFontSize, 0, 0, 0, FW_NORMAL, FALSE, FALSE,
  78. //      FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  79. //      DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, szFontName);
  80.     m_pHelpIDs = pHelpIDs;
  81. }
  82.  
  83. CButtonDialog::~CButtonDialog()
  84. {
  85.     delete [] m_pButtons;
  86.     if (m_hDlgTmp != NULL)
  87.         GlobalFree(m_hDlgTmp);
  88. }
  89.  
  90. BEGIN_MESSAGE_MAP(CButtonDialog, CCSDialog)
  91.     //{{AFX_MSG_MAP(CButtonDialog)
  92.     ON_WM_CREATE()
  93.     //}}AFX_MSG_MAP
  94. END_MESSAGE_MAP()
  95.  
  96. /////////////////////////////////////////////////////////////////////////////
  97. // CButtonDialog message handlers
  98.  
  99. int CButtonDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
  100. {
  101.     if (m_pHelpIDs != NULL)
  102.     {
  103.         for (int i=0;i<m_strArray.GetSize();i++)
  104.             m_pHelpIDs[i*2] = i+m_nBaseID;
  105.     }
  106.     if (CCSDialog::OnCreate(lpCreateStruct) == -1)
  107.         return -1;
  108.  
  109.     SetWindowText(m_strCaption);
  110.     m_pButtons = new CButton[m_strArray.GetSize()];
  111.  
  112.     CRect rect(0, 0, 10, 10);
  113.     if (!m_staticIcon.Create(NULL,
  114.         SS_ICON | WS_GROUP | WS_CHILD | WS_VISIBLE, rect, this))
  115.     {
  116.         return -1;
  117.     }
  118.     m_staticIcon.SetIcon(::LoadIcon(NULL, GetIconID(m_wStyle)));
  119.  
  120.     if (!m_staticText.Create(m_strText, SS_LEFT | SS_NOPREFIX | WS_GROUP |
  121.         WS_CHILD | WS_VISIBLE, rect, this))
  122.     {
  123.         return -1;
  124.     }
  125.     m_staticText.SetFont(&m_font);
  126.  
  127.     for (int i=0;i<m_strArray.GetSize();i++)
  128.     {
  129.         if (!m_pButtons[i].Create(m_strArray[i], WS_TABSTOP | WS_CHILD |
  130.             WS_VISIBLE | ((i == 0) ? WS_GROUP : 0) |
  131.             ((i == m_nDefButton) ? BS_DEFPUSHBUTTON : BS_PUSHBUTTON),
  132.             rect, this, i+m_nBaseID))
  133.         {
  134.             return -1;
  135.         }
  136.         m_pButtons[i].SetFont(&m_font);
  137.     }
  138.     PositionControls();
  139.     return 0;
  140. }
  141.  
  142. BOOL CButtonDialog::OnInitDialog()
  143. {
  144.     CCSDialog::OnInitDialog();
  145.     if (m_pHelpIDs == NULL) // no context help
  146.         ModifyStyleEx(WS_EX_CONTEXTHELP, 0); //remove
  147.  
  148.     m_pButtons[m_nDefButton].SetFocus();
  149.     return FALSE;  // return TRUE  unless you set the focus to a control
  150. }
  151.  
  152. /////////////////////////////////////////////////////////////////////////////
  153. // CButtonDialog operations
  154.  
  155. void CButtonDialog::AddButtons(LPCTSTR lpszButton)
  156. {
  157.     CString str, strButtons;
  158.     int i=0;
  159.     if (HIWORD(lpszButton) == NULL)
  160.         strButtons.LoadString(LOWORD((DWORD)lpszButton));
  161.     else
  162.         strButtons = lpszButton;
  163.     while (AfxExtractSubString(str, strButtons, i++, '\n'))
  164.         AddButton(str);
  165. }
  166.  
  167. #ifndef DS_3DLOOK
  168. #define DS_3DLOOK 0x4
  169. #endif
  170.  
  171. void CButtonDialog::FillInHeader(LPDLGTEMPLATE lpDlgTmp)
  172. {
  173.     USES_CONVERSION;
  174.     lpDlgTmp->style = DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE |
  175.         WS_CAPTION | WS_SYSMENU;
  176.     if (theApp.m_bWin4)
  177.         lpDlgTmp->style |= DS_CONTEXTHELP;
  178.     lpDlgTmp->dwExtendedStyle = 0;
  179.     lpDlgTmp->cdit = 0;
  180.     lpDlgTmp->x = 0;
  181.     lpDlgTmp->y = 0;
  182.     lpDlgTmp->cx = 100;
  183.     lpDlgTmp->cy = 100;
  184.  
  185.     LPWSTR lpStr = (LPWSTR)(lpDlgTmp + 1); /* Move ptr to the variable fields */
  186.  
  187.     *lpStr++ = 0;  /* No Menu resource for Message Box */
  188.     *lpStr++ = 0;  /* No Class name for MessageBox */
  189.  
  190.     int nLen = m_strCaption.GetLength();
  191.     wcscpy(lpStr, T2CW(m_strCaption));
  192.  
  193.     lpStr += nLen+1;
  194.     WORD* pWord = (WORD*)lpStr;
  195.     *pWord = 10; // 10 pt font
  196.     pWord++;
  197.     lpStr = (LPWSTR) pWord;
  198.  
  199.     wcscpy(lpStr, T2W(theApp.m_lf.lfFaceName));
  200. }
  201.  
  202. /////////////////////////////////////////////////////////////////////////////
  203. // CButtonDialog overridables
  204.  
  205. BOOL CButtonDialog::OnCommand(WPARAM wParam, LPARAM /*lParam*/)
  206. {
  207.     if (wParam == IDCANCEL && m_nCancel != -1)
  208.     {
  209.         EndDialog(m_nCancel);
  210.         return TRUE;
  211.     }
  212.     if (::GetDlgItem(m_hWnd, wParam)==NULL)
  213.         return FALSE;
  214.     EndDialog(wParam-m_nBaseID);
  215.     return TRUE;
  216. }
  217.  
  218. int CButtonDialog::DoModal()
  219. {
  220.     ASSERT(m_strArray.GetSize() != 0);
  221.     if (m_strArray.GetSize() == 0)
  222.         return (m_nCancel != -1) ? m_nCancel : 0;
  223.  
  224.     // compute size of header
  225.     // Fixed portions of DLG template header = sizeof(DLGTEMPLATE);
  226.     // One null byte for menu name and one for class name = 2
  227.     // Caption text plus NULL = m_strCaption.GetLength()+1
  228.     int nSize = sizeof(DLGTEMPLATE);
  229.     nSize += (2 + m_strCaption.GetLength()+1+lstrlen(theApp.m_lf.lfFaceName)+1)*2 +sizeof(WORD);
  230.     m_hDlgTmp = GlobalAlloc(GPTR, nSize);
  231.     if (m_hDlgTmp == NULL)
  232.         return IDCANCEL;
  233.     LPDLGTEMPLATE lpDlgTmp = (LPDLGTEMPLATE)GlobalLock(m_hDlgTmp);
  234.     FillInHeader(lpDlgTmp);
  235.     GlobalUnlock(m_hDlgTmp);
  236.     InitModalIndirect(m_hDlgTmp);
  237.  
  238.     return CCSDialog::DoModal();
  239. }
  240.  
  241. /////////////////////////////////////////////////////////////////////////////
  242. // CButtonDialog implementation
  243.  
  244. void CButtonDialog::PositionControls()
  245. {
  246.     CSize sizeBase = GetBaseUnits();
  247.     int nButtonHeight = (sizeBase.cy*14)/8;
  248.     int nHeight = 0;
  249.     int nSep,nLeftMargin,nRightMargin,nTopMargin,nBottomMargin;
  250.     int nButtonAdj;
  251.     int nWidth = 0;
  252.     CRect rectText;
  253.  
  254.     // a) 5/8 screen Width
  255.     // b) Caption
  256.     // c) nLeftMargin ICON nSep TEXT nRightMargin
  257.     // d) nLeftMargin Button1 nSep Button2 ... nRightMargin
  258.     // client width is max(b,d, min(c,a))
  259.  
  260.     CSize sizeIcon(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
  261.     nSep = sizeIcon.cx/2;
  262.     nLeftMargin = nSep;
  263.     nRightMargin = nSep;
  264.     nTopMargin = nSep;
  265.     nBottomMargin = nSep;
  266.  
  267.     CClientDC dc(this);
  268.     CFont* pOldFont = dc.SelectObject(&m_font);
  269.  
  270.     nButtonAdj = dc.GetTextExtent(_T("XXX"),3).cx; // padding on buttons
  271.  
  272.     int nScreenWidth58 = dc.GetDeviceCaps(HORZRES)*5/8;
  273.     int nCaptionWidth = dc.GetTextExtent(m_strCaption, m_strCaption.
  274.         GetLength()).cx;
  275.     CSize sizeText = dc.GetTextExtent(m_strText,m_strText.GetLength());
  276.     int nTextIconWidth = nLeftMargin+sizeIcon.cx+nSep+sizeText.cx+nRightMargin;
  277.     int nButtons = m_strArray.GetSize();
  278.     int nButtonsWidth = nLeftMargin+nRightMargin+(nButtons-1)*nSep;
  279.     for (int i=0;i<nButtons;i++)
  280.     {
  281.         nButtonsWidth +=
  282.             dc.GetTextExtent(m_strArray[i],m_strArray[i].GetLength()).cx+
  283.             nButtonAdj*2;
  284.     }
  285.  
  286.     nWidth = min(nTextIconWidth,nScreenWidth58);
  287.     nWidth = max(nWidth, nCaptionWidth);
  288.     nWidth = max(nWidth, nButtonsWidth);
  289.  
  290.     m_staticIcon.SetWindowPos(NULL, nLeftMargin, nTopMargin, sizeIcon.cx,
  291.         sizeIcon.cy, SWP_NOZORDER);
  292.  
  293.     if (sizeText.cx > nWidth-nLeftMargin-nRightMargin-sizeIcon.cx-nSep)
  294.     {
  295.         sizeText.cx = nWidth-nLeftMargin-nRightMargin-sizeIcon.cx-nSep;
  296. //      int nTextWidth = nWidth-nLeftMargin-nRightMargin-sizeIcon.cx-nSep;
  297. //      rectText.SetRect(0, 0, nTextWidth, 32767);
  298.         rectText.SetRect(0, 0, sizeText.cx, 32767);
  299.         /* Ask DrawText for the right cy */
  300.         sizeText.cy = dc.DrawText(m_strText, m_strText.GetLength(), &rectText,
  301.             DT_CALCRECT | DT_WORDBREAK | DT_EXPANDTABS | DT_NOPREFIX);
  302.     }
  303.  
  304.     m_staticText.SetWindowPos(NULL, nSep+sizeIcon.cx+nSep, nTopMargin,
  305.         sizeText.cx, sizeText.cy, SWP_NOZORDER);
  306.  
  307.     sizeText.cy = max(sizeText.cy, sizeIcon.cy); // at least icon height
  308.     nHeight = nTopMargin + sizeText.cy + nSep + nButtonHeight + nBottomMargin;
  309.  
  310.     CRect rect;
  311.     rect.left = (nWidth - (nButtonsWidth - nLeftMargin - nRightMargin))/2;
  312.     rect.top = nTopMargin + sizeText.cy + nSep;
  313.     rect.bottom = rect.top + nButtonHeight;
  314.  
  315.     for (i=0;i<m_strArray.GetSize();i++)
  316.     {
  317.         rect.right = rect.left + dc.GetTextExtent(m_strArray[i],m_strArray[i].GetLength()).cx +
  318.             2*nButtonAdj;
  319.         m_pButtons[i].MoveWindow(&rect);
  320.         rect.left = rect.right + nSep;
  321.     }
  322.  
  323.     rect.SetRect(0,0,nWidth,nHeight);
  324.     CalcWindowRect(&rect);
  325.     SetWindowPos(NULL, (dc.GetDeviceCaps(HORZRES)-rect.Width())/2,
  326.         (dc.GetDeviceCaps(VERTRES)-rect.Height())/2, rect.Width(), rect.Height(),
  327.         SWP_NOZORDER|SWP_NOACTIVATE);
  328.     if(m_nCancel == -1) // no cancel button
  329.     {
  330. //      CMenu* pMenu = GetSystemMenu(FALSE);
  331. //      if (pMenu != NULL)
  332. //          pMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);
  333.     }
  334.     dc.SelectObject(pOldFont);
  335. }
  336.  
  337. CSize CButtonDialog::GetBaseUnits()
  338. {
  339.     CDisplayIC dc;
  340.     CFont* pFont = dc.SelectObject(&m_font);
  341.     TEXTMETRIC tm;
  342.     VERIFY(dc.GetTextMetrics(&tm));
  343.     dc.SelectObject(pFont);
  344.     return CSize(tm.tmAveCharWidth, tm.tmHeight);
  345. }
  346.  
  347. LPCTSTR CButtonDialog::GetIconID(WORD wFlags)
  348. {
  349.     LPCTSTR lpszIcon = NULL;
  350.     wFlags &= MB_ICONMASK;
  351.     if (wFlags == MB_ICONHAND)
  352.         lpszIcon = IDI_HAND;
  353.     else if (wFlags == MB_ICONQUESTION)
  354.         lpszIcon = IDI_QUESTION;
  355.     else if (wFlags == MB_ICONEXCLAMATION)
  356.         lpszIcon = IDI_EXCLAMATION;
  357.     else if (wFlags == MB_ICONASTERISK)
  358.         lpszIcon = IDI_ASTERISK;
  359.     return lpszIcon;
  360. }
  361.