BUTTONDI.CPP
上传用户:aakk678
上传日期:2022-07-09
资源大小:406k
文件大小:10k
源码类别:

界面编程

开发平台:

Visual C++

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