home *** CD-ROM | disk | FTP | other *** search
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and Microsoft
- // QuickHelp and/or WinHelp documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
-
- #include "stdafx.h"
-
- #ifdef AFX_CORE2_SEG
- #pragma code_seg(AFX_CORE2_SEG)
- #endif
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // System metrics etc
- /////////////////////////////////////////////////////////////////////////////
-
- AUX_DATA afxData;
-
- /////////////////////////////////////////////////////////////////////////////
- // Sub-Segment Allocation
-
- #pragma optimize("qgel", off) // assembler cannot be globally optimized
- //
- // Helper function for using LocalAlloc on arbitrary segments
- // returns either a long pointer to the handle (LHND flags used)
- // or a long pointer to the buffer allocated (LPTR flags used)
- //
- LPVOID PASCAL _AfxLocalAlloc(UINT sgmnt, UINT wFlags, UINT wBytes)
- {
- HANDLE hMem;
-
- _asm {
- push ds ; /* Save DS */
- mov ds, sgmnt ; /* get the segment to allocate within */
- }
-
- // Cannot use any globals here
-
- hMem = LocalAlloc(wFlags, wBytes);
-
- _asm {
- pop ds ; /* Restore DS */
- }
-
- if (hMem != NULL)
- return (LPVOID)MAKELONG(hMem, sgmnt);
- else
- return NULL;
- }
-
- //
- // Helper function for using LocalFree to free a memory block
- // allocated with _AfxLocalAlloc.
- //
- void PASCAL _AfxLocalFree(LPVOID lhBlock)
- {
- _asm {
- push ds ; /* Save DS */
- mov ds, WORD PTR lhBlock[2] ; /* Get the segment from the long pointer */
- }
-
- ::LocalFree((HLOCAL)_AFX_FP_OFF(lhBlock));
-
- _asm {
- pop ds ; /* Restore DS */
- }
- }
-
- //
- // Helper function for using LocalLock to Lock a memory block
- // allocated with _AfxLocalAlloc.
- //
- LPSTR PASCAL _AfxLocalLock(LPVOID lhBlock)
- {
- _asm {
- push ds ; /* Save DS */
- mov ds, WORD PTR lhBlock[2] ; /* Get the segment from the long pointer */
- }
-
- PSTR p = (PSTR)::LocalLock((HLOCAL)_AFX_FP_OFF(lhBlock));
-
- _asm {
- pop ds ; /* Restore DS */
- }
- return (LPSTR)MAKELONG(p, HIWORD(lhBlock));
- }
-
- //
- // Helper function for using LocalUnlock to Unlock a memory block
- // allocated with _AfxLocalAlloc.
- //
- BOOL PASCAL _AfxLocalUnlock(LPVOID lhBlock)
- {
- _asm {
- push ds ; /* Save DS */
- mov ds, WORD PTR lhBlock[2] ; /* Get the segment from the long pointer */
- }
-
- BOOL b = ::LocalUnlock((HLOCAL)_AFX_FP_OFF(lhBlock));
-
- _asm {
- pop ds ; /* Restore DS */
- }
- return b;
- }
- #pragma optimize("", on) // return to default optimizations
-
- /////////////////////////////////////////////////////////////////////////////
- // Other helpers
-
- // turn a file, relative path or other into an absolute path
- BOOL PASCAL _AfxFullPath(LPSTR lpszPathOut, LPCSTR lpszFileIn)
- // lpszPathOut = buffer of _MAX_PATH
- // lpszFileIn = file, relative path or absolute path
- // (both in ANSI character set)
- {
- ASSERT(AfxIsValidAddress(lpszPathOut, _MAX_PATH));
-
- OFSTRUCT of;
- if (OpenFile(lpszFileIn, &of, OF_PARSE) != HFILE_ERROR)
- {
- // of.szPathName is in the OEM character set
- OemToAnsi(of.szPathName, lpszPathOut);
- AnsiUpper(lpszPathOut); // paths in upper case just to be sure
- return TRUE;
- }
- else
- {
- TRACE1("Warning: could not parse the path %Fs\n", lpszFileIn);
- lstrcpy(lpszPathOut, lpszPathOut); // take it literally
- AnsiUpper(lpszPathOut); // paths in upper case just to be sure
- return FALSE;
- }
- }
-
- // like strncpy/fstrncpy but always zero terminate and don't zero fill
- void PASCAL _AfxStrCpy(LPSTR lpszDest, LPCSTR lpszSrc, size_t nSizeDest)
- {
- ASSERT(AfxIsValidAddress(lpszDest, nSizeDest));
- size_t nLen = lstrlen(lpszSrc);
- if (nLen > nSizeDest-1)
- {
- nLen = nSizeDest-1;
- TRACE2("Warning: truncating string '%Fs' to %d characters\n",
- lpszSrc, nLen);
- }
- _fmemcpy(lpszDest, lpszSrc, nLen);
- lpszDest[nLen] = '\0';
- }
-
- BOOL PASCAL _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 char BASED_CODE szComboBox[] = "combobox";
- char szCompare[sizeof(szComboBox) + 1];
- ::GetClassName(hWnd, szCompare, sizeof(szCompare));
- return (lstrcmpi(szCompare, szComboBox) == 0);
- }
-
-
- void PASCAL _AfxSmartSetWindowText(HWND hWndCtrl, LPCSTR lpszNew)
- {
- int nNewLen = lstrlen(lpszNew);
- char szOld[64];
- // fast check to see if text really changes (reduces flash in controls)
- if (nNewLen > sizeof(szOld) ||
- ::GetWindowText(hWndCtrl, szOld, sizeof(szOld)) != nNewLen ||
- lstrcmp(szOld, lpszNew) != 0)
- {
- // change it
- ::SetWindowText(hWndCtrl, lpszNew);
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
- // Initialization code
-
- #ifdef AFX_INIT_SEG
- #pragma code_seg(AFX_INIT_SEG)
- #endif
-
- AUX_DATA::AUX_DATA()
- {
- HDC hDCScreen = GetDC(NULL);
- ASSERT(hDCScreen != NULL);
-
- // System metrics
- cxVScroll = GetSystemMetrics(SM_CXVSCROLL);
- cyHScroll = GetSystemMetrics(SM_CYHSCROLL);
- cxIcon = GetSystemMetrics(SM_CXICON);
- cyIcon = GetSystemMetrics(SM_CYICON);
-
- // Device metrics for screen
- cxPixelsPerInch = GetDeviceCaps(hDCScreen, LOGPIXELSX);
- cyPixelsPerInch = GetDeviceCaps(hDCScreen, LOGPIXELSY);
- cySysFont = HIWORD(GetTextExtent(hDCScreen, "M", 1));
-
- // Border attributes
- hbrLtGray = ::CreateSolidBrush(RGB(192, 192, 192));
- hbrDkGray = ::CreateSolidBrush(RGB(128, 128, 128));
- ASSERT(hbrLtGray != NULL);
- ASSERT(hbrDkGray != NULL);
-
- // Cached system values (updated in CFrameWnd::OnSysColorChange)
- hbrBtnFace = NULL;
- hbrBtnShadow = NULL;
- hbrBtnHilite = NULL;
- UpdateSysColors();
-
- // Standard cursors
- hcurWait = ::LoadCursor(NULL, IDC_WAIT);
- hcurArrow = ::LoadCursor(NULL, IDC_ARROW);
- ASSERT(hcurWait != NULL);
- ASSERT(hcurArrow != NULL);
-
- // Clipboard formats
- static char BASED_CODE szNative[] = "Native";
- cfNative = ::RegisterClipboardFormat(szNative);
- ASSERT(cfNative != NULL);
- static char BASED_CODE szOwnerLink[] = "OwnerLink";
- cfOwnerLink = ::RegisterClipboardFormat(szOwnerLink);
- ASSERT(cfOwnerLink != NULL);
- static char BASED_CODE szObjectLink[] = "ObjectLink";
- cfObjectLink = ::RegisterClipboardFormat(szObjectLink);
- ASSERT(cfObjectLink != NULL);
-
- ReleaseDC(NULL, hDCScreen);
-
- WORD nVersion = LOWORD(::GetVersion());
- bWin31 = ((LOBYTE(nVersion) << 8) + HIBYTE(nVersion)) >= 0x030a;
- bWin30Compat = FALSE;
-
- // allocated on demand
- hStatusFont = NULL;
- hbmMenuDot = NULL;
- pfnFreeToolBar = NULL;
- }
-
- // Termination code
- AUX_DATA::~AUX_DATA()
- {
- // cleanup
- _AfxExitDelete(hbrLtGray);
- _AfxExitDelete(hbrDkGray);
- _AfxExitDelete(hbrBtnFace);
- _AfxExitDelete(hbrBtnShadow);
- _AfxExitDelete(hbrBtnHilite);
- _AfxExitDelete(afxDlgBkBrush);
-
- // clean up objects we don't actually create
- _AfxExitDelete(hStatusFont);
- _AfxExitDelete(hbmMenuDot);
- if (pfnFreeToolBar != NULL)
- (*pfnFreeToolBar)(); // toolbar cleanup uses _AfxExitDelete
- }
-
- void AUX_DATA::UpdateSysColors()
- {
- clrBtnFace = ::GetSysColor(COLOR_BTNFACE);
- clrBtnShadow = ::GetSysColor(COLOR_BTNSHADOW);
- if (bWin31)
- clrBtnHilite = ::GetSysColor(COLOR_BTNHIGHLIGHT);
- else
- clrBtnHilite = RGB(255,255,255);
- clrBtnText = ::GetSysColor(COLOR_BTNTEXT);
- clrWindowFrame = ::GetSysColor(COLOR_WINDOWFRAME);
-
- if (hbrBtnFace != NULL)
- ::DeleteObject(hbrBtnFace);
- if (hbrBtnShadow != NULL)
- ::DeleteObject(hbrBtnShadow);
- if (hbrBtnHilite != NULL)
- ::DeleteObject(hbrBtnHilite);
- hbrBtnFace = ::CreateSolidBrush(clrBtnFace);
- hbrBtnShadow = ::CreateSolidBrush(clrBtnShadow);
- hbrBtnHilite = ::CreateSolidBrush(clrBtnHilite);
- ASSERT(hbrBtnFace != NULL);
- ASSERT(hbrBtnShadow != NULL);
- ASSERT(hbrBtnHilite != NULL);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Other compatibility helpers for different versions of Windows
-
- void PASCAL _AfxExitDelete(HGDIOBJ hObject)
- {
- if (hObject != NULL)
- ::DeleteObject(hObject);
-
- #ifdef _WINDLL // any DLL
- #ifdef _DEBUG
- // Debug Kernel warns about these not being deleted but they really are
- // deleted when the DLL is implicitly loaded by Windows.
-
- // NOTE: you may wish to output a similar message in your application
- // if you rely on Windows to implicitly load and free your DLL.
- // If you explicitly load/free your DLL, this message is not needed.
-
- if (afxData.bWin31 && ::GetSystemMetrics(SM_DEBUG))
- {
- // Windows 3.0 does not always allow OutputDebugString in retail
-
- char szMsg[64];
- static char BASED_CODE szFormat[] =
- "wn MFC 2.0 GDI: Object has been safely deleted: %04X\r\n";
-
- if (hObject != NULL)
- {
- ASSERT(::wsprintf(szMsg, szFormat, hObject) < sizeof(szMsg));
- ::OutputDebugString(szMsg);
- }
- }
- #endif
- #endif
- }
-
- void PASCAL _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))
- {
- // try 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);
- }
-
- // Enable Win3.0 compatibility when running under Win3.1
- // See TN034 for more details.
- void AFXAPI AfxEnableWin30Compatibility()
- {
- afxData.bWin30Compat = TRUE;
- }
-
- /////////////////////////////////////////////////////////////////////////////
-