// This is a part of the Microsoft Foundation Classes C++ library. // Copyright (C) 1992-1998 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 #ifdef AFX_CORE2_SEG #pragma code_seg(AFX_CORE2_SEG) #endif #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // Other helpers BOOL AFXAPI AfxCustomLogFont(UINT nIDS, LOGFONT* pLogFont) { ASSERT(pLogFont != NULL); ASSERT(nIDS != 0); TCHAR szFontInfo[256]; if (!AfxLoadString(nIDS, 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'; } lstrcpyn(pLogFont->lfFaceName, szFontInfo, LF_FACESIZE); 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 lstrcmpi(szCompare, _T("combobox")) == 0; } BOOL AFXAPI _AfxCompareClassName(HWND hWnd, LPCTSTR lpszClassName) { ASSERT(::IsWindow(hWnd)); TCHAR szTemp[32]; ::GetClassName(hWnd, szTemp, _countof(szTemp)); return lstrcmpi(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)-1 && (::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) { int nNewLen = lstrlen(lpszNew); TCHAR szOld[256]; // 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) { ASSERT(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 && ::GetParent(hWndRcvr) == ::GetDesktopWindow()) 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 ASSERT(GlobalFlags(hGlobal) != GMEM_INVALID_HANDLE); 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 TRACE0("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 TRACE0("Warning: Freeing application's memory safety pool!\n"); free(pThreadState->m_pSafetyPoolBuffer); pThreadState->m_pSafetyPoolBuffer = NULL; } else { BOOL bEnable = AfxEnableMemoryTracking(FALSE); _expand(pThreadState->m_pSafetyPoolBuffer, nOldBufferSize - (nSize + MIN_MALLOC_OVERHEAD)); AfxEnableMemoryTracking(bEnable); TRACE3("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 } TRACE0("ERROR: Critical memory allocation from safety pool failed!\n"); AfxThrowMemoryException(); // oops return 0; } #endif // !_AFX_PORTABLE /////////////////////////////////////////////////////////////////////////////