INSTALL.C
上传用户:shijixite
上传日期:2007-01-03
资源大小:108k
文件大小:11k
源码类别:

输入法编程

开发平台:

Visual C++

  1. /**************************************************************************
  2. * install.c -- install c_*.nls conversion tables.
  3. *
  4. *         Steve Firebaugh
  5. *         Microsoft Developer Support
  6. *         Copyright (c) 1992-1997 Microsoft Corporation
  7. *
  8. *
  9. *
  10. * Note, this module must have UNICODE defined because the registry
  11. *  code will not work without it.
  12. *
  13. **************************************************************************/
  14. #define UNICODE
  15. #include <windows.h>
  16. #include <commdlg.h>
  17. #include <string.h>
  18. #include <stdio.h>
  19. #include "uconvert.h"
  20. #include "install.h"
  21. /**************************************************************************
  22. *  Global variables.
  23. **************************************************************************/
  24. /* This is the registry key that we store conversion table information under. */
  25. TCHAR NlsRegEntryStr[]=TEXT("SYSTEM\CurrentControlSet\Control\Nls\CodePage");
  26. /***************************************************************************
  27. *    FUNCTION: InstallTableProc
  28. *
  29. * Dialog window procedure for the Install *.nls tables dialog.
  30. *
  31. ***************************************************************************/
  32. LRESULT CALLBACK InstallTableProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  33. {
  34.   switch (message) {
  35.     /**********************************************************************
  36.     *  WM_INITDIALOG
  37.     *
  38.     * Fill dialog with a list of the currently existing tables.
  39.     **********************************************************************/
  40.     case WM_INITDIALOG:
  41.       if (!ListInstalledTables (GetDlgItem (hwnd, DID_LISTBOX), LB_ADDSTRING, FALSE))
  42.         EndDialog (hwnd, FALSE);
  43.         return TRUE;
  44.     break;
  45.     case WM_COMMAND:
  46.       switch (wParam) {
  47.         case IDCANCEL:
  48.         case IDOK:
  49.           EndDialog (hwnd, TRUE);
  50.         break;
  51.         /**********************************************************************
  52.         *  WM_COMMAND, BID_ADD
  53.         *
  54.         * Use common dialog, get new *.nls name, and try to install it.
  55.         **********************************************************************/
  56.         case BID_ADD:
  57.           if (GetTableFileNames(hwnd))
  58.             ListInstalledTables (GetDlgItem (hwnd, DID_LISTBOX), LB_ADDSTRING, FALSE);
  59.         break;
  60.       }
  61.     break; /* end WM_COMMAND */
  62.     case WM_SYSCOMMAND:
  63.       if (wParam == SC_CLOSE)
  64.         EndDialog (hwnd, TRUE);
  65.     break; /* end WM_SYSCOMMAND */
  66.   } /* end switch */
  67.   return FALSE;
  68. }
  69. /***************************************************************************
  70. *    FUNCTION: GetTableFileNames
  71. *
  72. * Throw up a common dialog to the user, and let them search for the *.nls
  73. *  file to install.
  74. *
  75. * LIMITATION:  Currently only works for one file at a time.
  76. *  Should rewrite to accept multiple files.
  77. *
  78. ***************************************************************************/
  79. int GetTableFileNames (HWND hwnd)
  80. {
  81.     OPENFILENAME OpenFileName;
  82.     /* buffers for the file names. */
  83.     TCHAR szFile[MAX_PATH],szFileTitle[MAX_PATH];
  84.     TCHAR szFilter[MAX_PATH], buffer[50];
  85.     TCHAR *p;
  86.     /* Build up the correct filter strings for OPENFILENAME structure */
  87.     p = szFilter;
  88.     lstrcpy (buffer,LoadResourceString(IDS_FILE_FILTER_SPEC4));
  89.     lstrcpy (p,buffer);
  90.     p += lstrlen (buffer) +1;
  91.     lstrcpy (buffer,TEXT("*.nls"));
  92.     lstrcpy (p,buffer);
  93.     p += lstrlen (buffer) +1;
  94.     lstrcpy (p,TEXT(""));
  95.     wsprintf (szFile, TEXT(""));
  96.     wsprintf (szFileTitle, TEXT(""));
  97.     OpenFileName.lStructSize       = sizeof(OPENFILENAME);
  98.     OpenFileName.hwndOwner         = hwnd;
  99.     OpenFileName.hInstance         = NULL;
  100.     OpenFileName.lpstrFilter       = szFilter;
  101.     OpenFileName.lpstrCustomFilter = NULL;
  102.     OpenFileName.nMaxCustFilter    = 0L;
  103.     OpenFileName.nFilterIndex      = 1L;
  104.     OpenFileName.lpstrFile         = szFile;
  105.     OpenFileName.nMaxFile          = MAX_PATH;
  106.     OpenFileName.lpstrFileTitle    = szFileTitle;
  107.     OpenFileName.nMaxFileTitle     = MAX_PATH;
  108.     OpenFileName.lpstrInitialDir   = NULL;
  109.     OpenFileName.lpstrTitle        = LoadResourceString(IDS_TABLE_FILE_TITLE);
  110.     OpenFileName.nFileOffset       = 0;
  111.     OpenFileName.nFileExtension    = 0;
  112.     OpenFileName.lpstrDefExt       = NULL;
  113.     OpenFileName.lCustData         = 0;
  114.     OpenFileName.lpfnHook          = NULL;
  115.     OpenFileName.lpTemplateName    = NULL;
  116. //    OpenFileName.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT;
  117.     OpenFileName.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST ;
  118.     if (!GetOpenFileName(&OpenFileName)) return 0;
  119.     return (InstallFile (szFile,szFileTitle));
  120. }
  121. /***************************************************************************
  122. *    FUNCTION: InstallFile
  123. *
  124. * Given full path name, and just file name, copy that file into the
  125. *  system directory, and change the registry to indicate that the file
  126. *  has now been "installed."
  127. *
  128. ***************************************************************************/
  129. int InstallFile (TCHAR* szPathAndName, TCHAR* szName)
  130. {
  131. TCHAR szTargetFile[MAX_PATH], buffer[MAX_PATH];
  132. TCHAR keyname[MAX_PATH];
  133. HKEY hKey;
  134. int cp, nChar;
  135. LONG rValue;
  136.     /* First verify that they have selected a valid file name. */
  137.     CharLowerBuff (szName,lstrlen (szName));
  138.     if (myScanf (szName, &cp) != 1) {
  139.       MessageBox (NULL, LoadResourceString(IDS_INCORRECT_FILE_TYPE),
  140.                         NULL, MB_ICONSTOP | MB_OK);
  141.       return FALSE;
  142.     }
  143.     /* Build up a complete path name for the target file.
  144.      *  Get the system directory, and prepend it before szName.
  145.      */
  146.     GetSystemDirectory (buffer, MAX_PATH);
  147.     nChar = wsprintf (szTargetFile, TEXT("%s\%s"), buffer, szName);
  148.     if (nChar >= MAX_PATH) {
  149.       MessageBox (NULL, LoadResourceString(IDS_FILENAME_OVERFLOW),NULL, MB_ICONSTOP | MB_OK);
  150.       return FALSE;
  151.     }
  152.     /* Now, try to open the registry for writing... This may fail if
  153.      *  the current user has insufficient privilege, or it may fail
  154.      *  for other, unforeseen, reasons.
  155.      */
  156.     rValue = RegOpenKeyEx (HKEY_LOCAL_MACHINE, NlsRegEntryStr, 0, KEY_SET_VALUE, &hKey);
  157.     if (rValue == ERROR_ACCESS_DENIED) {
  158.       MessageBox (NULL, LoadResourceString(IDS_LOGON_AS_ADMIN),
  159.                LoadResourceString(IDS_ACCESS_DENIED), MB_ICONSTOP | MB_OK);
  160.       return FALSE;
  161.     }
  162.     if (rValue != ERROR_SUCCESS) {
  163.       MessageBox (NULL, LoadResourceString(IDS_REGOPENKEYEX_FAILED),NULL, MB_ICONSTOP | MB_OK);
  164.       return FALSE;
  165.     }
  166.     /* Try to copy file... one reason for failure is file already
  167.      *  exists.  If so, query the user to try again.
  168.      *  If fails again, just report problem and exit.
  169.      */
  170.     if (!CopyFile (szPathAndName, szTargetFile, TRUE)) {
  171.       /* if failure was from existing file, query user preference
  172.        *  regarding replacing it.
  173.        */
  174.       if (GetLastError() == ERROR_FILE_EXISTS) {
  175.         if (MessageBox (NULL, LoadResourceString(IDS_FILE_ALREADY_EXISTS),
  176.                         LoadResourceString(IDS_APP_WARNING),
  177.                         MB_ICONEXCLAMATION | MB_YESNO) == IDNO) {
  178.           goto close_and_exit;
  179.         } else {
  180.           if (!CopyFile (szPathAndName, szTargetFile, FALSE)) {
  181.             MessageBox (NULL, LoadResourceString(IDS_FILE_CP_FAILED_AGAIN),
  182.                           NULL, MB_ICONSTOP | MB_OK);
  183.             goto close_and_exit;
  184.           }
  185.         }
  186.       /* no duplicate file, CopyFile() failed for other reasons
  187.        *  report failure and return.
  188.        */
  189.       } else {
  190.         MessageBox (NULL, LoadResourceString(IDS_FILE_CP_FAILED),
  191.                       NULL, MB_ICONSTOP | MB_OK);
  192.         goto close_and_exit;
  193.       }
  194.     }
  195.     /* Finally, write the new key value to the registry. */
  196.     if (myScanf (szName, &cp) == 1) {
  197.       wsprintf (keyname, TEXT("%d"), cp);
  198.       RegSetValueEx (hKey, keyname, 0, REG_SZ, (LPBYTE)szName,
  199.                      (DWORD)((lstrlen(szName) +1)*sizeof(TCHAR)));
  200.     } else
  201.       MessageBox (NULL, szName, LoadResourceString(IDS_FILE_PARSE_FAILED),
  202.               MB_ICONSTOP | MB_OK);
  203. close_and_exit:
  204.     RegCloseKey (hKey);
  205.     return TRUE;
  206. }
  207. /***************************************************************************
  208. *    FUNCTION: ListInstalledTables
  209. *
  210. * Display the *.nls conversion tables currently installed, according to the
  211. *  registry.  Display either the file name, or just the codepage number.
  212. *
  213. * hwndFill - listbox or combobox to fill with names.
  214. * message - LB_ADDSTRING or CB_ADDSTRING
  215. * NumberOnly - FALSE then use full file name, TRUE then just use number.
  216. *
  217. * CRITERION for table being installed:
  218. *  value in registry is c_* where * is number.
  219. *
  220. ***************************************************************************/
  221. int ListInstalledTables (HWND hwndFill, UINT message, int NumberOnly)
  222. {
  223.   TCHAR szKeyname[MAX_PATH], szValue[MAX_PATH];
  224.   DWORD cBytesName, cBytesValue, iSubKey;
  225.   int  cp;
  226.   HKEY hKey;
  227.   /* open the registry key for reading.  If failure, report and exit. */
  228.   if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, NlsRegEntryStr, 0, KEY_QUERY_VALUE, &hKey)) {
  229.     MessageBox (NULL, LoadResourceString(IDS_REGOPENKEYEX_FAILED),
  230.             NULL, MB_ICONSTOP | MB_OK);
  231.     return FALSE;
  232.   }
  233.   /* empty the current contents. */
  234.   if (message == LB_ADDSTRING)
  235.     SendMessage (hwndFill, LB_RESETCONTENT, 0, 0);
  236.   else if (message == CB_ADDSTRING)
  237.     SendMessage (hwndFill, CB_RESETCONTENT, 0, 0);
  238.   iSubKey = 0;
  239.   cBytesName = cBytesValue = MAX_PATH;
  240.   while (!RegEnumValue (hKey, iSubKey, szKeyname, &cBytesName, NULL, NULL, (LPBYTE)szValue, &cBytesValue)) {
  241.     if (myScanf (szValue, &cp) == 1) {
  242.       /* if we are to display only the number, then reformat szValue string */
  243.       if (NumberOnly)
  244.         wsprintf (szValue, TEXT("%d"), cp);
  245.       SendMessage (hwndFill, message, 0 ,(LPARAM) szValue);
  246.     }
  247.     iSubKey++;
  248.     cBytesName = cBytesValue = MAX_PATH;  // undoc.ed feature, must be set each time.
  249.   }
  250.   RegCloseKey (hKey);
  251.   return TRUE;
  252. }
  253. /***************************************************************************
  254. *    FUNCTION: myScanf
  255. *
  256. * Convert a string into a number (like sscanf).
  257. *  However, this function works independent of UNICODE turned on.
  258. *
  259. * NOT a general function... looking for "c_%d.nls"
  260. *
  261. ***************************************************************************/
  262. int myScanf (TCHAR* pSource, int* pValue)
  263. {
  264. char ansibuffer[MAX_PATH];
  265. int iStrLen;
  266.   iStrLen = lstrlen (pSource);
  267.   if (iStrLen == 0) return 0;
  268. #ifdef UNICODE
  269.   WideCharToMultiByte (CP_ACP, 0, pSource, -1,
  270.            ansibuffer, MAX_PATH, NULL, NULL);
  271. #else
  272.   lstrcpy (ansibuffer, pSource);
  273. #endif
  274.   CharLowerBuffA (ansibuffer,lstrlenA (ansibuffer));
  275.   return (sscanf (ansibuffer, "c_%d.nls", pValue)); // leave off TEXT()
  276. }