aboutdlg.cpp

来自「《ATL深入解析》随书源码」· C++ 代码 · 共 659 行 · 第 1/2 页

CPP
659
字号
// AboutDlg.cpp : Implementation of CAboutDlg
#include "stdafx.h"
#include "AboutDlg.h"
#include <windowsx.h>
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg

// Function prototypes for message handlers

static BOOL AboutDlg_OnInitDialog (HWND hwnd, HWND hwndFocus, LPARAM lParam) ;
static void AboutDlg_OnCommand (HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) ;

typedef enum { typeDefault        = 0,
               typeAdvancedServer = 1,
               typeWorkstation    = 2,
               typeServer         = 3 } NTTYPE ;

static NTTYPE GetNTVersion () ;

// Function prototypes for static functions

static void  DisplayExecutableVersionInfo (HWND hwnd) ;
static void  DisplayOperatingSystemVersionInfo (HWND hwnd) ;
static void  DisplayProcessorVersionInfo (HWND hwnd) ;

static DWORD FormatMessageFromString (LPCTSTR szFormat, LPTSTR  szBuffer, DWORD nSize, ...) ;

LRESULT CAboutDlg::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    // Center the dialog window
    CenterWindow () ;

    // Update controls with application version info
    DisplayExecutableVersionInfo (m_hWnd) ;

    // Update controls with operating system version info
    DisplayOperatingSystemVersionInfo (m_hWnd) ;

    // Update controls with processor version info
    DisplayProcessorVersionInfo (m_hWnd) ;

    return TRUE ;   // Let the system set the focus
}

//
// 040904B0 means US English, Unicode code page
// 040904E4 means US English, Windows MultiLingual code page
static const TCHAR szValueNameBase [] = TEXT("\\StringFileInfo\\040904B0\\") ;
static const TCHAR szProductName []   = TEXT("ProductName") ;

// Number of characters in the base portion of the value name string
#define BASECHARS    (DIM(szValueNameBase) - 1)

//
//  void DisplayExecutableVersionInfo (HWND hwnd)
//
//  hwnd            Window handle for the dialog box window
//
//  PURPOSE:        Retrieves the application's version resource
//                  infomation and displays the info in the
//                  appropriate dialog box controls.
//
//  COMMENTS:       This implementation uses the initial control
//                  window text as a version info value key. This
//                  function displays the value retrieved for a
//                  key in the respective control.
//

#define DIM(a) (sizeof(a)/sizeof(a[0]))

static void
DisplayExecutableVersionInfo (HWND hwnd)
{
	BOOL                bResult ;               // Result of Boolean functions
    DWORD               dwVerInfoSize ;         // Size of version information
    DWORD               dwHandle ;              // Extraneous but required parameter
    HMODULE             hmod ;                  // Application's module handle
    HWND                hwndControl ;           // Control window handle
    LPVOID              pVerInfo ;              // File version info pointer
    LPVOID              pValue ;                // Value from version info
	TCHAR               szFullPath [_MAX_PATH] ;// Application executable path
	TCHAR               szValueName [256] ;     // Name of value to retrieve
    UINT                uLength ;               // Length of retrieved value

    // Get the full path to this server
    hmod = _Module.GetModuleInstance() ;
    ::GetModuleFileName (hmod, szFullPath, DIM(szFullPath)) ;

    // Determine the size buffer needed to store the version information:
    dwVerInfoSize = GetFileVersionInfoSize (szFullPath, &dwHandle) ;
    if (0 == dwVerInfoSize)
        return ;

    // Allocate a buffer for the version info block
    pVerInfo = new char [dwVerInfoSize] ;
    ATLASSERT (NULL != pVerInfo) ;
    if (NULL == pVerInfo)
        return ;

    // Read the version info block into the buffer
    GetFileVersionInfo (szFullPath, dwHandle, dwVerInfoSize, pVerInfo) ;

    // Build value name base string...
	lstrcpy (szValueName, szValueNameBase) ;
	
	// Build the \StringFileInfo\040904E4\ProductName value name
	lstrcpy (szValueName + BASECHARS, szProductName) ;

	// Retrieve the value
    bResult = ::VerQueryValue (pVerInfo, szValueName, &pValue, &uLength) ;

    // Format the output for the dialog caption
    // Get the current caption then append to it the ProductName value
    GetWindowText (hwnd, szValueName, DIM (szValueName)) ;
	lstrcat (szValueName, reinterpret_cast <LPCTSTR>(pValue)) ;

    // Change the dialog caption - normally "About <ProductName>"
	SetWindowText (hwnd, szValueName) ;

	// For each control in the dialog...
    //  fetch the version info name from the control's initial window text.
    //  retrieve the value with that name,
    //  change the control's window text to the retrieved value.
    // Technique derived from GENERIC.C.

    hwndControl = GetFirstChild (hwnd) ;
    while (NULL != hwndControl) {
        // Build value name base string...
	    lstrcpy (szValueName, szValueNameBase) ;
	
    	// Build the \StringFileInfo\040904E4\<ControlText> value name
        // The Win32 API contains the following predefined version information strings:
        //     CompanyName              LegalCopyright     
        //     FileDescription          OriginalFilename   
        //     FileVersion              ProductName        
        //     InternalName             ProductVersion     
        
        // Get the control's text...
        GetWindowText (hwndControl,
                       szValueName + BASECHARS,
                       DIM(szValueName) - BASECHARS) ;

	    // Retrieve the value
	    bResult = VerQueryValue (pVerInfo, szValueName, &pValue, &uLength) ;

        // If version information is available and the version information name exists...
        if (bResult)
            // If a value exists for the version information name...
            if (0 != uLength && NULL != pValue)
                // Change the control's text to the version information value
                SetWindowText (hwndControl, reinterpret_cast<LPCTSTR>(pValue)) ;

        hwndControl = GetNextSibling (hwndControl) ;
    }

    // Free the memory for the version information block
    delete [] pVerInfo ;
}


//
//  DWORD DisplayOperatingSystemVersionInfo (HWND hwnd)
//
//  hwnd            Window handle for the dialog box window
//
//  PURPOSE:        Displays the operating system's version
//
//  COMMENTS:
//

static void
DisplayOperatingSystemVersionInfo (HWND hwnd)
{
    BOOL                bResult ;
    HINSTANCE           hinst ;
    NTTYPE              NtOsType ;
    TCHAR               szOSVer [256] ;
    TCHAR               szFormatString [256] ;

    // Get OS version information
    OSVERSIONINFO       osver ;
    osver.dwOSVersionInfoSize = sizeof (osver) ;    // Must initialize size member!

    bResult = GetVersionEx (&osver) ;       // Retrieve version info
    ATLASSERT (FALSE != bResult) ;
    if (FALSE == bResult)
        return ;

    hinst = GetWindowInstance (hwnd) ;      // Get instance for LoadString

    switch (osver.dwPlatformId) {
        case VER_PLATFORM_WIN32_NT:         // Windows NT
            NtOsType = GetNTVersion () ;
            LoadString (hinst, IDS_PLATFORM_WIN32_NT + NtOsType,
                        szFormatString, DIM (szFormatString)) ;
            break ;

        case VER_PLATFORM_WIN32s:           // Win32s on Windows 3.1
            LoadString (hinst, IDS_PLATFORM_WIN32s,
                        szFormatString, DIM (szFormatString)) ;
            break ;

        case VER_PLATFORM_WIN32_WINDOWS:     // Windows 95/98
            if ((osver.dwMajorVersion > 4) ||
                (osver.dwMajorVersion == 4) && (osver.dwMinorVersion > 0)) {
                // Windows 98
                LoadString (hinst, IDS_PLATFORM_WIN32_WINDOWS98,
                            szFormatString, DIM (szFormatString)) ;
                // Windows 95 encodes extra info in HIWORD(dwBuildNumber)
                // Remove unwanted junk
                osver.dwBuildNumber = LOWORD (osver.dwBuildNumber) ;
            }
            else {
                // Windows 95
                LoadString (hinst, IDS_PLATFORM_WIN32_WINDOWS95,
                            szFormatString, DIM (szFormatString)) ;
                // Windows 95 encodes extra info in HIWORD(dwBuildNumber)
                // Remove unwanted junk
                osver.dwBuildNumber = LOWORD (osver.dwBuildNumber) ;
            }
            break ;

        default:                            // Unknown operating system
            LoadString (hinst, IDS_PLATFORM_UNKNOWN,
                        szFormatString, DIM (szFormatString)) ;
            break ;
    }

    wsprintf (szOSVer, szFormatString,
              osver.dwMajorVersion,
              osver.dwMinorVersion,
              osver.dwBuildNumber) ;
    SetDlgItemText (hwnd, IDC_ABOUT_OSVERSION, szOSVer) ;
}


//
//  void DisplayProcessorVersionInfo (HWND hwnd, DWORD dwPlatformId)
//
//  hwnd            Window handle for the dialog box window
//  dwPlatformId    Hardware platform ID returned by GetVersionEx
//
//  PURPOSE:        Displays the processor's version
//
//  COMMENTS:
//

static void
DisplayProcessorVersionInfo (HWND hwnd)
{
    BOOL                bRecognized ;
    HINSTANCE           hinst ;
    SYSTEM_INFO         si ;
    TCHAR               szBuffer [256] ;
    TCHAR               szFormat [256] ;

    // Get current system information
    // Zero the structure as Windows 95 and older versions of Windows NT
    // do not initialize *all* fields of the structure (specifically,
    // wProcessorLevel and wProcessorRevision. Unfortunately, the
    // documentation does not say *which* versions of Windows NT do not
    // support setting these fields. Therefore use the new fields if
    // they seem to have been set. otherwise use the "obsolete" fields.

    ZeroMemory (&si, sizeof (si)) ;
    GetSystemInfo (&si) ;
    
    hinst = GetWindowInstance (hwnd) ;      // Get instance for LoadString

    // Determine processor architecture
    bRecognized = TRUE ;
    switch (si.wProcessorArchitecture) {
        default:
            bRecognized = FALSE ;
            LoadString (hinst, IDS_PROCESSOR_ARCHITECTURE_UNKNOWN,
                        szBuffer, DIM (szBuffer)) ;
            break ;

        case PROCESSOR_ARCHITECTURE_INTEL:  // Intel
            switch (si.wProcessorLevel) {
                default:
                    bRecognized = FALSE ;
                    LoadString (hinst,
                                IDS_PROCESSOR_LEVEL_INTEL_UNKNOWN,
                                szBuffer, DIM (szBuffer)) ;
                    break ;

                case 3:                     // Intel 80386
                    LoadString (hinst,
                                IDS_PROCESSOR_ARCHITECTURE_INTEL_386_486,
                                szFormat, DIM (szFormat)) ;
                    FormatMessageFromString (
                        szFormat,
                        szBuffer, DIM (szBuffer),
                        TEXT ("80386"),
                        LOBYTE (si.wProcessorRevision)) ;
                    break ;

                case 4:                     // Intel 80486
                    LoadString (hinst,
                                IDS_PROCESSOR_ARCHITECTURE_INTEL_386_486,
                                szFormat, DIM (szFormat)) ;
                    FormatMessageFromString (
                        szFormat,
                        szBuffer, DIM (szBuffer),
                        TEXT ("80486"),
                        LOBYTE (si.wProcessorRevision)) ;
                    break ;

                case 5:                     // Intel Pentium
                    LoadString (hinst,
                                IDS_PROCESSOR_ARCHITECTURE_INTEL_PENTIUM,
                                szFormat, DIM (szFormat)) ;
                    switch (HIBYTE(si.wProcessorRevision)) {
                    default:
                    FormatMessageFromString (
                        szFormat,
                        szBuffer, DIM (szBuffer),
                        TEXT ("Pentium"),
                        HIBYTE (si.wProcessorRevision),
                        LOBYTE (si.wProcessorRevision)) ;
                    break ;
                    case 4:
                    FormatMessageFromString (
                        szFormat,
                        szBuffer, DIM (szBuffer),
                        TEXT ("Pentium with MMX"),
                        HIBYTE (si.wProcessorRevision),
                        LOBYTE (si.wProcessorRevision)) ;
                    break;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?