// This is a part of the Microsoft Foundation Classes C++ library. // Copyright (C) Microsoft Corporation // All rights reserved. // // This source code is only intended as a supplement to the // Microsoft Foundation Classes Reference and related // electronic documentation provided with the library. // See these sources for detailed information regarding the // Microsoft Foundation Classes product. #include "stdafx.h" #include ///////////////////////////////////////////////////////////////////////////// // Other helpers BOOL AFXAPI AfxCustomLogFont(UINT nIDS, LOGFONT* pLogFont) { ENSURE_ARG(pLogFont != NULL); ASSERT(nIDS != 0); TCHAR szFontInfo[256]; if (!AfxLoadString(nIDS, szFontInfo,_countof(szFontInfo))) return FALSE; LPTSTR lpszSize = _tcschr(szFontInfo, '\n'); if (lpszSize != NULL) { // get point size and convert to pixels pLogFont->lfHeight = _ttoi(lpszSize+1); pLogFont->lfHeight = MulDiv(pLogFont->lfHeight, afxData.cyPixelsPerInch, 72); *lpszSize = '\0'; } Checked::tcsncpy_s(pLogFont->lfFaceName, _countof(pLogFont->lfFaceName), szFontInfo, _TRUNCATE); return TRUE; } BOOL AFXAPI _AfxIsComboBoxControl(HWND hWnd, UINT nStyle) { if (hWnd == NULL) return FALSE; // do cheap style compare first if ((UINT)(::GetWindowLong(hWnd, GWL_STYLE) & 0x0F) != nStyle) return FALSE; // do expensive classname compare next TCHAR szCompare[_countof("combobox")+1]; ::GetClassName(hWnd, szCompare, _countof(szCompare)); return ::AfxInvariantStrICmp(szCompare, _T("combobox")) == 0; } BOOL AFXAPI _AfxCompareClassName(HWND hWnd, LPCTSTR lpszClassName) { ASSERT(::IsWindow(hWnd)); TCHAR szTemp[32]; ::GetClassName(hWnd, szTemp, _countof(szTemp)); return ::AfxInvariantStrICmp(szTemp, lpszClassName) == 0; } HWND AFXAPI _AfxChildWindowFromPoint(HWND hWnd, POINT pt) { ASSERT(hWnd != NULL); // check child windows ::ClientToScreen(hWnd, &pt); HWND hWndChild = ::GetWindow(hWnd, GW_CHILD); for (; hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT)) { if (_AfxGetDlgCtrlID(hWndChild) != (WORD)0 && (::GetWindowLong(hWndChild, GWL_STYLE) & WS_VISIBLE)) { // see if point hits the child window CRect rect; ::GetWindowRect(hWndChild, rect); if (rect.PtInRect(pt)) return hWndChild; } } return NULL; // not found } void AFXAPI AfxSetWindowText(HWND hWndCtrl, LPCTSTR lpszNew) { ENSURE(hWndCtrl); ENSURE(lpszNew); int nNewLen = ATL::lstrlen(lpszNew); TCHAR szOld[256]=_T(""); // fast check to see if text really changes (reduces flash in controls) if (nNewLen > _countof(szOld) || ::GetWindowText(hWndCtrl, szOld, _countof(szOld)) != nNewLen || lstrcmp(szOld, lpszNew) != 0) { // change it ::SetWindowText(hWndCtrl, lpszNew); } } void AFXAPI AfxDeleteObject(HGDIOBJ* pObject) { ENSURE_ARG(pObject != NULL); if (*pObject != NULL) { DeleteObject(*pObject); *pObject = NULL; } } void AFXAPI AfxCancelModes(HWND hWndRcvr) { // if we receive a message destined for a window, cancel any combobox // popups that could be in toolbars or dialog bars HWND hWndCancel = ::GetFocus(); if (hWndCancel == NULL) return; // nothing to cancel if (hWndCancel == hWndRcvr) return; // let input go to window with focus // focus is in part of a combo-box if (!_AfxIsComboBoxControl(hWndCancel, (UINT)CBS_DROPDOWNLIST)) { // check as a dropdown hWndCancel = ::GetParent(hWndCancel); // parent of edit is combo if (hWndCancel == hWndRcvr) return; // let input go to part of combo if (!_AfxIsComboBoxControl(hWndCancel, (UINT)CBS_DROPDOWN)) return; // not a combo-box that is active } // combo-box is active, but if receiver is a popup, do nothing if (hWndRcvr != NULL && (::GetWindowLong(hWndRcvr, GWL_STYLE) & WS_CHILD) != 0 && #ifndef _WIN32_WCE ::GetParent(hWndRcvr) == ::GetDesktopWindow()) #else ::GetParent(hWndRcvr) == HWND_DESKTOP) #endif // !_WIN32_WCE return; // finally, we should cancel the mode! ::SendMessage(hWndCancel, CB_SHOWDROPDOWN, FALSE, 0L); } void AFXAPI AfxGlobalFree(HGLOBAL hGlobal) { if (hGlobal == NULL) return; // avoid bogus warning error messages from various debugging tools #ifndef _WIN32_WCE // GMEM_INVALID_HANDLE ASSERT(GlobalFlags(hGlobal) != GMEM_INVALID_HANDLE); #endif // !_WIN32_WCE UINT nCount = GlobalFlags(hGlobal) & GMEM_LOCKCOUNT; while (nCount--) GlobalUnlock(hGlobal); // finally, really free the handle GlobalFree(hGlobal); } ///////////////////////////////////////////////////////////////////////////// // Special new handler for safety pool on temp maps #ifndef _AFX_PORTABLE #define MIN_MALLOC_OVERHEAD 4 // LocalAlloc or other overhead int AFX_CDECL AfxCriticalNewHandler(size_t nSize) // nSize is already rounded { // called during critical memory allocation // free up part of the app's safety cache TRACE(traceMemory, 0, _T("Warning: Critical memory allocation failed!\n")); _AFX_THREAD_STATE* pThreadState = AfxGetThreadState(); if (pThreadState != NULL && pThreadState->m_pSafetyPoolBuffer != NULL) { size_t nOldBufferSize = _msize(pThreadState->m_pSafetyPoolBuffer); if (nOldBufferSize <= nSize + MIN_MALLOC_OVERHEAD) { // give it all up TRACE(traceMemory, 0, _T("Warning: Freeing application's memory safety pool!\n")); free(pThreadState->m_pSafetyPoolBuffer); pThreadState->m_pSafetyPoolBuffer = NULL; } else { BOOL bEnable = AfxEnableMemoryTracking(FALSE); #ifndef _WIN32_WCE _expand(pThreadState->m_pSafetyPoolBuffer, nOldBufferSize - (nSize + MIN_MALLOC_OVERHEAD)); #else realloc(pThreadState->m_pSafetyPoolBuffer, nOldBufferSize - (nSize + MIN_MALLOC_OVERHEAD)); #endif // !_WIN32_WCE AfxEnableMemoryTracking(bEnable); TRACE(traceMemory, 0, _T("Warning: Shrinking safety pool from %d to %d to satisfy request of %d bytes.\n"), nOldBufferSize, _msize(pThreadState->m_pSafetyPoolBuffer), nSize); } return 1; // retry it } TRACE(traceMemory, 0, _T("ERROR: Critical memory allocation from safety pool failed!\n")); AfxThrowMemoryException(); // oops } #endif // !_AFX_PORTABLE /////////////////////////////////////////////////////////////////////////////