home *** CD-ROM | disk | FTP | other *** search
/ Computer Select (Limited Edition) / Computer Select.iso / msj / v06n06 / intnat.exe / INTERN.EXE / INTERFNS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-01  |  27.9 KB  |  955 lines

  1. /*
  2.  * Function support segment for INTERNAT
  3.  *
  4.  * William S. Hall
  5.  * 3665 Benton Street, #66
  6.  * Santa Clara, CA 95051
  7.  *
  8.  */
  9.  
  10. #define NOKANJI
  11. #define NOCOMM
  12. #define NOSOUND
  13. #include <windows.h>
  14. #include <stdlib.h>
  15. #include <search.h>
  16. #include <ctype.h>
  17. #include <string.h>
  18. #include <stdio.h>
  19. #include "interfns.h"
  20. #include "intermnu.h"
  21. #include "intdgdef.h"
  22. #include "internat.h"
  23. #include "interdlg.h"
  24. #include "winutils.h"
  25. #include "interstr.h"
  26.  
  27. /* local functions */
  28. BOOL FAR PASCAL AboutDlg(HWND hDlg, unsigned message, WORD wParam, LONG lParam);
  29. BOOL FAR PASCAL CompareDlgFunc(HWND hDlg, unsigned message, WORD wParam,
  30.                                LONG lParam);
  31. BOOL FAR PASCAL IntlDlg(HWND hDlg, unsigned message, WORD wParam, LONG lParam);
  32. static void NEAR DoCompare(HWND hDlg, BOOL cmptype);
  33. static void NEAR SetOEMCharSet(HWND hWnd, WORD id);
  34. static void NEAR ResetDisplay(void);
  35. static void NEAR DoAnsiCase(HWND hWnd, WORD id,
  36.                             WORD (FAR PASCAL *fp)(LPSTR, WORD));
  37. static void NEAR DoCCase(HWND hWnd, WORD id, int (*fp)(int));
  38. static WORD NEAR GetCheckedItem(HMENU hSub);
  39. static void NEAR IsAnsiType(HWND hWnd, WORD id, BOOL (FAR PASCAL *fp)(char));
  40. static void NEAR AnsiOem(HWND hWnd, WORD id, BOOL cset,
  41.                          int (FAR PASCAL *fp)(LPSTR, LPSTR, int));
  42. static void NEAR IsCType(HWND hWnd, WORD id, BOOL (*fp)(int));
  43. static void NEAR LSort(HWND hWnd, WORD id, int (*fp)());
  44. static void NEAR ShowKBCodePage(HWND hWnd);
  45. static int lcompare(BYTE *c1, BYTE *c2);
  46. static int lcomparei(BYTE *c1, BYTE *c2);
  47. static int compare(BYTE *c1, BYTE *c2);
  48. static int comparei(BYTE *c1, BYTE *c2);
  49. static void NEAR ShowKBType(HWND hWnd);
  50. BOOL FAR PASCAL OEMConvertDlg(HWND hDlg,unsigned message,WORD wParam,
  51.                               LONG lParam);
  52. static void NEAR SetOEMConvertStyle(HWND hDlg, WORD id, BOOL flag);
  53. static void NEAR IntlDlgInit(HWND hDlg);
  54. static void NEAR GetLanguageString(BYTE *buf);
  55. static void NEAR ShowKBLanguage(HWND hWnd);
  56. BOOL FAR PASCAL ListSortDlg(HWND hDlg, unsigned message, WORD wParam,
  57.                             LONG lParam);
  58. static void NEAR ListSortInit(HWND hDlg);
  59. static void NEAR ListOpen(HWND hDlg);
  60. static void NEAR SwitchLanguage(HWND hWnd);
  61.  
  62. #define BUFLEN  128             /* comparison string buf length */
  63. #define MAXTOGGLEMENUS 3        /* first three menus contain toggled items */
  64. #define MAXPATHLEN      144
  65. #define MAXFILENAMELEN  12
  66. #define NAMELEN 128
  67.  
  68. /* display contents of WM_KEYUP, WM_KEYDOWN, WM_CHAR, and WM_DEADCHAR msgs */
  69. void FAR DoKeyStuff(HWND hWnd, unsigned message, WORD wParam, LONG lParam)
  70. {
  71.     RECT rect;
  72.     BYTE buf[40];
  73.     BYTE fmt[40];
  74.     WORD loword;
  75.     BYTE lobyte, hibyte;
  76.  
  77.     GetClientRect(hWnd, &rect);
  78.     rect.left = kwidth;
  79.     loword = LOWORD(lParam);
  80.     lobyte = LOBYTE(HIWORD(lParam));
  81.     hibyte = HIBYTE(HIWORD(lParam));
  82.  
  83.     switch(message) {
  84.         case WM_KEYDOWN:
  85.             GetKeyNameText(lParam, buf, sizeof(buf));
  86.             memset(kbubuf, 0, sizeof(kbubuf));
  87.             memset(kbbuf, 0, sizeof(kbbuf));
  88.             LoadString(hRC, IDS_KEYDOWN, fmt, sizeof(fmt));
  89.             rect.top = cheight;
  90.             rect.bottom = rect.top + 4 * cheight;
  91.             wsprintf(kbdbuf, fmt, wParam, loword, lobyte,
  92.                      hibyte, (LPSTR)buf);
  93.             break;
  94.         case WM_KEYUP:
  95.             GetKeyNameText(lParam, buf, sizeof(buf));
  96.             LoadString(hRC, IDS_KEYUP, fmt, sizeof(fmt));
  97.             rect.top = 2 * cheight;
  98.             rect.bottom = rect.top  + cheight;
  99.             wsprintf(kbubuf, fmt,
  100.                      wParam, loword, lobyte, hibyte, (LPSTR)buf);
  101.             break;
  102.         case WM_CHAR:
  103.             GetKeyNameText(lParam, buf, sizeof(buf));
  104.             LoadString(hRC, IDS_KEYCHAR, fmt, sizeof(fmt));
  105.             rect.top = 3 * cheight;
  106.             rect.bottom = rect.top  + cheight;
  107.             wsprintf(kbbuf, fmt,
  108.                      wParam, loword, lobyte, hibyte, (LPSTR)buf);
  109.             break;
  110.         case WM_DEADCHAR:
  111.             GetKeyNameText(lParam, buf, sizeof(buf));
  112.             LoadString(hRC, IDS_KEYMUTE, fmt, sizeof(fmt));
  113.             rect.top = 3 * cheight;
  114.             rect.bottom = rect.top  + cheight;
  115.             wsprintf(kbbuf, fmt,
  116.                      wParam, loword, lobyte, hibyte, (LPSTR)buf);
  117.             break;
  118.     }
  119.     InvalidateRect(hWnd, &rect, TRUE);
  120. }
  121.  
  122. /* menu command processor */
  123. void FAR WndCommand(HWND hWnd, WORD wParam)
  124. {
  125.     switch(wParam) {
  126.         case IDM_ABOUT:
  127.             OpenDlgBox(hWnd, AboutDlg, DT_ABOUT, hRC);
  128.             break;
  129.         case IDM_OEMCHARSET:
  130.             SetOEMCharSet(hWnd, wParam);
  131.             break;
  132.         case IDM_ANSIUPPER:
  133.             DoAnsiCase(hWnd, wParam, AnsiUpperBuff);
  134.             break;
  135.         case IDM_ANSILOWER:
  136.             DoAnsiCase(hWnd, wParam, AnsiLowerBuff);
  137.             break;
  138.         case IDM_ISCHARALPHA:
  139.             IsAnsiType(hWnd, wParam, IsCharAlpha);
  140.             break;
  141.         case IDM_ISCHARALPHANUM:
  142.             IsAnsiType(hWnd, wParam, IsCharAlphaNumeric);
  143.             break;
  144.         case IDM_ISCHARUPPER:
  145.             IsAnsiType(hWnd, wParam, IsCharUpper);
  146.             break;
  147.         case IDM_ISCHARLOWER:
  148.             IsAnsiType(hWnd, wParam, IsCharLower);
  149.             break;
  150.         case IDM_TOUPPER:
  151.             DoCCase(hWnd, wParam, toupper);
  152.             break;
  153.         case IDM_TOLOWER:
  154.             DoCCase(hWnd, wParam, tolower);
  155.             break;
  156.         case IDM_ISALPHA:
  157.             IsCType(hWnd, wParam, isalpha);
  158.             break;
  159.         case IDM_ISALNUM:
  160.             IsCType(hWnd, wParam, isalnum);
  161.             break;
  162.         case IDM_ISUPPER:
  163.             IsCType(hWnd, wParam, isupper);
  164.             break;
  165.         case IDM_ISLOWER:
  166.             IsCType(hWnd, wParam, islower);
  167.             break;
  168.         case IDM_LSTRCMP:
  169.             LSort(hWnd, wParam, lcompare);
  170.             break;
  171.         case IDM_LSTRCMPI:
  172.             LSort(hWnd, wParam, lcomparei);
  173.             break;
  174.         case IDM_STRCMP:
  175.             LSort(hWnd, wParam, compare);
  176.             break;
  177.         case IDM_STRCMPI:
  178.             LSort(hWnd, wParam, comparei);
  179.             break;
  180.         case IDM_ANSITOOEM:
  181.             AnsiOem(hWnd, wParam, TRUE, AnsiToOemBuff);
  182.             break;
  183.         case IDM_OEMTOANSI:
  184.             AnsiOem(hWnd, wParam, FALSE, OemToAnsiBuff);
  185.             break;
  186.         case IDM_LSTRCMPTEST:
  187.             OpenDlgBoxParam(hWnd, CompareDlgFunc, DT_COMPARE, hRC, (LONG)TRUE);
  188.             break;
  189.         case IDM_STRCMPTEST:
  190.             OpenDlgBoxParam(hWnd, CompareDlgFunc, DT_COMPARE, hRC, (LONG)FALSE);
  191.             break;
  192.         case IDM_KBCODEPAGE:
  193.             ShowKBCodePage(hWnd);
  194.             break;
  195.         case IDM_KBLAYOUT:
  196.             ShowKBLanguage(hWnd);
  197.             break;
  198.         case IDM_KBTYPE:
  199.             ShowKBType(hWnd);
  200.             break;
  201.         case IDM_ESOEMCONVERT:
  202.             OpenDlgBox(hWnd, OEMConvertDlg, DT_OEMCONVERT, hRC);
  203.             break;
  204.         case IDM_INTL:
  205.             OpenDlgBox(hWnd, IntlDlg, DT_INTL, hRC);
  206.             break;
  207.         case IDM_LISTSORT:
  208.             OpenDlgBox(hWnd, ListSortDlg, DT_LISTSORT, hRC);
  209.             break;
  210.         case IDM_LANGUAGE:
  211.             SwitchLanguage(hWnd);
  212.             break;
  213.     }
  214. }
  215.  
  216. /* Change language. This routine is a bit cavalier if the menu does not load */
  217. static void NEAR SwitchLanguage(HWND hWnd)
  218. {
  219.     register int result;
  220.     BOOL change = FALSE;
  221.     BYTE buf[80];
  222.  
  223.     result = OpenDlgBox(hWnd, LangDlgFunc, DT_LANGUAGE, hRC);
  224.  
  225.     switch (result) {
  226.         case IDS_PIGLATIN:
  227.             if (hRC == hInst) {
  228.                 LoadString(hInst, IDS_PGLLIBNAME, buf, sizeof(buf));
  229.                 hRC = LoadLibrary(buf);
  230.                 if (hRC >= 32)
  231.                     change = TRUE;
  232.             }
  233.             break;
  234.         case IDS_ENGLISH:
  235.             if (hRC != hInst) {
  236.                 if (hRC)
  237.                     FreeLibrary(hRC);
  238.                 hRC = hInst;
  239.                 change = TRUE;
  240.             }
  241.             break;
  242.     }
  243.     if (change) {
  244.         char szTitle[50];
  245.         HMENU hMenu, hOldMenu;
  246.       /* redraw title */
  247.         LoadString(hRC, IDS_TITLE,szTitle,sizeof(szTitle));
  248.         SetWindowText(hWnd, szTitle);
  249.       /* load the menu */
  250.         hOldMenu = GetMenu(hWnd);
  251.         hMenu = LoadMenu(hRC, szAppName);
  252.         SetMenu(hWnd, hMenu);
  253.         DestroyMenu(hOldMenu);
  254.       /* restore the display to startup */
  255.         ResetDisplay();
  256.         InvalidateRect(hWnd, NULL, TRUE);
  257.     }
  258. }
  259.  
  260. /* read the keyboard type */
  261. static void NEAR ShowKBType(HWND hWnd)
  262. {
  263.  
  264.     char fmt[255];
  265.     char buf[255];
  266.  
  267.     LoadString(hRC, IDS_KBTYPE, fmt, sizeof(fmt));
  268.     wsprintf(buf,fmt,GetKeyboardType(0),GetKeyboardType(1),GetKeyboardType(2));
  269.  
  270.     MessageBox(hWnd, buf, szAppName, MB_OK | MB_ICONINFORMATION);
  271. }
  272.  
  273. /* show the code page Windows THINKS it has */
  274. static void NEAR ShowKBCodePage(HWND hWnd)
  275. {
  276.     char buf[80];
  277.     char fmt[80];
  278.     int cp;
  279.  
  280.     cp = GetKBCodePage();
  281.  
  282.     LoadString(hRC, IDS_KBCODEPAGE, fmt, sizeof(fmt));
  283.     wsprintf(buf, fmt, cp);
  284.  
  285.     MessageBox(hWnd, buf, szAppName, MB_OK | MB_ICONINFORMATION);
  286. }
  287.  
  288. /* sort the backing store, but only from the space char only */
  289. static void NEAR LSort(HWND hWnd, WORD id, int (*fp)())
  290. {
  291.     HMENU hMenu;
  292.     WORD item;
  293.     HCURSOR hCursor;
  294.  
  295.     hMenu = GetMenu(hWnd);
  296.     item = GetCheckedItem(hMenu);
  297.     CheckMenuItem(hMenu, item, MF_UNCHECKED);
  298.  
  299.     if (item == id)
  300.         ResetDisplay();
  301.     else {
  302.         SetCapture(hWnd);
  303.         hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  304.         ResetDisplay();
  305.         qsort(display + 32, sizeof(display) - 32, sizeof(char), fp);
  306.         CheckMenuItem(hMenu, id, MF_CHECKED);
  307.         SetCursor(hCursor);
  308.         ReleaseCapture();
  309.     }
  310.     InvalidateRect(hWnd, NULL, TRUE);
  311. }
  312.  
  313. /* do a lstrcmp compare */
  314. static int lcompare(BYTE *c1, BYTE *c2)
  315. {
  316.     static BYTE buf1[2];
  317.     static BYTE buf2[2];
  318.  
  319.     buf1[0] = *c1;
  320.     buf2[0] = *c2;
  321.  
  322.     return lstrcmp(buf1, buf2);
  323. }
  324.  
  325. /* do a lstrcmpi compare */
  326. static int lcomparei(BYTE *c1, BYTE *c2)
  327. {
  328.  
  329.     static BYTE buf1[2];
  330.     static BYTE buf2[2];
  331.  
  332.     buf1[0] = *c1;
  333.     buf2[0] = *c2;
  334.  
  335.     return lstrcmpi(buf1, buf2);
  336.  
  337. }
  338.  
  339. /* do a strcmp compare */
  340. static int compare(BYTE *c1, BYTE *c2)
  341. {
  342.     static BYTE buf1[2];
  343.     static BYTE buf2[2];
  344.  
  345.     buf1[0] = *c1;
  346.     buf2[0] = *c2;
  347.  
  348.     return strcmp(buf1, buf2);
  349. }
  350.  
  351. /* do a strcmpi compare */
  352. static int comparei(BYTE *c1, BYTE *c2)
  353. {
  354.  
  355.     static BYTE buf1[2];
  356.     static BYTE buf2[2];
  357.  
  358.     buf1[0] = *c1;
  359.     buf2[0] = *c2;
  360.  
  361.     return strcmpi(buf1, buf2);
  362.  
  363. }
  364.  
  365. /* set screen to show the OEM character set */
  366. static void NEAR SetOEMCharSet(HWND hWnd, WORD id)
  367. {
  368.     HMENU hMenu;
  369.     WORD item;
  370.  
  371.     hMenu = GetMenu(hWnd);
  372.     item = GetCheckedItem(hMenu);
  373.     CheckMenuItem(hMenu, item, MF_UNCHECKED);
  374.  
  375.     if (item == id)
  376.         OEMCharSet = FALSE;
  377.     else {
  378.         ResetDisplay();
  379.         OEMCharSet = TRUE;
  380.         CheckMenuItem(hMenu, id, MF_CHECKED);
  381.     }
  382.     InvalidateRect(hWnd, NULL, TRUE);
  383. }
  384.  
  385. /* do one of the many conversions from ANSI to OEM or back */
  386. static void NEAR AnsiOem(HWND hWnd, WORD id,
  387.                          BOOL cset, int (FAR PASCAL *fp)(LPSTR,LPSTR,int))
  388. {
  389.  
  390.     HMENU hMenu;
  391.     WORD item;
  392.  
  393.     hMenu = GetMenu(hWnd);
  394.     item = GetCheckedItem(hMenu);
  395.     CheckMenuItem(hMenu, item, MF_UNCHECKED);
  396.  
  397.     if (item == id)
  398.         ResetDisplay();
  399.     else {
  400.         ResetDisplay();
  401.         if (cset)
  402.             OEMCharSet = TRUE;
  403.         (*fp)(display, display, sizeof(display));
  404.         CheckMenuItem(hMenu, id, MF_CHECKED);
  405.     }
  406.     InvalidateRect(hWnd, NULL, TRUE);
  407. }
  408.  
  409. /* map to upper or lower case using Windows functions */
  410. static void NEAR DoAnsiCase(HWND hWnd, WORD id,
  411.                             WORD (FAR PASCAL *fp)(LPSTR, WORD))
  412. {
  413.  
  414.     HMENU hMenu;
  415.     WORD item;
  416.  
  417.     hMenu = GetMenu(hWnd);
  418.     item = GetCheckedItem(hMenu);
  419.     CheckMenuItem(hMenu, item, MF_UNCHECKED);
  420.  
  421.     if (item == id)
  422.         ResetDisplay();
  423.     else {
  424.         ResetDisplay();
  425.         (*fp)(display, sizeof(display));
  426.         CheckMenuItem(hMenu, id, MF_CHECKED);
  427.     }
  428.     InvalidateRect(hWnd, NULL, TRUE);
  429. }
  430.  
  431. /* map to upper or lower case using C functions */
  432. static void NEAR DoCCase(HWND hWnd, WORD id, int (*fp)(int))
  433. {
  434.  
  435.     HMENU hMenu;
  436.     WORD item;
  437.     register int i;
  438.  
  439.     hMenu = GetMenu(hWnd);
  440.     item = GetCheckedItem(hMenu);
  441.     CheckMenuItem(hMenu, item, MF_UNCHECKED);
  442.  
  443.     if (item == id)
  444.         ResetDisplay();
  445.     else {
  446.         for (i = 0; i < sizeof(display); i++)
  447.             display[i] = (BYTE)(*fp)(i);
  448.         CheckMenuItem(hMenu, id, MF_CHECKED);
  449.     }
  450.     InvalidateRect(hWnd, NULL, TRUE);
  451. }
  452.  
  453. /* determine ANSI type for character */
  454. static void NEAR IsAnsiType(HWND hWnd, WORD id, BOOL (FAR PASCAL *fp)(char))
  455. {
  456.  
  457.     HMENU hMenu;
  458.     WORD item;
  459.     register int i;
  460.  
  461.     hMenu = GetMenu(hWnd);
  462.     item = GetCheckedItem(hMenu);
  463.     CheckMenuItem(hMenu, item, MF_UNCHECKED);
  464.  
  465.     if (item == id)
  466.         ResetDisplay();
  467.     else {
  468.         for (i = 0; i < sizeof(display); i++) {
  469.             if ((*fp)((char)i))
  470.                 display[i] = (BYTE)i;
  471.             else
  472.                 display[i] = '_';
  473.         }
  474.         CheckMenuItem(hMenu, id, MF_CHECKED);
  475.     }
  476.     InvalidateRect(hWnd, NULL, TRUE);
  477. }
  478.  
  479. /* determine C type for character */
  480. static void NEAR IsCType(HWND hWnd, WORD id, BOOL (*fp)(int))
  481. {
  482.  
  483.     HMENU hMenu;
  484.     WORD item;
  485.     register int i;
  486.  
  487.     hMenu = GetMenu(hWnd);
  488.     item = GetCheckedItem(hMenu);
  489.     CheckMenuItem(hMenu, item, MF_UNCHECKED);
  490.  
  491.     if (item == id)
  492.         ResetDisplay();
  493.     else {
  494.         for (i = 0; i < sizeof(display); i++) {
  495.             if ((*fp)(i))
  496.                 display[i] = (BYTE)i;
  497.             else
  498.                 display[i] = '_';
  499.         }
  500.         CheckMenuItem(hMenu, id, MF_CHECKED);
  501.     }
  502.     InvalidateRect(hWnd, NULL, TRUE);
  503. }
  504.  
  505. /* look at a menu and find out which one is checked */
  506. static WORD NEAR GetCheckedItem(HMENU hMenu)
  507. {
  508.     register WORD i, j;
  509.     register WORD state;
  510.     HMENU hSub;
  511.     WORD n;
  512.  
  513.     for (j = 0; j < MAXTOGGLEMENUS; j++) {
  514.         hSub = GetSubMenu(hMenu, j);
  515.         n = GetMenuItemCount(hSub);
  516.         for (i = 0; i < n; i++) {
  517.             state = GetMenuState(hSub, i, MF_BYPOSITION);
  518.             if (state & MF_CHECKED)
  519.                 return GetMenuItemID(hSub, i);
  520.         }
  521.     }
  522.     return -1;
  523. }
  524.  
  525. /* reset the backing store and any flags */
  526. static void NEAR ResetDisplay(void)
  527. {
  528.     register int i;
  529.  
  530.     for (i = 0; i < sizeof(display); i++)
  531.         display[i] = (BYTE)i;
  532.     OEMCharSet = FALSE;
  533. }
  534.  
  535. /* compare two strings dialog */
  536. BOOL FAR PASCAL CompareDlgFunc(HWND hDlg, unsigned message,
  537.                                WORD wParam, LONG lParam)
  538. {
  539.     static BOOL cmptype;
  540.  
  541.     switch(message) {
  542.  
  543.         case WM_INITDIALOG:
  544.             SendDlgItemMessage(hDlg, IDD_STRING1, EM_LIMITTEXT, BUFLEN, 0L);
  545.             SendDlgItemMessage(hDlg, IDD_STRING2, EM_LIMITTEXT, BUFLEN, 0L);
  546.             cmptype = (BOOL)lParam;
  547.             break;
  548.  
  549.         case WM_COMMAND:
  550.             switch(wParam) {
  551.  
  552.                 case IDD_STRING1:
  553.                 case IDD_STRING2:       /* compare on every char typed */
  554.                     if (HIWORD(lParam) == EN_CHANGE)
  555.                         DoCompare(hDlg, cmptype);
  556.                     break;
  557.  
  558.                 case IDCANCEL:
  559.                     EndDialog(hDlg, FALSE);
  560.                     break;
  561.  
  562.                 default:
  563.                     return FALSE;
  564.             }
  565.             break;
  566.  
  567.         default:
  568.             return FALSE;
  569.     }
  570.     return TRUE;
  571. }
  572.  
  573. /* do the compare using either C or Windows functions */
  574. static void NEAR DoCompare(HWND hDlg, BOOL cmptype)
  575. {
  576.     BYTE buf1[BUFLEN];
  577.     BYTE buf2[BUFLEN];
  578.     int cmp;
  579.     int cmpi;
  580.     static char cbuf[2];
  581.     static char cibuf[2];
  582.  
  583.     GetDlgItemText(hDlg, IDD_STRING1, buf1, sizeof(buf1));
  584.     GetDlgItemText(hDlg, IDD_STRING2, buf2, sizeof(buf2));
  585.  
  586.     if (cmptype) {
  587.         cmp = lstrcmp(buf1, buf2);
  588.         cmpi = lstrcmpi(buf1, buf2);
  589.     }
  590.     else {
  591.         cmp = strcmp(buf1, buf2);
  592.         cmpi = strcmpi(buf1, buf2);
  593.     }
  594.  
  595.     if (cmp < 0)
  596.         cbuf[0] = '<';
  597.     else if (cmp > 0)
  598.         cbuf[0] = '>';
  599.     else
  600.         cbuf[0] = '=';
  601.  
  602.     if (cmpi < 0)
  603.         cibuf[0] = '<';
  604.     else if (cmpi > 0)
  605.         cibuf[0] = '>';
  606.     else
  607.         cibuf[0] = '=';
  608.  
  609.     SetDlgItemText(hDlg, IDD_CASE, cbuf);
  610.     SetDlgItemText(hDlg, IDD_NOCASE, cibuf);
  611.  
  612. }
  613.  
  614. /* Show the effects of the OEMCONVERT style on an edit box */
  615. BOOL FAR PASCAL OEMConvertDlg(HWND hDlg, unsigned message, WORD wParam,
  616.                               LONG lParam)
  617. {
  618.  
  619.     switch(message) {
  620.  
  621.         case WM_INITDIALOG:
  622.             SetOEMConvertStyle(hDlg, IDD_OEMCONVERT, TRUE);
  623.             CheckDlgButton(hDlg, IDD_OEMON, TRUE);
  624.             break;
  625.  
  626.         case WM_COMMAND:
  627.             switch(wParam) {
  628.                 case IDD_OEMON:
  629.                     if (IsDlgButtonChecked(hDlg, IDD_OEMON)) {
  630.                         SetOEMConvertStyle(hDlg, IDD_OEMCONVERT, FALSE);
  631.                         CheckDlgButton(hDlg, IDD_OEMON, FALSE);
  632.                     }
  633.                     else {
  634.                         SetOEMConvertStyle(hDlg, IDD_OEMCONVERT, TRUE);
  635.                         CheckDlgButton(hDlg, IDD_OEMON, TRUE);
  636.                     }
  637.                     SetFocus(GetDlgItem(hDlg, IDD_OEMCONVERT));
  638.                     break;
  639.  
  640.                 case IDOK:
  641.                     EndDialog(hDlg, TRUE);
  642.                     break;
  643.  
  644.                 case IDCANCEL:
  645.                     EndDialog(hDlg, FALSE);
  646.                     break;
  647.  
  648.                 default:
  649.                     return FALSE;
  650.             }
  651.             break;
  652.  
  653.         default:
  654.             return FALSE;
  655.     }
  656.     return TRUE;
  657. }
  658.  
  659. /* set the OEMCONVERT style on or off */
  660. static void NEAR SetOEMConvertStyle(HWND hDlg, WORD id, BOOL flag)
  661. {
  662.  
  663.     LONG style;
  664.     HWND hctl;
  665.  
  666.     hctl = GetDlgItem(hDlg, id);
  667.     style = GetWindowLong(hctl, GWL_STYLE);
  668.  
  669.     if (flag)
  670.         style |= ES_OEMCONVERT;
  671.     else
  672.         style &= ~ES_OEMCONVERT;
  673.     SetWindowLong(hctl, GWL_STYLE, style);
  674. }
  675.  
  676. /* Read and display the strings from the win.ini [intl] section */
  677. BOOL FAR PASCAL IntlDlg(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
  678. {
  679.  
  680.     switch(message) {
  681.  
  682.         case WM_INITDIALOG:
  683.             IntlDlgInit(hDlg);
  684.             break;
  685.  
  686.         case WM_COMMAND:
  687.             switch(wParam) {
  688.                 case IDOK:
  689.                 case IDCANCEL:
  690.                     EndDialog(hDlg, TRUE);
  691.                     break;
  692.  
  693.                 default:
  694.                     return FALSE;
  695.             }
  696.             break;
  697.  
  698.         default:
  699.             return FALSE;
  700.     }
  701.     return TRUE;
  702. }
  703.  
  704. #define DEFCOUNTRY      0
  705.  
  706. /* Load up the dialog box */
  707. static void NEAR IntlDlgInit(HWND hDlg)
  708. {
  709.  
  710.     char kbuf[80];
  711.     char intlbuf[40];
  712.     char valbuf[80];
  713.     int val;
  714.  
  715.     LoadString(hRC, IDS_INTL, intlbuf, sizeof(intlbuf));
  716.  
  717.     LoadString(hRC, IDS_COUNTRYCODE, kbuf, sizeof(kbuf));
  718.     val = GetProfileInt(intlbuf, kbuf, 0);
  719.     SetDlgItemInt(hDlg, IDD_COUNTRYCODE, val, FALSE);
  720.  
  721.     LoadString(hRC, IDS_COUNTRY, kbuf, sizeof(kbuf));
  722.     val = GetProfileString(intlbuf, kbuf, "", valbuf, sizeof(valbuf));
  723.     SetDlgItemText(hDlg, IDD_COUNTRY, valbuf);
  724.  
  725.     GetLanguageString(valbuf);
  726.     SetDlgItemText(hDlg, IDD_LANGUAGE, valbuf);
  727.  
  728.     LoadString(hRC, IDS_LISTSEPARATOR, kbuf, sizeof(kbuf));
  729.     val = GetProfileString(intlbuf, kbuf, "", valbuf, sizeof(valbuf));
  730.     SetDlgItemText(hDlg, IDD_LISTSEPARATOR, valbuf);
  731.  
  732.     LoadString(hRC, IDS_MEASUREMENT, kbuf, sizeof(kbuf));
  733.     val = GetProfileInt(intlbuf, kbuf, 0);
  734.     SetDlgItemInt(hDlg, IDD_MEASUREMENT, val, FALSE);
  735.  
  736.     LoadString(hRC, IDS_TIMEFORMAT, kbuf, sizeof(kbuf));
  737.     val = GetProfileInt(intlbuf, kbuf, 0);
  738.     SetDlgItemInt(hDlg, IDD_TIMEFORMAT, val, FALSE);
  739.  
  740.     LoadString(hRC, IDS_TIMESEPARATOR, kbuf, sizeof(kbuf));
  741.     val = GetProfileString(intlbuf, kbuf, "", valbuf, sizeof(valbuf));
  742.     SetDlgItemText(hDlg, IDD_TIMESEPARATOR, valbuf);
  743.  
  744.     LoadString(hRC, IDS_AMSTRING, kbuf, sizeof(kbuf));
  745.     val = GetProfileString(intlbuf, kbuf, "", valbuf, sizeof(valbuf));
  746.     SetDlgItemText(hDlg, IDD_AMSTRING, valbuf);
  747.  
  748.     LoadString(hRC, IDS_PMSTRING, kbuf, sizeof(kbuf));
  749.     val = GetProfileString(intlbuf, kbuf, "", valbuf, sizeof(valbuf));
  750.     SetDlgItemText(hDlg, IDD_PMSTRING, valbuf);
  751.  
  752.     LoadString(hRC, IDS_TIMELEADINGZERO, kbuf, sizeof(kbuf));
  753.     val = GetProfileInt(intlbuf, kbuf, 0);
  754.     SetDlgItemInt(hDlg, IDD_TIMELEADINGZERO, val, FALSE);
  755.  
  756.     LoadString(hRC, IDS_WIN2DATEFORMAT, kbuf, sizeof(kbuf));
  757.     val = GetProfileInt(intlbuf, kbuf, 0);
  758.     SetDlgItemInt(hDlg, IDD_WIN2DATEFORMAT, val, FALSE);
  759.  
  760.     LoadString(hRC, IDS_WIN2DATESEPARATOR, kbuf, sizeof(kbuf));
  761.     val = GetProfileString(intlbuf, kbuf, "", valbuf, sizeof(valbuf));
  762.     SetDlgItemText(hDlg, IDD_WIN2DATESEPARATOR, valbuf);
  763.  
  764.     LoadString(hRC, IDS_SHORTDATEFORMAT, kbuf, sizeof(kbuf));
  765.     val = GetProfileString(intlbuf, kbuf, "", valbuf, sizeof(valbuf));
  766.     SetDlgItemText(hDlg, IDD_SHORTDATEFORMAT, valbuf);
  767.  
  768.     LoadString(hRC, IDS_LONGDATEFORMAT, kbuf, sizeof(kbuf));
  769.     val = GetProfileString(intlbuf, kbuf, "", valbuf, sizeof(valbuf));
  770.     SetDlgItemText(hDlg, IDD_LONGDATEFORMAT, valbuf);
  771.  
  772.     LoadString(hRC, IDS_CURRENCYSYMBOL, kbuf, sizeof(kbuf));
  773.     val = GetProfileString(intlbuf, kbuf, "", valbuf, sizeof(valbuf));
  774.     SetDlgItemText(hDlg, IDD_CURRENCYSYMBOL, valbuf);
  775.  
  776.     LoadString(hRC, IDS_CURRENCYFORMAT, kbuf, sizeof(kbuf));
  777.     val = GetProfileInt(intlbuf, kbuf, 0);
  778.     SetDlgItemInt(hDlg, IDD_CURRENCYFORMAT, val, FALSE);
  779.  
  780.     LoadString(hRC, IDS_CURRENCYDIGITS, kbuf, sizeof(kbuf));
  781.     val = GetProfileInt(intlbuf, kbuf, 0);
  782.     SetDlgItemInt(hDlg, IDD_CURRENCYDIGITS, val, FALSE);
  783.  
  784.     LoadString(hRC, IDS_NEGATIVECURRENCY, kbuf, sizeof(kbuf));
  785.     val = GetProfileInt(intlbuf, kbuf, 0);
  786.     SetDlgItemInt(hDlg, IDD_NEGATIVECURRENCY, val, FALSE);
  787.  
  788.     LoadString(hRC, IDS_1000SEPARATOR, kbuf, sizeof(kbuf));
  789.     val = GetProfileString(intlbuf, kbuf, "", valbuf, sizeof(valbuf));
  790.     SetDlgItemText(hDlg, IDD_1000SEPARATOR, valbuf);
  791.  
  792.     LoadString(hRC, IDS_DECIMALSEPARATOR, kbuf, sizeof(kbuf));
  793.     val = GetProfileString(intlbuf, kbuf, "", valbuf, sizeof(valbuf));
  794.     SetDlgItemText(hDlg, IDD_DECIMALSEPARATOR, valbuf);
  795.  
  796.     LoadString(hRC, IDS_DECIMALDIGITS, kbuf, sizeof(kbuf));
  797.     val = GetProfileInt(intlbuf, kbuf, 0);
  798.     SetDlgItemInt(hDlg, IDD_DECIMALDIGITS, val, FALSE);
  799.  
  800.     LoadString(hRC, IDS_DECIMALLEADINGZERO, kbuf, sizeof(kbuf));
  801.     val = GetProfileInt(intlbuf, kbuf, 0);
  802.     SetDlgItemInt(hDlg, IDD_DECIMALLEADINGZERO, val, FALSE);
  803.  
  804. }
  805.  
  806. /* Get the language module string.  */
  807. static void NEAR GetLanguageString(BYTE *buf)
  808. {
  809.     GetPrivateProfileString("boot.description", "language.dll",
  810.                             "English (American)", buf, 80, "system.ini");
  811. }
  812.  
  813. /* Read the keyboard's name from Setup.inf.
  814.    Imbedded strings used here are not language dependent */
  815. static void NEAR ShowKBLanguage(HWND hWnd)
  816. {
  817.     char kbdll[20];
  818.     char keystr[512];
  819.     char winpath[MAXPATHLEN + MAXFILENAMELEN + 2];
  820.     char *keyptr;
  821.     register int len;
  822.     char kbstring[80];
  823.     char fmt[80];
  824.     char buf[80];
  825.     char *result;
  826.  
  827.     /* find out where SETUP.INF is located and add in its name */
  828.     len = GetSystemDirectory(winpath, sizeof(winpath));
  829.     if ((len == 0) || (len > MAXPATHLEN))
  830.         return;                         /* error */
  831.     if (winpath[len - 1] != '\\')       /* are we in a subdirectory ? */
  832.         lstrcat(winpath, "\\");
  833.     lstrcat(winpath, "SETUP.INF");
  834.  
  835.     /* now read in the name of the keyboard dll in use from system.ini */
  836.     len = GetPrivateProfileString("keyboard", "keyboard.dll",
  837.                                   "", kbdll, sizeof(kbdll), "system.ini");
  838.     if (len == 0)
  839.         strcpy(keystr, "nodll");        /* none in use */
  840.     else        /* found one, so enumerate all possibilities */
  841.         GetPrivateProfileString("keyboard.tables", NULL, "",
  842.                                  keystr, sizeof(keystr), winpath);
  843.     keyptr = keystr;
  844.     while (len = strlen(keyptr)) {   /* loop thru strings until target found */
  845.         GetPrivateProfileString("keyboard.tables", keyptr, "",
  846.                                  kbstring, sizeof(kbstring), winpath);
  847.         if (result = strstr(kbstring, kbdll)) {
  848.             strtok(kbstring, "\"");     /* found one, parse and add to tile */
  849.             LoadString(hRC, IDS_KBLAYOUT, fmt, sizeof(fmt));
  850.             wsprintf(buf, fmt, (LPSTR)strtok(NULL, "\""));
  851.             MessageBox(hWnd, buf, szAppName, MB_OK | MB_ICONINFORMATION);
  852.             break;
  853.         }
  854.         keyptr += len + 1;
  855.     }
  856. }
  857.  
  858. /* Show the effects of sorting a list according to current language module */
  859. BOOL FAR PASCAL ListSortDlg(HWND hDlg, unsigned message, WORD wParam,
  860.                             LONG lParam)
  861. {
  862.  
  863.     switch(message) {
  864.  
  865.         case WM_INITDIALOG:
  866.             ListSortInit(hDlg);
  867.             break;
  868.  
  869.         case WM_COMMAND:
  870.             switch(wParam) {
  871.                 case IDOK:
  872.                     ListOpen(hDlg);
  873.                     break;
  874.  
  875.                 case IDCANCEL:
  876.                     EndDialog(hDlg, FALSE);
  877.                     break;
  878.  
  879.                 default:
  880.                     return FALSE;
  881.             }
  882.             break;
  883.  
  884.         default:
  885.             return FALSE;
  886.     }
  887.     return TRUE;
  888. }
  889.  
  890. /* Initialize the dialog */
  891. static void NEAR ListSortInit(HWND hDlg)
  892. {
  893.     BYTE buf[80];
  894.     BYTE lang[80];
  895.     BYTE title[50];
  896.     BYTE *fmt = "%s : %s";      /* should be moved to resources */
  897.  
  898.     GetWindowText(hDlg, title, sizeof(title));
  899.     GetLanguageString(lang);
  900.     wsprintf(buf, fmt, (LPSTR)title, (LPSTR)lang);
  901.     SetWindowText(hDlg, buf);
  902.  
  903.     SetOEMConvertStyle(hDlg, IDD_FILENAME, TRUE);
  904.     SendDlgItemMessage(hDlg, IDD_FILENAME, EM_LIMITTEXT, NAMELEN, 0L);
  905. }
  906.  
  907. /* Open a list of strings and put them into two
  908.    list boxes with one sorted and the other unsorted.
  909. */
  910. static void NEAR ListOpen(HWND hDlg)
  911. {
  912.  
  913.     FILE *fp;
  914.     BYTE fname[NAMELEN];
  915.     BYTE buf[256];
  916.     BYTE *pbuf;
  917.     int pos;
  918.     HWND hList;
  919.  
  920.     SendDlgItemMessage(hDlg, IDD_LISTSORT, LB_RESETCONTENT, 0, 0L);
  921.     SendDlgItemMessage(hDlg, IDD_NOSORT, LB_RESETCONTENT, 0, 0L);
  922.     GetDlgItemText(hDlg, IDD_FILENAME, fname, sizeof(fname));
  923.   /* using stream functions, so must convert name */
  924.     AnsiToOem(fname, fname);
  925.     fp = fopen(fname, "r");
  926.     if (fp != NULL) {
  927.         SendDlgItemMessage(hDlg, IDD_LISTSORT, LB_RESETCONTENT, 0, 0L);
  928.         SendDlgItemMessage(hDlg, IDD_LISTSORT, WM_SETREDRAW, FALSE, 0L);
  929.         SendDlgItemMessage(hDlg, IDD_NOSORT, WM_SETREDRAW, FALSE, 0L);
  930.         while (pbuf = fgets(buf, sizeof(buf), fp)) {
  931.             buf[strlen(pbuf) - 1] = 0;
  932.             pos = (int)SendDlgItemMessage(hDlg, IDD_LISTSORT, LB_ADDSTRING, 0,
  933.                                           (LONG)(LPSTR)buf);
  934.             if (pos == CB_ERR)
  935.                 break;
  936.             pos = (int)SendDlgItemMessage(hDlg, IDD_NOSORT, LB_ADDSTRING, 0,
  937.                                           (LONG)(LPSTR)buf);
  938.             if (pos == CB_ERR)
  939.                 break;
  940.         }
  941.         fclose(fp);
  942.         SendDlgItemMessage(hDlg, IDD_LISTSORT, WM_SETREDRAW, TRUE, 0L);
  943.         SendDlgItemMessage(hDlg, IDD_NOSORT, WM_SETREDRAW, TRUE, 0L);
  944.         hList = GetDlgItem(hDlg, IDD_LISTSORT);
  945.         InvalidateRect(hList, NULL, TRUE);
  946.         UpdateWindow(hList);
  947.         hList = GetDlgItem(hDlg, IDD_NOSORT);
  948.         InvalidateRect(hList, NULL, TRUE);
  949.         UpdateWindow(hList);
  950.      }
  951.      else {     /* file not found */
  952.         MessageBeep(0);
  953.     }
  954. }
  955.