winutil.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #include <malloc.h>
  12. #ifdef AFX_CORE2_SEG
  13. #pragma code_seg(AFX_CORE2_SEG)
  14. #endif
  15. #ifdef _DEBUG
  16. #undef THIS_FILE
  17. static char THIS_FILE[] = __FILE__;
  18. #endif
  19. /////////////////////////////////////////////////////////////////////////////
  20. // Other helpers
  21. BOOL AFXAPI AfxCustomLogFont(UINT nIDS, LOGFONT* pLogFont)
  22. {
  23. ASSERT(pLogFont != NULL);
  24. ASSERT(nIDS != 0);
  25. TCHAR szFontInfo[256];
  26. if (!AfxLoadString(nIDS, szFontInfo))
  27. return FALSE;
  28. LPTSTR lpszSize = _tcschr(szFontInfo, '\n');
  29. if (lpszSize != NULL)
  30. {
  31. // get point size and convert to pixels
  32. pLogFont->lfHeight = _ttoi(lpszSize+1);
  33. pLogFont->lfHeight =
  34. MulDiv(pLogFont->lfHeight, afxData.cyPixelsPerInch, 72);
  35. *lpszSize = '\0';
  36. }
  37. lstrcpyn(pLogFont->lfFaceName, szFontInfo, LF_FACESIZE);
  38. return TRUE;
  39. }
  40. BOOL AFXAPI _AfxIsComboBoxControl(HWND hWnd, UINT nStyle)
  41. {
  42. if (hWnd == NULL)
  43. return FALSE;
  44. // do cheap style compare first
  45. if ((UINT)(::GetWindowLong(hWnd, GWL_STYLE) & 0x0F) != nStyle)
  46. return FALSE;
  47. // do expensive classname compare next
  48. TCHAR szCompare[_countof("combobox")+1];
  49. ::GetClassName(hWnd, szCompare, _countof(szCompare));
  50. return lstrcmpi(szCompare, _T("combobox")) == 0;
  51. }
  52. BOOL AFXAPI _AfxCompareClassName(HWND hWnd, LPCTSTR lpszClassName)
  53. {
  54. ASSERT(::IsWindow(hWnd));
  55. TCHAR szTemp[32];
  56. ::GetClassName(hWnd, szTemp, _countof(szTemp));
  57. return lstrcmpi(szTemp, lpszClassName) == 0;
  58. }
  59. HWND AFXAPI _AfxChildWindowFromPoint(HWND hWnd, POINT pt)
  60. {
  61. ASSERT(hWnd != NULL);
  62. // check child windows
  63. ::ClientToScreen(hWnd, &pt);
  64. HWND hWndChild = ::GetWindow(hWnd, GW_CHILD);
  65. for (; hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT))
  66. {
  67. if (_AfxGetDlgCtrlID(hWndChild) != (WORD)-1 &&
  68. (::GetWindowLong(hWndChild, GWL_STYLE) & WS_VISIBLE))
  69. {
  70. // see if point hits the child window
  71. CRect rect;
  72. ::GetWindowRect(hWndChild, rect);
  73. if (rect.PtInRect(pt))
  74. return hWndChild;
  75. }
  76. }
  77. return NULL; // not found
  78. }
  79. void AFXAPI AfxSetWindowText(HWND hWndCtrl, LPCTSTR lpszNew)
  80. {
  81. int nNewLen = lstrlen(lpszNew);
  82. TCHAR szOld[256];
  83. // fast check to see if text really changes (reduces flash in controls)
  84. if (nNewLen > _countof(szOld) ||
  85. ::GetWindowText(hWndCtrl, szOld, _countof(szOld)) != nNewLen ||
  86. lstrcmp(szOld, lpszNew) != 0)
  87. {
  88. // change it
  89. ::SetWindowText(hWndCtrl, lpszNew);
  90. }
  91. }
  92. void AFXAPI AfxDeleteObject(HGDIOBJ* pObject)
  93. {
  94. ASSERT(pObject != NULL);
  95. if (*pObject != NULL)
  96. {
  97. DeleteObject(*pObject);
  98. *pObject = NULL;
  99. }
  100. }
  101. void AFXAPI AfxCancelModes(HWND hWndRcvr)
  102. {
  103. // if we receive a message destined for a window, cancel any combobox
  104. // popups that could be in toolbars or dialog bars
  105. HWND hWndCancel = ::GetFocus();
  106. if (hWndCancel == NULL)
  107. return; // nothing to cancel
  108. if (hWndCancel == hWndRcvr)
  109. return; // let input go to window with focus
  110. // focus is in part of a combo-box
  111. if (!_AfxIsComboBoxControl(hWndCancel, (UINT)CBS_DROPDOWNLIST))
  112. {
  113. // check as a dropdown
  114. hWndCancel = ::GetParent(hWndCancel); // parent of edit is combo
  115. if (hWndCancel == hWndRcvr)
  116. return; // let input go to part of combo
  117. if (!_AfxIsComboBoxControl(hWndCancel, (UINT)CBS_DROPDOWN))
  118. return; // not a combo-box that is active
  119. }
  120. // combo-box is active, but if receiver is a popup, do nothing
  121. if (hWndRcvr != NULL &&
  122. (::GetWindowLong(hWndRcvr, GWL_STYLE) & WS_CHILD) != 0 &&
  123. ::GetParent(hWndRcvr) == ::GetDesktopWindow())
  124. return;
  125. // finally, we should cancel the mode!
  126. ::SendMessage(hWndCancel, CB_SHOWDROPDOWN, FALSE, 0L);
  127. }
  128. void AFXAPI AfxGlobalFree(HGLOBAL hGlobal)
  129. {
  130. if (hGlobal == NULL)
  131. return;
  132. // avoid bogus warning error messages from various debugging tools
  133. ASSERT(GlobalFlags(hGlobal) != GMEM_INVALID_HANDLE);
  134. UINT nCount = GlobalFlags(hGlobal) & GMEM_LOCKCOUNT;
  135. while (nCount--)
  136. GlobalUnlock(hGlobal);
  137. // finally, really free the handle
  138. GlobalFree(hGlobal);
  139. }
  140. /////////////////////////////////////////////////////////////////////////////
  141. // Special new handler for safety pool on temp maps
  142. #ifndef _AFX_PORTABLE
  143. #define MIN_MALLOC_OVERHEAD 4 // LocalAlloc or other overhead
  144. int AFX_CDECL AfxCriticalNewHandler(size_t nSize)
  145. // nSize is already rounded
  146. {
  147. // called during critical memory allocation
  148. // free up part of the app's safety cache
  149. TRACE0("Warning: Critical memory allocation failed!\n");
  150. _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
  151. if (pThreadState != NULL && pThreadState->m_pSafetyPoolBuffer != NULL)
  152. {
  153. size_t nOldBufferSize = _msize(pThreadState->m_pSafetyPoolBuffer);
  154. if (nOldBufferSize <= nSize + MIN_MALLOC_OVERHEAD)
  155. {
  156. // give it all up
  157. TRACE0("Warning: Freeing application's memory safety pool!\n");
  158. free(pThreadState->m_pSafetyPoolBuffer);
  159. pThreadState->m_pSafetyPoolBuffer = NULL;
  160. }
  161. else
  162. {
  163. BOOL bEnable = AfxEnableMemoryTracking(FALSE);
  164. _expand(pThreadState->m_pSafetyPoolBuffer,
  165. nOldBufferSize - (nSize + MIN_MALLOC_OVERHEAD));
  166. AfxEnableMemoryTracking(bEnable);
  167. TRACE3("Warning: Shrinking safety pool from %d to %d to satisfy request of %d bytes.\n",
  168. nOldBufferSize, _msize(pThreadState->m_pSafetyPoolBuffer), nSize);
  169. }
  170. return 1; // retry it
  171. }
  172. TRACE0("ERROR: Critical memory allocation from safety pool failed!\n");
  173. AfxThrowMemoryException(); // oops
  174. return 0;
  175. }
  176. #endif // !_AFX_PORTABLE
  177. /////////////////////////////////////////////////////////////////////////////