mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
6.2 KiB
220 lines
6.2 KiB
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
// Copyright (C) 1992-1995 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 <malloc.h>
|
|
|
|
#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
|
|
static const TCHAR szComboBox[] = _T("combobox");
|
|
TCHAR szCompare[_countof(szComboBox)+1];
|
|
::GetClassName(hWnd, szCompare, _countof(szCompare));
|
|
return lstrcmpi(szCompare, szComboBox) == 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);
|
|
}
|
|
|
|
#ifdef _MAC
|
|
// The EqualRect API provided by the Windows Portability Libraries for Macintosh
|
|
// returns true if the input rectangles are both empty, even if they do not have
|
|
// identical coordinates. _AfxIdenticalRect only returns true if the rectangles
|
|
// have exactly identical coordinates.
|
|
BOOL AFXAPI _AfxIdenticalRect(LPCRECT lpRectOne, LPCRECT lpRectTwo)
|
|
{
|
|
ASSERT(sizeof(RECT) == 4 * sizeof(LONG)); // require no gaps between fields
|
|
return memcmp(lpRectOne, lpRectTwo, sizeof(RECT)) == 0;
|
|
}
|
|
#endif //_MAC
|
|
|
|
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
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|