home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / MFC / SRC / AUXDATA.CP_ / AUXDATA.CP
Encoding:
Text File  |  1993-02-08  |  10.5 KB  |  374 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992 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 Microsoft
  7. // QuickHelp and/or WinHelp documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFX_CORE2_SEG
  14. #pragma code_seg(AFX_CORE2_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char BASED_CODE THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. /////////////////////////////////////////////////////////////////////////////
  23. // System metrics etc
  24. /////////////////////////////////////////////////////////////////////////////
  25.  
  26. AUX_DATA afxData;
  27.  
  28. /////////////////////////////////////////////////////////////////////////////
  29. // Sub-Segment Allocation
  30.  
  31. #pragma optimize("qgel", off) // assembler cannot be globally optimized
  32. //
  33. // Helper function for using LocalAlloc on arbitrary segments
  34. // returns either a long pointer to the handle (LHND flags used)
  35. // or a long pointer to the buffer allocated (LPTR flags used)
  36. //
  37. LPVOID PASCAL _AfxLocalAlloc(UINT sgmnt, UINT wFlags, UINT wBytes)
  38. {
  39.     HANDLE  hMem;
  40.  
  41.     _asm {
  42.         push    ds          ; /* Save DS */
  43.         mov     ds, sgmnt   ; /* get the segment to allocate within */
  44.     }
  45.  
  46.     // Cannot use any globals here
  47.  
  48.     hMem = LocalAlloc(wFlags, wBytes);
  49.  
  50.     _asm {
  51.         pop     ds          ; /* Restore DS */
  52.     }
  53.  
  54.     if (hMem != NULL)
  55.         return (LPVOID)MAKELONG(hMem, sgmnt);
  56.     else
  57.         return NULL;
  58. }
  59.  
  60. //
  61. // Helper function for using LocalFree to free a memory block
  62. // allocated with _AfxLocalAlloc.
  63. //
  64. void PASCAL _AfxLocalFree(LPVOID lhBlock)
  65. {
  66.     _asm {
  67.         push    ds              ; /* Save DS */
  68.         mov     ds, WORD PTR lhBlock[2] ; /* Get the segment from the long pointer */
  69.     }
  70.  
  71.     ::LocalFree((HLOCAL)_AFX_FP_OFF(lhBlock));
  72.  
  73.     _asm {
  74.         pop     ds              ; /* Restore DS */
  75.     }
  76. }
  77.  
  78. //
  79. // Helper function for using LocalLock to Lock a memory block
  80. // allocated with _AfxLocalAlloc.
  81. //
  82. LPSTR PASCAL _AfxLocalLock(LPVOID lhBlock)
  83. {
  84.     _asm {
  85.         push    ds              ; /* Save DS */
  86.         mov     ds, WORD PTR lhBlock[2] ; /* Get the segment from the long pointer */
  87.     }
  88.  
  89.     PSTR p = (PSTR)::LocalLock((HLOCAL)_AFX_FP_OFF(lhBlock));
  90.  
  91.     _asm {
  92.         pop     ds              ; /* Restore DS */
  93.     }
  94.     return (LPSTR)MAKELONG(p, HIWORD(lhBlock));
  95. }
  96.  
  97. //
  98. // Helper function for using LocalUnlock to Unlock a memory block
  99. // allocated with _AfxLocalAlloc.
  100. //
  101. BOOL PASCAL _AfxLocalUnlock(LPVOID lhBlock)
  102. {
  103.     _asm {
  104.         push    ds              ; /* Save DS */
  105.         mov     ds, WORD PTR lhBlock[2] ; /* Get the segment from the long pointer */
  106.     }
  107.  
  108.     BOOL b = ::LocalUnlock((HLOCAL)_AFX_FP_OFF(lhBlock));
  109.  
  110.     _asm {
  111.         pop     ds              ; /* Restore DS */
  112.     }
  113.     return b;
  114. }
  115. #pragma optimize("", on)    // return to default optimizations
  116.  
  117. /////////////////////////////////////////////////////////////////////////////
  118. // Other helpers
  119.  
  120. // turn a file, relative path or other into an absolute path
  121. BOOL PASCAL _AfxFullPath(LPSTR lpszPathOut, LPCSTR lpszFileIn)
  122.     // lpszPathOut = buffer of _MAX_PATH
  123.     // lpszFileIn = file, relative path or absolute path
  124.     // (both in ANSI character set)
  125. {
  126.     ASSERT(AfxIsValidAddress(lpszPathOut, _MAX_PATH));
  127.  
  128.     OFSTRUCT of;
  129.     if (OpenFile(lpszFileIn, &of, OF_PARSE) != HFILE_ERROR)
  130.     {
  131.         // of.szPathName is in the OEM character set
  132.         OemToAnsi(of.szPathName, lpszPathOut);
  133.         AnsiUpper(lpszPathOut); // paths in upper case just to be sure
  134.         return TRUE;
  135.     }
  136.     else
  137.     {
  138.         TRACE1("Warning: could not parse the path %Fs\n", lpszFileIn);
  139.         lstrcpy(lpszPathOut, lpszPathOut);  // take it literally
  140.         AnsiUpper(lpszPathOut); // paths in upper case just to be sure
  141.         return FALSE;
  142.     }
  143. }
  144.  
  145. // like strncpy/fstrncpy but always zero terminate and don't zero fill
  146. void PASCAL _AfxStrCpy(LPSTR lpszDest, LPCSTR lpszSrc, size_t nSizeDest)
  147. {
  148.     ASSERT(AfxIsValidAddress(lpszDest, nSizeDest));
  149.     size_t nLen = lstrlen(lpszSrc);
  150.     if (nLen > nSizeDest-1)
  151.     {
  152.         nLen = nSizeDest-1;
  153.         TRACE2("Warning: truncating string '%Fs' to %d characters\n",
  154.                 lpszSrc, nLen);
  155.     }
  156.     _fmemcpy(lpszDest, lpszSrc, nLen);
  157.     lpszDest[nLen] = '\0';
  158. }
  159.  
  160. BOOL PASCAL _AfxIsComboBoxControl(HWND hWnd, UINT nStyle)
  161. {
  162.     if (hWnd == NULL)
  163.         return FALSE;
  164.     // do cheap style compare first
  165.     if ((UINT)(::GetWindowLong(hWnd, GWL_STYLE) & 0x0F) != nStyle)
  166.         return FALSE;
  167.  
  168.     // do expensive classname compare next
  169.     static char BASED_CODE szComboBox[] = "combobox";
  170.     char szCompare[sizeof(szComboBox) + 1];
  171.     ::GetClassName(hWnd, szCompare, sizeof(szCompare));
  172.     return (lstrcmpi(szCompare, szComboBox) == 0);
  173. }
  174.  
  175.  
  176. void PASCAL _AfxSmartSetWindowText(HWND hWndCtrl, LPCSTR lpszNew)
  177. {
  178.     int nNewLen = lstrlen(lpszNew);
  179.     char szOld[64];
  180.     // fast check to see if text really changes (reduces flash in controls)
  181.     if (nNewLen > sizeof(szOld) ||
  182.         ::GetWindowText(hWndCtrl, szOld, sizeof(szOld)) != nNewLen ||
  183.         lstrcmp(szOld, lpszNew) != 0)
  184.     {
  185.         // change it
  186.         ::SetWindowText(hWndCtrl, lpszNew);
  187.     }
  188. }
  189.  
  190. /////////////////////////////////////////////////////////////////////////////
  191. /////////////////////////////////////////////////////////////////////////////
  192. // Initialization code
  193.  
  194. #ifdef AFX_INIT_SEG
  195. #pragma code_seg(AFX_INIT_SEG)
  196. #endif
  197.  
  198. AUX_DATA::AUX_DATA()
  199. {
  200.     HDC hDCScreen = GetDC(NULL);
  201.     ASSERT(hDCScreen != NULL);
  202.  
  203.     // System metrics
  204.     cxVScroll = GetSystemMetrics(SM_CXVSCROLL);
  205.     cyHScroll = GetSystemMetrics(SM_CYHSCROLL);
  206.     cxIcon = GetSystemMetrics(SM_CXICON);
  207.     cyIcon = GetSystemMetrics(SM_CYICON);
  208.  
  209.     // Device metrics for screen
  210.     cxPixelsPerInch = GetDeviceCaps(hDCScreen, LOGPIXELSX);
  211.     cyPixelsPerInch = GetDeviceCaps(hDCScreen, LOGPIXELSY);
  212.     cySysFont = HIWORD(GetTextExtent(hDCScreen, "M", 1));
  213.  
  214.     // Border attributes
  215.     hbrLtGray = ::CreateSolidBrush(RGB(192, 192, 192));
  216.     hbrDkGray = ::CreateSolidBrush(RGB(128, 128, 128));
  217.     ASSERT(hbrLtGray != NULL);
  218.     ASSERT(hbrDkGray != NULL);
  219.  
  220.     // Cached system values (updated in CFrameWnd::OnSysColorChange)
  221.     hbrBtnFace = NULL;
  222.     hbrBtnShadow = NULL;
  223.     hbrBtnHilite = NULL;
  224.     UpdateSysColors();
  225.         
  226.     // Standard cursors
  227.     hcurWait = ::LoadCursor(NULL, IDC_WAIT);
  228.     hcurArrow = ::LoadCursor(NULL, IDC_ARROW);
  229.     ASSERT(hcurWait != NULL);
  230.     ASSERT(hcurArrow != NULL);
  231.  
  232.     // Clipboard formats
  233.     static char BASED_CODE szNative[] = "Native";
  234.     cfNative = ::RegisterClipboardFormat(szNative);
  235.     ASSERT(cfNative != NULL);
  236.     static char BASED_CODE szOwnerLink[] = "OwnerLink";
  237.     cfOwnerLink = ::RegisterClipboardFormat(szOwnerLink);
  238.     ASSERT(cfOwnerLink != NULL);
  239.     static char BASED_CODE szObjectLink[] = "ObjectLink";
  240.     cfObjectLink = ::RegisterClipboardFormat(szObjectLink);
  241.     ASSERT(cfObjectLink != NULL);
  242.  
  243.     ReleaseDC(NULL, hDCScreen);
  244.  
  245.     WORD nVersion = LOWORD(::GetVersion());
  246.     bWin31 = ((LOBYTE(nVersion) << 8) + HIBYTE(nVersion)) >= 0x030a;
  247.     bWin30Compat = FALSE;
  248.  
  249.     // allocated on demand
  250.     hStatusFont = NULL;
  251.     hbmMenuDot = NULL;
  252.     pfnFreeToolBar = NULL;
  253. }
  254.  
  255. // Termination code
  256. AUX_DATA::~AUX_DATA()
  257. {
  258.     // cleanup
  259.     _AfxExitDelete(hbrLtGray);
  260.     _AfxExitDelete(hbrDkGray);
  261.     _AfxExitDelete(hbrBtnFace);
  262.     _AfxExitDelete(hbrBtnShadow);
  263.     _AfxExitDelete(hbrBtnHilite);
  264.     _AfxExitDelete(afxDlgBkBrush);
  265.  
  266.     // clean up objects we don't actually create
  267.     _AfxExitDelete(hStatusFont);
  268.     _AfxExitDelete(hbmMenuDot);
  269.     if (pfnFreeToolBar != NULL)
  270.         (*pfnFreeToolBar)();        // toolbar cleanup uses _AfxExitDelete
  271. }
  272.  
  273. void AUX_DATA::UpdateSysColors()
  274. {
  275.     clrBtnFace = ::GetSysColor(COLOR_BTNFACE);
  276.     clrBtnShadow = ::GetSysColor(COLOR_BTNSHADOW);
  277.     if (bWin31)
  278.         clrBtnHilite = ::GetSysColor(COLOR_BTNHIGHLIGHT);
  279.     else
  280.         clrBtnHilite = RGB(255,255,255);
  281.     clrBtnText = ::GetSysColor(COLOR_BTNTEXT);
  282.     clrWindowFrame = ::GetSysColor(COLOR_WINDOWFRAME);
  283.  
  284.     if (hbrBtnFace != NULL)
  285.         ::DeleteObject(hbrBtnFace);
  286.     if (hbrBtnShadow != NULL)
  287.         ::DeleteObject(hbrBtnShadow);
  288.     if (hbrBtnHilite != NULL)
  289.         ::DeleteObject(hbrBtnHilite);
  290.     hbrBtnFace = ::CreateSolidBrush(clrBtnFace);
  291.     hbrBtnShadow = ::CreateSolidBrush(clrBtnShadow);
  292.     hbrBtnHilite = ::CreateSolidBrush(clrBtnHilite);
  293.     ASSERT(hbrBtnFace != NULL);
  294.     ASSERT(hbrBtnShadow != NULL);
  295.     ASSERT(hbrBtnHilite != NULL);
  296. }
  297.  
  298. /////////////////////////////////////////////////////////////////////////////
  299. // Other compatibility helpers for different versions of Windows
  300.  
  301. void PASCAL _AfxExitDelete(HGDIOBJ hObject)
  302. {
  303.     if (hObject != NULL)
  304.         ::DeleteObject(hObject);
  305.  
  306. #ifdef _WINDLL      // any DLL
  307. #ifdef _DEBUG
  308.     // Debug Kernel warns about these not being deleted but they really are
  309.     // deleted when the DLL is implicitly loaded by Windows.
  310.  
  311.     // NOTE: you may wish to output a similar message in your application
  312.     // if you rely on Windows to implicitly load and free your DLL.
  313.     // If you explicitly load/free your DLL, this message is not needed.
  314.  
  315.     if (afxData.bWin31 && ::GetSystemMetrics(SM_DEBUG))
  316.     {
  317.         // Windows 3.0 does not always allow OutputDebugString in retail
  318.  
  319.         char szMsg[64];
  320.         static char BASED_CODE szFormat[] = 
  321.                     "wn MFC 2.0 GDI: Object has been safely deleted: %04X\r\n";
  322.  
  323.         if (hObject != NULL)
  324.         {
  325.             ASSERT(::wsprintf(szMsg, szFormat, hObject) < sizeof(szMsg));
  326.             ::OutputDebugString(szMsg);
  327.         }
  328.     }
  329. #endif
  330. #endif
  331. }
  332.  
  333. void PASCAL _AfxCancelModes(HWND hWndRcvr)
  334. {
  335.     // if we receive a message destined for a window, cancel any combobox
  336.     //  popups that could be in toolbars or dialog bars
  337.     HWND hWndCancel = ::GetFocus();
  338.     if (hWndCancel == NULL)
  339.         return;     // nothing to cancel
  340.  
  341.     if (hWndCancel == hWndRcvr)
  342.         return;     // let input go to window with focus
  343.  
  344.     // focus is in part of a combo-box
  345.     if (!_AfxIsComboBoxControl(hWndCancel, (UINT)CBS_DROPDOWNLIST))
  346.     {
  347.         // try as a dropdown
  348.         hWndCancel = ::GetParent(hWndCancel);   // parent of edit is combo
  349.         if (hWndCancel == hWndRcvr)
  350.             return;     // let input go to part of combo
  351.  
  352.         if (!_AfxIsComboBoxControl(hWndCancel, (UINT)CBS_DROPDOWN))
  353.             return;     // not a combo-box that is active
  354.     }
  355.  
  356.     // combo-box is active, but if receiver is a popup, do nothing
  357.     if (hWndRcvr != NULL &&
  358.       (::GetWindowLong(hWndRcvr, GWL_STYLE) & WS_CHILD) != 0 &&
  359.       ::GetParent(hWndRcvr) == ::GetDesktopWindow())
  360.         return;
  361.  
  362.     // finally, we should cancel the mode !
  363.     ::SendMessage(hWndCancel, CB_SHOWDROPDOWN, FALSE, 0L);
  364. }
  365.  
  366. // Enable Win3.0 compatibility when running under Win3.1
  367. //  See TN034 for more details.
  368. void AFXAPI AfxEnableWin30Compatibility()
  369. {
  370.     afxData.bWin30Compat = TRUE;
  371. }
  372.  
  373. /////////////////////////////////////////////////////////////////////////////
  374.