home *** CD-ROM | disk | FTP | other *** search
/ Troubleshooting Netware Systems / CSTRIAL0196.BIN / attach / msj / v10n04 / multilin.exe / NUMBFORM.CPP < prev    next >
C/C++ Source or Header  |  1995-04-01  |  8KB  |  261 lines

  1. // numbform.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "global.h"
  6. #include "numbform.h"
  7. #include "picture.h"
  8.  
  9. #ifdef _DEBUG
  10. #undef THIS_FILE
  11. static char BASED_CODE THIS_FILE[] = __FILE__;
  12. #endif
  13.  
  14. // GetNumberFormat does not provide picture definition
  15. // as GetDateFormat or GetTimeFormat do. This file provides
  16. // a simple implementation of such a facility. The implemen-
  17. // tation is split into two parts, an overloaded function 
  18. // int GetNumberFormat(
  19. //    LCID  lcid,            // locale of interest 
  20. //    DWORD  dwFlags,        // flags specifying function options 
  21. //    LPCTSTR    lpValue,    // number to be formatted 
  22. //    LPCTSTR  lpFormat,    // format string 
  23. //    LPTSTR  lpNumberStr,    // buffer for storing formatted string 
  24. //    int  cchNumber        // size of buffer 
  25. //   );    
  26. // that will parse an arbitrary string and break it into
  27. // pieces that can be handled individually by the built-in
  28. // Win32 GetNumberFormat function, and a class CPicture
  29. // that will transform the picture string pointed to by
  30. // lpFormat into the NUMBERFMT structure required by the
  31. // built-in GetNumberFormat.
  32.  
  33. int GetNumberFormat(LCID lcid, DWORD dwFlags, LPCTSTR lpValue, LPCTSTR lpFormat, LPTSTR lpNumber, UINT cchNumber)
  34. {
  35.     // If no format, just use defaults
  36.     if(lpFormat==NULL) 
  37.     {
  38.         return ::GetNumberFormat(lcid, dwFlags, lpValue, NULL, lpNumber, cchNumber);
  39.     }
  40.  
  41.     // Loop over format string
  42.     UINT cchMax = cchNumber;
  43.     BOOL fInEscape = FALSE;
  44.     while(*lpFormat && cchNumber) 
  45.     {
  46.         // strip ' escaped strings,
  47.         if( *lpFormat == _T('\'') )
  48.         {
  49.             // look ahead for '' to represent ' itself
  50.             if( fInEscape && *(lpFormat+1)==_T('\''))
  51.             {
  52.                 // Copy ' character
  53.                 *lpNumber++=*lpFormat++;
  54.                 cchNumber--;
  55.             } 
  56.             else
  57.             {
  58.                 fInEscape = !fInEscape;
  59.             }
  60.             // Always eat at least one ' character
  61.             lpFormat++;
  62.             continue; 
  63.         }
  64.         if( fInEscape )
  65.         {
  66.             // Copy one character
  67.             *lpNumber++=*lpFormat++;
  68.             cchNumber--;
  69.             continue;
  70.         }
  71.         // Try to parse this character as a number picture
  72.         CPicture pict(lpFormat, lcid, dwFlags );
  73.         UINT cchFormat=pict.m_Length;
  74.         if(cchFormat)
  75.         {
  76.             // Have a numeric picture in the lpInput stream
  77.             // Insert the formatted number    
  78.             
  79.             UINT cchOut=GetNumberFormat(lcid, 0, lpValue, &pict, lpNumber, cchNumber);
  80.             if( !cchOut )
  81.             {
  82.                 // some error
  83.                 return 0;
  84.             }
  85.             // Account for lpInput and output string used up
  86.             lpFormat+=cchFormat;
  87.             cchNumber-=(cchOut-1);
  88.             lpNumber+=(cchOut-1);
  89.             continue;
  90.         }
  91.         // Current character in lpInput string is not part of a
  92.         // numeric picture, echo directly
  93.         *lpNumber++=*lpFormat++;
  94.         cchNumber--;
  95.     }           
  96.     // terminate
  97.     *lpNumber=_T('\0');
  98.     return cchMax - cchNumber + 1; // # of characters in output    
  99. }
  100.  
  101. /////////////////////////////////////////////////////////////////////////////
  102. // CNumbFormat dialog
  103.  
  104. CNumbFormat::CNumbFormat(CWnd* pParent /*=NULL*/)
  105.     : CDialog(CNumbFormat::IDD, pParent)
  106. {
  107.     //{{AFX_DATA_INIT(CNumbFormat)
  108.         // NOTE: the ClassWizard will add member initialization here
  109.     //}}AFX_DATA_INIT
  110. }
  111.  
  112.  
  113. void CNumbFormat::DoDataExchange(CDataExchange* pDX)
  114. {
  115.     CDialog::DoDataExchange(pDX);
  116.     //{{AFX_DATA_MAP(CNumbFormat)
  117.         // NOTE: the ClassWizard will add DDX and DDV calls here
  118.     //}}AFX_DATA_MAP
  119. }
  120.  
  121.  
  122. BEGIN_MESSAGE_MAP(CNumbFormat, CDialog)
  123.     //{{AFX_MSG_MAP(CNumbFormat)
  124.     ON_EN_CHANGE(IDC_CUSTOM, OnChangeCustom)
  125.     ON_LBN_DBLCLK(IDC_NUMBFORMATS, OnDblclkNumbformats)
  126.     //}}AFX_MSG_MAP
  127. END_MESSAGE_MAP()
  128.  
  129.  
  130. /////////////////////////////////////////////////////////////////////////////
  131. // CNumbFormat message handlers
  132.  
  133. BOOL CNumbFormat::OnInitDialog() 
  134. {
  135.     CDialog::OnInitDialog();
  136.     
  137.     // TODO: Add extra initialization here
  138.     AppendNumberFormat( LOCALE_NOUSEROVERRIDE);         
  139.     AppendNumberFormat( LOCALE_UNRESTRICTED);         
  140.  
  141.     SendDlgItemMessage( IDC_NUMBFORMATS, LB_SETCURSEL, 0, 0);
  142.     SendMessage( WM_COMMAND, IDC_NUMBFORMATS, 0);
  143.  
  144.     // Format a sample date
  145.     OnDblclkNumbformats();    
  146.  
  147.  
  148.     return TRUE;  // return TRUE unless you set the focus to a control
  149.                   // EXCEPTION: OCX Property Pages should return FALSE
  150. }
  151.  
  152.  
  153.   #define STRINGLEN 128
  154.  
  155. /////////////////////////////////////////////////////
  156. // EnumNumberFormatsProc
  157. //
  158. // Add the given date format string to the list box and
  159. // set that item's data to LOCALE_NOUSEROVERRIDE or not
  160.  
  161. #define MAXSAMPLELEN 128
  162. #define MAXNUMBERFORMAT 50
  163.  
  164. ////////////////////////////////
  165. // ShowSampleNumber
  166. //
  167.  
  168. void CNumbFormat::ShowSampleNumber( CString& szNumberFormat, DWORD dwNumberFlags)
  169. {
  170.     static TCHAR szSampleNumber[ MAXSAMPLELEN];
  171.  
  172.     GetNumberFormat( GetThreadLocale(),      // use this thread's locale
  173.                    dwNumberFlags,            // flags passed into this function
  174.                    _T("0.7890"),                    // sample positive numeric value
  175.                    szNumberFormat,           // format seleted by user
  176.                    szSampleNumber,           // for formatted number
  177.                    MAXSAMPLELEN);            // number buffer length
  178.  
  179.     SetDlgItemText( IDC_POSFORMAT, szSampleNumber);
  180.     
  181.     GetNumberFormat( GetThreadLocale(),      // use this thread's locale
  182.                    dwNumberFlags,            // flags passed into this function
  183.                    _T("-123456.7890"),           // sample numeric value
  184.                    szNumberFormat,           // format seleted by user
  185.                    szSampleNumber,           // for formatted number
  186.                    MAXSAMPLELEN);            // number buffer length
  187.  
  188.     SetDlgItemText( IDC_NEGFORMAT, szSampleNumber);
  189. }
  190.  
  191. BOOL  CNumbFormat::AppendNumberFormat( DWORD dwFlags)     
  192. {
  193.     static TCHAR szTmp[STRINGLEN] = TEXT("");
  194.     LONG lTmp;
  195.     LONG lIndex = SendDlgItemMessage( IDC_NUMBFORMATS,
  196.                                       LB_GETCOUNT,
  197.                                       0, 0);
  198.     CPicture pix(GetThreadLocale(), dwFlags);
  199.     int nBufLen = pix.m_Length;
  200.     if ( nBufLen == 0 )
  201.     {
  202.         LONG lRC = GetLastError();
  203.     }
  204.  
  205.                                 // Is this format string already in the list?
  206.     for ( lTmp = 0; lTmp < lIndex; ++lTmp )
  207.     {
  208.         SendDlgItemMessage( IDC_NUMBFORMATS,
  209.                             LB_GETTEXT,
  210.                             lTmp,
  211.                             (LPARAM)szTmp);
  212.  
  213.         if ( lstrcmp( pix, szTmp) == 0 )
  214.             return( TRUE);      // Already in list
  215.     }
  216.     lIndex = SendDlgItemMessage( IDC_NUMBFORMATS,
  217.                                  LB_ADDSTRING, 
  218.                                  0, 
  219.                                  (LPARAM)(LPCTSTR)pix);
  220.  
  221.     if ( ! (lIndex = LB_ERR || lIndex == LB_ERRSPACE) )
  222.     {
  223.         return( SendDlgItemMessage( IDC_NUMBFORMATS,
  224.                                     LB_SETITEMDATA, 
  225.                                     lIndex, 
  226.                                     (LPARAM)dwFlags) == LB_ERR ? FALSE : TRUE);
  227.     }
  228.     return( FALSE);
  229. }
  230.  
  231. void CNumbFormat::OnChangeCustom() 
  232. {
  233.     // TODO: Add your control notification handler code here
  234.     CString szNumberFormat;
  235.     SendDlgItemMessage( IDC_CUSTOM, 
  236.                         WM_GETTEXT,
  237.                         MAXNUMBERFORMAT, 
  238.                         (LPARAM)(szNumberFormat.GetBufferSetLength(MAXNUMBERFORMAT)));
  239.     DWORD dwNumberFlags = 0;
  240.  
  241.     ShowSampleNumber( szNumberFormat, dwNumberFlags);
  242. }
  243.  
  244. void CNumbFormat::OnDblclkNumbformats() 
  245. {
  246.     // TODO: Add your control notification handler code here
  247.     
  248.     LONG lIndex = SendDlgItemMessage( IDC_NUMBFORMATS, 
  249.                                       LB_GETCURSEL, 0, 0);
  250.  
  251.     CString szNumberFormat;
  252.     SendDlgItemMessage( IDC_NUMBFORMATS, 
  253.                         LB_GETTEXT,
  254.                         (WPARAM)lIndex, 
  255.                         (LPARAM)(szNumberFormat.GetBufferSetLength(MAXNUMBERFORMAT)));
  256.     DWORD dwNumberFlags = SendDlgItemMessage( IDC_NUMBFORMATS, 
  257.                                                   LB_GETITEMDATA, 
  258.                                                   (WPARAM)lIndex, 0);
  259.     ShowSampleNumber( szNumberFormat, dwNumberFlags);
  260. }
  261.