home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / i18nv102.zip / SAMPLE / WORLD / WORLD.C < prev    next >
C/C++ Source or Header  |  1995-08-28  |  51KB  |  973 lines

  1. /*****************************************************************************/
  2. /***     Include files                                                     ***/
  3. /*****************************************************************************/
  4.  
  5. #include "world.h"                      /* Include data for this application.*/
  6. #include "wrld_msg.h"                   /* Include label defines for the     */
  7.                                         /*  message catalog.                 */
  8.  
  9. /*****************************************************************************/
  10. /***     Center a window in the middle of the screen.                      ***/
  11. /*****************************************************************************/
  12.  
  13. void center_the_window(HWND hwnd)
  14. {
  15.   RECTL win_rect;                       /* Bounding rectangle for dialog.    */
  16.   LONG  win_width, win_height;          /* Height and width of message box.  */
  17.  
  18.                                         /*  Get the bounding rect for the win*/
  19.                                         /*  Calculate width and height.      */
  20.                                         /*  Move the dialog to center of the */
  21.                                         /*   screen.                         */
  22.   WinQueryWindowRect(hwnd, &win_rect);
  23.   win_width = win_rect.xRight - win_rect.xLeft;
  24.   win_height = win_rect.yTop - win_rect.yBottom;
  25.   WinSetWindowPos(hwnd, HWND_TOP, (SHORT) (screen_width - win_width) / 2,
  26.                   (SHORT) (screen_height - win_height) / 2, win_width,
  27.                   win_height, SWP_MOVE | SWP_ACTIVATE | SWP_SHOW);
  28. }
  29.  
  30. /*****************************************************************************/
  31. /***     Initialize routine for program.                                   ***/
  32. /*****************************************************************************/
  33.  
  34. MRESULT EXPENTRY message_dialog_func(HWND hwnd, ULONG mess, MPARAM parm1,
  35.                                      MPARAM parm2)
  36. {
  37.   switch (mess)
  38.   {
  39.                                         /* When we initialize the dialog...  */
  40.                                         /*  Hide window while updating the   */
  41.                                         /*   text...                         */
  42.                                         /*  Set title of dialog.             */
  43.                                         /*  Set text in text field.          */
  44.                                         /*  Set text in "OK" button.         */
  45.                                         /*  Center dialog on screen.         */
  46.                                         /*  Return OK.                       */
  47.     case WM_INITDLG: WinEnableWindowUpdate(hwnd, FALSE);
  48.                      WinSetWindowText(hwnd, error_title);
  49.                      WinSetDlgItemText(hwnd, MESSAGE_TEXT, error_text);
  50.                      WinSetDlgItemText(hwnd, MESSAGE_OK,
  51.                         catgets(msg_handle, MSG, MSG_OK, "OK"));
  52.                      center_the_window(hwnd);
  53.                      return(MRESULT)TRUE;
  54.  
  55.                                         /* For other messages, use default   */
  56.     default:         return WinDefDlgProc(hwnd, mess, parm1, parm2);
  57.   }
  58.  
  59.                                         /* Return OK.                        */
  60.   return((MRESULT) 0);
  61. }
  62.  
  63. /*****************************************************************************/
  64. /***     Display a cultural message box                                    ***/
  65. /*****************************************************************************/
  66.  
  67. void error_message(HWND parent_window, char *the_text, char *the_title)
  68. {
  69.                                         /* Set up the title and text.        */
  70.                                         /* Display the message dialog box.   */
  71.   error_title = the_title;
  72.   error_text = the_text;
  73.   WinDlgBox(HWND_DESKTOP, parent_window, message_dialog_func, 0,
  74.             MESSAGE_DIALOG, 0);
  75. }
  76.  
  77. /*****************************************************************************/
  78. /***     Initialize routine for program.                                   ***/
  79. /*****************************************************************************/
  80.  
  81. void initialize(void)
  82. {
  83.   int count;                            /* Loop counter.                     */
  84.  
  85.                                         /* Loop through all the locales...   */
  86.                                         /*  Clear out "active" flag for each */
  87.                                         /*   locale's dialog (not visible).  */
  88.                                         /* To start with, we don't have any  */
  89.                                         /*  of the message locale menu items */
  90.                                         /*  checked.                         */
  91.                                         /* Start off with text in menus.     */
  92.                                         /* Start off with no minimized icon. */
  93.   for (count = 0; count < NUM_LOCALES; count++)
  94.   {
  95.       locale_active[count] = 0;
  96.   }
  97.   cur_mess_locale = NO_LOCALE;
  98.   icons_in_menus = FALSE;
  99.   icon_pointer = (HPOINTER) NULL;
  100. }
  101.  
  102. /*****************************************************************************/
  103. /***     Set up text for messages menu (called from many places)           ***/
  104. /*****************************************************************************/
  105.  
  106. void set_messages_menu(void)
  107. {
  108.   static MENUITEM menu_item = {0, MIS_TEXT, 0, 0, 0, 0}; /* A menu struct.   */
  109.   int count;                            /* Loop counter.                     */
  110.  
  111.                                         /* We want to put the text version   */
  112.                                         /*  in the menu items of the message */
  113.                                         /*  menu.                            */
  114.                                         /* For each one...                   */
  115.                                         /*  Change it to a text menu item.   */
  116.                                         /*  Send a message so it knows that. */
  117.                                         /*  Set the text in the menu item.   */
  118.                                         /* Check the proper locale.          */
  119.   for (count = 0; count < NUM_LOCALES; count++)
  120.   {
  121.     menu_item.id = (ULONG) (MENU_LANGS_LANG0 + count);
  122.     WinSendMsg(hwnd_menu, MM_SETITEM, MPFROM2SHORT(0, TRUE), MPFROMP(&menu_item));
  123.     set_menu_text(MENU_LANGS_LANG0 + count, MEN_LANGS_LANG0 + count,
  124.                   def_locs[count]);
  125.   }
  126.   WinCheckMenuItem(hwnd_menu, MENU_LANGS_LANG0 + cur_mess_locale, TRUE);
  127. }
  128.  
  129. /*****************************************************************************/
  130. /***     Set up text for menus and main window title from message catalog  ***/
  131. /*****************************************************************************/
  132.  
  133. int set_text_for_menus(void)
  134. {
  135.   char *ret_string;                     /* Value of the LC_MESSAGES locale   */
  136.                                         /*  variable.                        */
  137.   int count;                            /* Loop variable.                    */
  138.   nl_catd t_handle;                     /* Temp handle for msg catalog.      */
  139.  
  140.                                         /* If no locale menu item is yet set.*/
  141.                                         /*  Get the LC_MESSAGES var.         */
  142.                                         /*  Loop through the locales...      */
  143.                                         /*   When we find the one that       */
  144.                                         /*    matches LC_MESSAGES...         */
  145.                                         /*    Save the locale number.        */
  146.                                         /*    End the loop now.              */
  147.   if   (cur_mess_locale == NO_LOCALE)
  148.   {
  149.        ret_string = setlocale(LC_MESSAGES, NULL);
  150.        for (count = 0; count < NUM_LOCALES; count++)
  151.        {
  152.          if (strcoll(ret_string, locale_names[count]) == 0)
  153.          {
  154.             cur_mess_locale = count;
  155.             count = NUM_LOCALES;
  156.          }
  157.        }
  158.   }
  159.   else
  160.   {
  161.                                         /* If another locale already active. */
  162.                                         /*  Create the new catalog name.     */
  163.                                         /*  Try to open it.                  */
  164.                                         /*  If we can't open it...           */
  165.                                         /*   Print out an error message (from*/
  166.                                         /*    the old message catalog).      */
  167.                                         /*   Leave the routine.              */
  168.                                         /*  Otherwise...                     */
  169.                                         /*   Close the old message catalog.  */
  170.                                         /*   Use the new one.                */
  171.        sprintf(t_cat_name, CAT_NAME, locale_names[cur_mess_locale]);
  172.        /* NOTE: Uses LANG instead of LC_MESSAGES locale category. This should
  173.         * be changed. */
  174.        t_handle = catopen(t_cat_name, 0);
  175.        if   (t_handle == CATD_ERR)
  176.        {
  177.             error_message(hwndClient,
  178.                           catgets(msg_handle, HELP, HELP_NO_LOC, "Could not open the specified message catalog."),
  179.                           catgets(msg_handle, HELP, HELP_TITLE, "Help for WORLD"));
  180.             return(FALSE);
  181.        }
  182.        else
  183.        {
  184.             catclose(msg_handle);
  185.             msg_handle = t_handle;
  186.        }
  187.   }
  188.  
  189.                                         /* Set the main window title from    */
  190.                                         /*  the message catalog.             */
  191.                                         /* Set the menu items from the       */
  192.                                         /*  message catalog.                 */
  193.                                         /* If not icons (text items instead),*/
  194.                                         /*  Place the text in the messages   */
  195.                                         /*   menu.                           */
  196.   WinSetWindowText(hwndFrame,
  197.                    catgets(msg_handle, MESS_MAIN, MESS_TITLE,
  198.                            "World demo program"));
  199.   set_menu_text(MENU_FILE, MEN_FILE, "~File");
  200.   set_menu_text(MENU_FILE_HELP, MEN_FILE_HELP, "~Help\tF1");
  201.   set_menu_text(MENU_FILE_ABOUT, MEN_FILE_ABOUT, "~About WORLD");
  202.   set_menu_text(MENU_LOCALE, MEN_LOCALE, "~Locale");
  203.   set_menu_text(MENU_LOCALE_SET, MEN_LOCALE_SET, "~Set path");
  204.   set_menu_text(MENU_OPTIONS, MEN_OPTIONS, "~Options");
  205.   set_menu_text(MENU_OPTIONS_ICON, MEN_OPTIONS_ICON, "~Show icons in menus");
  206.   set_menu_text(MENU_LANGS, MEN_LANGS, "~Message");
  207.   if (!icons_in_menus)
  208.   {
  209.      set_messages_menu();
  210.   }
  211.  
  212.                                         /* For each of the locales...        */
  213.                                         /*  If the dialog for that locale is */
  214.                                         /*   open...                         */
  215.                                         /*   Change the title, buttons and   */
  216.                                         /*    static text for it to the new  */
  217.                                         /*    message catalog's values.      */
  218.   for (count = 0; count < NUM_LOCALES; count++)
  219.   {
  220.       if (locale_active[count])
  221.       {
  222.          WinSendMsg(locale_windows[count], WM_REDRAW_NLS_TEXT, NULL, NULL);
  223.       }
  224.   }
  225.  
  226.                                         /* Everything was set OK.            */
  227.   return(TRUE);
  228. }
  229.  
  230. /*****************************************************************************/
  231. /***     Open the message catalog for the program.                         ***/
  232. /*****************************************************************************/
  233.  
  234. void open_message_catalog(void)
  235. {
  236.                                         /* Set locale for messages.          */
  237.                                         /* Create the message catalog path.  */
  238.                                         /* Open the message catalog.         */
  239.                                         /* If we can't open it...            */
  240.                                         /*  Print out an error.              */
  241.   setlocale(LC_ALL, "");
  242.   sprintf(t_cat_name, CAT_NAME, setlocale(LC_MESSAGES, NULL));
  243.   msg_handle = catopen(t_cat_name, 0);
  244.   if (msg_handle == CATD_ERR)
  245.   {
  246.      WinMessageBox(HWND_DESKTOP, HWND_DESKTOP,
  247.                    "Could not locale message catalog.  Using default messages.",
  248.                    "Help for WORLD", 0, MB_NOICON | MB_OK );
  249.   }
  250. }
  251.  
  252. /*****************************************************************************/
  253. /***     Sort collation array based on cultural collation                  ***/
  254. /*****************************************************************************/
  255.  
  256.                                         /* This routine does a brain-dead    */
  257.                                         /*  simple bubble sort of the array  */
  258.                                         /*  of names, sorting with the       */
  259.                                         /*  culturally-based strcoll.        */
  260.                                         /* NOTE: It assumes that the         */
  261.                                         /*  LC_COLLATE variable is set.      */
  262. void sort_coll_arr(void)
  263. {
  264.   int count1, count2;                   /* Two loop iteration variables.     */
  265.   nam t_str;                            /* String to be used for swapping.   */
  266.  
  267.                                         /* Iterate through the array.        */
  268.                                         /*  Loop through the items...        */
  269.                                         /*   If we need to swap 2 items,     */
  270.                                         /*    Do the swap.                   */
  271.   for (count1 = (NUM_COLL_STRINGS - 1); count1 > 0; count1--)
  272.   {
  273.       for (count2 = 0; count2 < count1; count2++)
  274.       {
  275.           if (strcoll(coll_arr[count2], coll_arr[count2 + 1]) > 0)
  276.           {
  277.              strcpy(t_str, coll_arr[count2]);
  278.              strcpy(coll_arr[count2], coll_arr[count2 + 1]);
  279.              strcpy(coll_arr[count2 + 1], t_str);
  280.           }
  281.       }
  282.   }
  283. }
  284.  
  285. /*****************************************************************************/
  286. /***     Load collation array with strings                                 ***/
  287. /*****************************************************************************/
  288.  
  289. void load_coll_arr(void)
  290. {
  291.   int count = 0;                        /* Index array for insertions.       */
  292.  
  293.                                         /* Add some strings to the array.    */
  294.   strcpy(coll_arr[count++], "lion");
  295.   strcpy(coll_arr[count++],"crow");
  296.   strcpy(coll_arr[count++],"chimp");
  297.   strcpy(coll_arr[count++],"loon");
  298.   strcpy(coll_arr[count++],"llama");
  299.   strcpy(coll_arr[count++],"camel");
  300.   sprintf(coll_arr[count++], "c%ct%c", o_circumflex, e_accute);
  301.   sprintf(coll_arr[count++], "c%ct%c", 'o', 'e');
  302.   sprintf(coll_arr[count++], "c%ct%c", o_circumflex, 'e');
  303.   sprintf(coll_arr[count++], "c%ct%c", 'o', e_accute);
  304. }
  305.  
  306. /*****************************************************************************/
  307. /***     Country dialog procedure                                          ***/
  308. /*****************************************************************************/
  309.  
  310. MRESULT EXPENTRY country_proc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  311. {
  312.   int count;                            /* General loop counter.             */
  313.   HWND list_box;                        /* Window handle for list box.       */
  314.  
  315.   char temp_string[255];                /* Temporary string used in formats. */
  316.  
  317.   double num = 1000.00;                 /* Number converted into money.      */
  318.   time_t ltime;                         /* Time variable for time.           */
  319.   struct tm *ptmT = NULL;               /* Time structure for date/time.     */
  320.  
  321.   switch(msg)
  322.   {
  323.                                         /* When we get the "init dialog" msg */
  324.     case WM_INITDLG:
  325.          {
  326.                                         /* Save the locale number with the   */
  327.                                         /*  dialog...                        */
  328.                                         /* Mark that the dialog is now open  */
  329.                                         /*  so it won't be displayed more    */
  330.                                         /*  than once...                     */
  331.                                         /* Move the dialog box to a location */
  332.                                         /*  on the screen based on locale.   */
  333.                                         /* Set the title based on locale     */
  334.                                         /*  (look it up in message catalog). */
  335.                                         /* Set up labels.                    */
  336.                                         /* Set the collate and cancel buttons*/
  337.            WinSetWindowUShort(hwnd, 0, which_locale);
  338.            locale_active[which_locale]++;
  339.            WinSetWindowPos(hwnd, HWND_TOP, locale_locs[which_locale].x,
  340.                            locale_locs[which_locale].y, 76, 112,
  341.                            SWP_MOVE | SWP_ACTIVATE | SWP_SHOW);
  342.            WinSetWindowText(hwnd, catgets(msg_handle, MESS_COUNTRY,
  343.                                           COUNTRY_TITLE_BASE + which_locale,
  344.                                           def_cntry[which_locale]));
  345.            WinSetDlgItemText(hwnd, COUNTRY_DATE_LABEL,
  346.                              catgets(msg_handle, MSG, MSG_DATE, "Date:"));
  347.            WinSetDlgItemText(hwnd, COUNTRY_TIME_LABEL,
  348.                              catgets(msg_handle, MSG, MSG_TIME, "Time:"));
  349.            WinSetDlgItemText(hwnd, COUNTRY_MONEY_LABEL,
  350.                              catgets(msg_handle, MSG, MSG_MONEY, "Monetary:"));
  351.            WinSetDlgItemText(hwnd, COUNTRY_COLL_BUTTON,
  352.                              catgets(msg_handle, MSG, MSG_COLLATE, "Collate"));
  353.            WinSetDlgItemText(hwnd, COUNTRY_CANCEL_BUTTON,
  354.                              catgets(msg_handle, MSG, MSG_CANCEL, "Cancel"));
  355.  
  356.                                         /* Build the locale name.            */
  357.                                         /* Set the locale to that locale.    */
  358.            sprintf(temp_locale_path, "%s\\%s", locale_path,
  359.                    locale_names[which_locale]);
  360.            setlocale(LC_ALL, temp_locale_path);
  361.  
  362.                                         /* Get window handle of the list box.*/
  363.                                         /* Load some strings into the array. */
  364.                                         /* Loop through the strings in array.*/
  365.                                         /*  Put each one in the list box.    */
  366.            list_box = WinWindowFromID(hwnd, COUNTRY_COLLATE);
  367.            load_coll_arr();
  368.            for (count = 0; count < NUM_COLL_STRINGS; count++)
  369.            {
  370.                WinInsertLboxItem(list_box, LIT_END, (PSZ) coll_arr[count]);
  371.            }
  372.  
  373.                                         /* Get the time.                     */
  374.                                         /* Convert to local time.            */
  375.                                         /* Format date culturally.           */
  376.                                         /* Place on dialog.                  */
  377.            time(<ime);
  378.            ptmT = localtime(<ime);
  379.            strftime(temp_string, sizeof(temp_string), "%x", ptmT);
  380.            WinSetDlgItemText(hwnd, COUNTRY_DATE, temp_string);
  381.  
  382.                                         /* Format the time culturally.       */
  383.                                         /* Place on dialog.                  */
  384.            strftime(temp_string, sizeof(temp_string), "%X", ptmT);
  385.            WinSetDlgItemText(hwnd, COUNTRY_TIME, temp_string);
  386.  
  387.                                         /* Format a monetary amount.         */
  388.                                         /* Place on dialog.                  */
  389.            strfmon(temp_string, sizeof(temp_string), "%n", num);
  390.            WinSetDlgItemText(hwnd, COUNTRY_MONEY, temp_string);
  391.          }
  392.          break;
  393.     case WM_COMMAND:
  394.          switch(SHORT1FROMMP(mp1))
  395.          {
  396.                                         /* If they press the collate button. */
  397.            case COUNTRY_COLL_BUTTON:
  398.                                         /* Get the locale number from the    */
  399.                                         /*  dialog.                          */
  400.                                         /* Form the locale name.             */
  401.                                         /* Set the locale.                   */
  402.                 which_locale = WinQueryWindowUShort(hwnd, 0);
  403.                 sprintf(temp_locale_path, "%s\\%s", locale_path,
  404.                         locale_names[which_locale]);
  405.                 setlocale(LC_ALL, temp_locale_path);
  406.  
  407.                                         /* Delete all the items in the list  */
  408.                                         /*  box.                             */
  409.                                         /* Load the strings into the array   */
  410.                                         /*  (the strings could be sorted from*/
  411.                                         /*   another locale).                */
  412.                                         /* Sort the strings culturally.      */
  413.                                         /* Get window handle for the list box*/
  414.                                         /* Load all the strings into the list*/
  415.                                         /*  box.                             */
  416.                 WinSendDlgItemMsg(hwnd, COUNTRY_COLLATE, LM_DELETEALL, 0, 0);
  417.                 load_coll_arr();
  418.                 sort_coll_arr();
  419.                 list_box = WinWindowFromID(hwnd, COUNTRY_COLLATE);
  420.                 for (count = 0; count < NUM_COLL_STRINGS; count++)
  421.                 {
  422.                     WinInsertLboxItem(list_box, LIT_END, (PSZ) coll_arr[count]);
  423.                 }
  424.                 break;
  425.                                         /* If they cancel the dialog...      */
  426.            case COUNTRY_CANCEL_BUTTON:
  427.                                         /* Get the locale from the dialog.   */
  428.                                         /* Set the flag so the dialog can    */
  429.                                         /*  be opened again.                 */
  430.                                         /* Close the dialog.                 */
  431.                 which_locale = WinQueryWindowUShort(hwnd, 0);
  432.                 locale_active[which_locale]--;
  433.                 WinPostMsg(hwnd, WM_CLOSE, NULL, NULL);
  434.                 break;
  435.            default : break;
  436.          }
  437.          break;
  438.     case WM_ERASEBACKGROUND:
  439.          return((MRESULT) 1);
  440.       case WM_REDRAW_NLS_TEXT:
  441.                                         /* Get the locale number for this dlg*/
  442.                                         /* Redraw title and dialog controls  */
  443.                                         /*  that depend on language.  Assume */
  444.                                         /*  that new message catalog is open.*/
  445.          count = WinQueryWindowUShort(hwnd, 0);
  446.          WinSetWindowText(hwnd, catgets(msg_handle, MESS_COUNTRY,
  447.                           COUNTRY_TITLE_BASE + count, def_cntry[count]));
  448.          WinSetDlgItemText(hwnd, COUNTRY_COLL_BUTTON,
  449.                            catgets(msg_handle, MSG, MSG_COLLATE, "Collate"));
  450.          WinSetDlgItemText(hwnd, COUNTRY_CANCEL_BUTTON,
  451.                            catgets(msg_handle, MSG, MSG_CANCEL, "Cancel"));
  452.          WinSetDlgItemText(hwnd, COUNTRY_DATE_LABEL,
  453.                            catgets(msg_handle, MSG, MSG_DATE, "Date:"));
  454.          WinSetDlgItemText(hwnd, COUNTRY_TIME_LABEL,
  455.                            catgets(msg_handle, MSG, MSG_TIME, "Time:"));
  456.          WinSetDlgItemText(hwnd, COUNTRY_MONEY_LABEL,
  457.                            catgets(msg_handle, MSG, MSG_MONEY, "Monetary:"));
  458.          break;
  459.     default:
  460.          return(WinDefDlgProc(hwnd, msg, mp1, mp2));
  461.   }
  462.   return((MRESULT) 0);
  463. }
  464.  
  465. /*****************************************************************************/
  466. /***     Display basic help dialog                                         ***/
  467. /*****************************************************************************/
  468.  
  469. void display_help(void)
  470. {
  471.                                         /* Display the help message.         */
  472.   error_message(hwndClient,
  473.                 catgets(msg_handle, HELP, HELP_TEXT,
  474.                 "To load a locale for a country, use the mouse to select a city."),
  475.                 catgets(msg_handle, HELP, HELP_TITLE, "Help for WORLD"));
  476.   return ;
  477. }
  478.  
  479. /*****************************************************************************/
  480. /***     Procedure to handle the locale path dialog box                    ***/
  481. /*****************************************************************************/
  482.  
  483. MRESULT EXPENTRY locale_path_dialog_func(HWND hwnd, ULONG mess,
  484.                                          MPARAM parm1, MPARAM parm2)
  485. {
  486.   switch (mess)
  487.   {
  488.                                         /* When we initialize the dialog...  */
  489.                                         /*  Hide window while updating the   */
  490.                                         /*   text...                         */
  491.                                         /*  Set title of dialog.             */
  492.                                         /*  Set the current path in the      */
  493.                                         /*   entry field.                    */
  494.                                         /*  Set text in "OK" button.         */
  495.                                         /*  Center dialog on screen.         */
  496.                                         /*  Return OK.                       */
  497.     case WM_INITDLG: WinEnableWindowUpdate(hwnd, FALSE);
  498.                      WinSetWindowText(hwnd,
  499.                         catgets(msg_handle, LPD, LPD_TITLE, "Locale Path"));
  500.                      WinSetDlgItemText(hwnd, LOCALE_PATH_ENTRY, locale_path);
  501.                      WinSetDlgItemText(hwnd, LOCALE_PATH_OK,
  502.                         catgets(msg_handle, MSG, MSG_OK, "OK"));
  503.                      center_the_window(hwnd);
  504.                      return(MRESULT)TRUE;
  505.                                         /* If we get a WM_COMMAND...         */
  506.                                         /*  If it is "OK" button.            */
  507.                                         /*   Get the locale path from entry  */
  508.                                         /*    field.                         */
  509.                                         /*   Dismiss the dialog box.         */
  510.                                         /*   Call on default processing.     */
  511.                                         /*  Otherwise, call on default...    */
  512.  
  513.     case WM_COMMAND: switch (SHORT1FROMMP(parm1))
  514.                      {
  515.                        case LOCALE_PATH_OK:
  516.                             WinQueryDlgItemText(hwnd, LOCALE_PATH_ENTRY,
  517.                                                 sizeof(locale_path),
  518.                                                 (PSZ) locale_path);
  519.                             WinDismissDlg(hwnd, FALSE);
  520.                             return WinDefDlgProc(hwnd, mess, parm1, parm2);
  521.                        default:
  522.                             return WinDefDlgProc(hwnd, mess, parm1, parm2);
  523.                      }
  524.                      break;
  525.  
  526.                                         /* For other messages, use default   */
  527.     default:         return WinDefDlgProc(hwnd, mess, parm1, parm2);
  528.   }
  529.  
  530.                                         /* Return OK.                        */
  531.   return((MRESULT) 0);
  532. }
  533.  
  534. /*****************************************************************************/
  535. /***     Procedure to handle the about path dialog box                     ***/
  536. /*****************************************************************************/
  537.  
  538. MRESULT EXPENTRY about_dialog_func(HWND hwnd, ULONG mess, MPARAM parm1,
  539.                                    MPARAM parm2)
  540. {
  541.   switch (mess)
  542.   {
  543.                                         /* When we initialize the dialog...  */
  544.                                         /*  Hide window while updating the   */
  545.                                         /*   text...                         */
  546.                                         /*  Set title of dialog.             */
  547.                                         /*  Set text in "OK" button.         */
  548.                                         /*  Set text in other fields.        */
  549.                                         /*  Return OK.                       */
  550.     case WM_INITDLG: WinEnableWindowUpdate(hwnd, FALSE);
  551.                      WinSetWindowText(hwnd,
  552.                         catgets(msg_handle, ABT, ABT_DIALOG, "About WORLD"));
  553.                      WinSetDlgItemText(hwnd, ABOUT_OK,
  554.                         catgets(msg_handle, MSG, MSG_OK, "OK"));
  555.                      WinSetDlgItemText(hwnd, ABOUT_TITLE,
  556.                         catgets(msg_handle, ABT, ABT_TITLE, "World Demo Program"));
  557.                      WinSetDlgItemText(hwnd, ABOUT_PRODUCER,
  558.                         catgets(msg_handle, ABT, ABT_PRODUCER, "Produced by:"));
  559.                      WinSetDlgItemText(hwnd, ABOUT_WRITER,
  560.                         catgets(msg_handle, ABT, ABT_WRITER, "Written by:"));
  561.                      WinSetDlgItemText(hwnd, ABOUT_WHERE,
  562.                         catgets(msg_handle, ABT, ABT_WHERE, "Made in Texas"));
  563.                      WinSetDlgItemText(hwnd, ABOUT_DIRECTOR,
  564.                         catgets(msg_handle, ABT, ABT_DIRECTOR, "Directed by:"));
  565.                      center_the_window(hwnd);
  566.                      return(MRESULT)TRUE;
  567.  
  568.                                         /* For other messages, use default   */
  569.     default:         return WinDefDlgProc(hwnd, mess, parm1, parm2);
  570.   }
  571.  
  572.                                         /* Return OK.                        */
  573.   return((MRESULT) 0);
  574. }
  575.  
  576. /*****************************************************************************/
  577. /***     Set locale-based icon                                             ***/
  578. /*****************************************************************************/
  579.  
  580. void set_locale_based_icon(void)
  581. {
  582.   char *ret_string;                     /* Return value of LC_MESSAGES.      */
  583.  
  584.                                         /* This routine loads an icon from   */
  585.                                         /*  a directory based on the current */
  586.                                         /*  locale.  It then uses that icon  */
  587.                                         /*  for the minimized icon.  Instead */
  588.                                         /*  the scheme used, one could parse */
  589.                                         /*  the NLSPATH environment variable,*/
  590.                                         /*  and check each directory for the */
  591.                                         /*  named icon.                      */
  592.  
  593.                                         /* If existing icon, delete it.      */
  594.                                         /* Read the icon from proper locale  */
  595.                                         /*  directory.                       */
  596.                                         /* Get locale for program's icon.    */
  597.                                         /* Form icon path name (from the     */
  598.                                         /*  current locale (or LC_MESSAGES   */
  599.                                         /*  if none assigned).               */
  600.                                         /* Load the icon from the file.      */
  601.                                         /* Set up as program's icon.         */
  602.   if (icon_pointer != (HPOINTER) NULL)
  603.   {
  604.      WinDestroyPointer(icon_pointer);
  605.   }
  606.   if   (cur_mess_locale != NO_LOCALE)
  607.   {
  608.        sprintf(t_icon_name, ICON_NAME, locale_names[cur_mess_locale]);
  609.   }
  610.   else
  611.   {
  612.        ret_string = setlocale(LC_MESSAGES, NULL);
  613.        sprintf(t_icon_name, ICON_NAME, ret_string);
  614.   }
  615.   icon_pointer = WinLoadFileIcon(t_icon_name, FALSE);
  616.   WinSendMsg(hwndFrame, WM_SETICON, (MPARAM) icon_pointer, NULL);
  617. }
  618.  
  619. /*****************************************************************************/
  620. /***     Try to open a locale dialog                                       ***/
  621. /*****************************************************************************/
  622.  
  623. void try_to_open(int the_locale, HWND parent_window)
  624. {
  625.                                         /* If the locale isn't already open. */
  626.   if (!locale_active[the_locale])
  627.   {
  628.                                         /* Set the locale in a global.       */
  629.                                         /* Form the locale name string.      */
  630.     which_locale = the_locale;
  631.     sprintf(temp_locale_path, "%s\\%s.DLL", locale_path,
  632.             locale_names[which_locale]);
  633.  
  634.                                         /* If the locale file (.dll) isn't   */
  635.                                         /*  found...                         */
  636.                                         /*  Print a warning.                 */
  637.                                         /* Else, open the dialog for the     */
  638.                                         /*  locale.                          */
  639.     if   (stat(temp_locale_path, &stat_buffer) == FILE_NOT_FOUND)
  640.     {
  641.          error_message(hwndClient,
  642.                    catgets(msg_handle, LOCALE, LOCALE_TEXT,
  643.          "The locale path specified is invalid.  Please use the Locale Menu to enter the correct path."),
  644.                    catgets(msg_handle, LOCALE, LOCALE_TITLE, "Help for WORLD"));
  645.     }
  646.     else
  647.     {
  648.          locale_windows[which_locale] = WinLoadDlg(hwndClient, parent_window,
  649.                                                    country_proc, 0L,
  650.                                                    COUNTRY_DIALOG, NULL);
  651.     }
  652.   }
  653. }
  654.  
  655. /*****************************************************************************/
  656. /***     Window procedure for client child of main window                  ***/
  657. /*****************************************************************************/
  658.  
  659. MRESULT EXPENTRY ClientWndProc(HWND hwndWnd, ULONG ulMsg, MPARAM mpParm1,
  660.                                MPARAM mpParm2)
  661. {
  662.   int t_menu;                           /* Used to remember which locale menu*/
  663.                                         /*  item is selected.                */
  664.   int old_locale;                       /* Old value of "current locale"     */
  665.   int count;                            /* Loop counter.                     */
  666.   static MENUITEM menu_item = {0, MIS_BITMAP, 0, 0, 0, 0};
  667.                                         /* Menu item structure for icons.    */
  668.  
  669.   switch (ulMsg)
  670.   {
  671.     case WM_CREATE:
  672.          {
  673.            HPS hpsWnd;                  /* Handle to presentation space.     */
  674.  
  675.                                         /* Get presentation space.           */
  676.                                         /* Load bitmap into it.              */
  677.                                         /*   Read in bitmap for that locale  */
  678.                                         /*    (the flag). For menus.         */
  679.                                         /* Release the presentation space.   */
  680.            hpsWnd = WinGetPS(hwndWnd);
  681.            GpiLoadBitmap(hpsWnd, NULLHANDLE, BITMAP_WORLD, 500, 350);
  682.            for (count = 0; count < NUM_LOCALES; count++)
  683.            {
  684.              locale_bitmaps[count] = GpiLoadBitmap(hpsWnd, NULLHANDLE,
  685.                                                    BITMAP_LANG0 + count,
  686.                                                    32, 32);
  687.            }
  688.            WinReleasePS(hpsWnd);
  689.          }
  690.          break;
  691.     case WM_ERASEBACKGROUND:
  692.          return MRFROMSHORT(TRUE);
  693.     case WM_PAINT:
  694.          {
  695.            HPS          hpsWnd;         /* Presentation space handle.        */
  696.            HBITMAP      hbmBitmap;      /* Bitmap handle.                    */
  697.            POINTL       ptl;            /* A point used in painting.         */
  698.  
  699.                                         /* Bitmap drawn from the corner.     */
  700.            ptl.x = 0;
  701.            ptl.y = 0;
  702.  
  703.                                         /* Start painting.                   */
  704.                                         /* Clear the presentation space.     */
  705.            hpsWnd = WinBeginPaint(hwndWnd, 0L, 0L);
  706.            GpiErase(hpsWnd);
  707.  
  708.                                         /* Load in the bitmap.               */
  709.                                         /* Draw it on the presentation space.*/
  710.                                         /* Release the memory for the bitmap.*/
  711.                                         /* End painting.                     */
  712.            hbmBitmap = GpiLoadBitmap(hpsWnd, NULLHANDLE, BITMAP_WORLD,
  713.                                      557, 353);
  714.            WinDrawBitmap(hpsWnd, hbmBitmap, NULL, &ptl, CLR_NEUTRAL,
  715.                          CLR_BACKGROUND, DBM_NORMAL);
  716.            GpiDeleteBitmap(hbmBitmap);
  717.            WinEndPaint(hpsWnd);
  718.          }
  719.          break;
  720.                                         /* If the user clicks or double      */
  721.                                         /*  clicks...                        */
  722.     case WM_BUTTON1DOWN:
  723.     case WM_BUTTON1DBLCLK:
  724.          {
  725.            int sel_a_city = FALSE;      /* Was a city selected?              */
  726.            SHORT x, y;                  /* Mouse location.                   */
  727.  
  728.                                         /* Get the location of the click.    */
  729.            x = MOUSEMSG(&ulMsg)->x;
  730.            y = MOUSEMSG(&ulMsg)->y;
  731.  
  732.                                         /* Go through all the locales...     */
  733.                                         /*  If the click is in the rectangle */
  734.                                         /*   defined for this locale...      */
  735.                                         /*   Try to open the dialog.         */
  736.                                         /*   Mark that we did click on a city*/
  737.                                         /*   Terminate the loop.             */
  738.            for (count = 0; count < NUM_LOCALES; count++)
  739.            {
  740.                if (((x > locale_hit_locs[count].xLeft) &&
  741.                     (x < locale_hit_locs[count].xRight)) &&
  742.                    ((y > locale_hit_locs[count].yBottom) &&
  743.                     (y < locale_hit_locs[count].yTop)))
  744.                {
  745.                   try_to_open(count, hwndWnd);
  746.                   sel_a_city = TRUE;
  747.                   count = NUM_LOCALES;
  748.                }
  749.            }
  750.  
  751.                                         /* If no city selected...            */
  752.                                         /*  Put up a message.                */
  753.            if (!sel_a_city)
  754.            {
  755.               error_message(hwndWnd,
  756.                         catgets(msg_handle, HELP, SEL_TEXT, "Please select a city."),
  757.                         catgets(msg_handle, HELP, HELP_TITLE, "Help for WORLD"));
  758.            }
  759.          }
  760.          break;
  761.                                         /* If a menu item selected...        */
  762.                                         /* Put up proper dialog for the item.*/
  763.     case WM_COMMAND:
  764.          switch (SHORT1FROMMP(mpParm1))
  765.          {
  766.            case MENU_LOCALE_SET:
  767.                             WinDlgBox(HWND_DESKTOP, hwndWnd,
  768.                                       locale_path_dialog_func, 0,
  769.                                       LOCALE_PATH_DIALOG, 0);
  770.                             break;
  771.            case MENU_FILE_HELP:
  772.                             display_help();
  773.                             break;
  774.            case MENU_FILE_ABOUT:
  775.                             WinDlgBox(HWND_DESKTOP, hwndWnd, about_dialog_func,
  776.                                       0, ABOUT_DIALOG, 0);
  777.                             break;
  778.            case MENU_OPTIONS_ICON:
  779.                                         /* Toggling the icon in menus option.*/
  780.                                         /*  Toggle the flag.                 */
  781.                                         /*  Check/uncheck item as needed.    */
  782.                             icons_in_menus = !icons_in_menus;
  783.                             WinCheckMenuItem(hwnd_menu, MENU_OPTIONS_ICON,
  784.                                              icons_in_menus);
  785.  
  786.                                         /* If drawing icons now...           */
  787.                                         /*  Loop through all locales.        */
  788.                                         /*   Set bitmap for each menu item.  */
  789.                                         /*   Set id of each menu item.       */
  790.                                         /*   Send change to the menu.        */
  791.                             if   (icons_in_menus)
  792.                             {
  793.                                  for (count = 0; count < NUM_LOCALES; count++)
  794.                                  {
  795.                                    menu_item.hItem = (ULONG)
  796.                                                      locale_bitmaps[count];
  797.                                    menu_item.id = (ULONG) (MENU_LANGS_LANG0 +
  798.                                                            count);
  799.                                    WinSendMsg(hwnd_menu, MM_SETITEM,
  800.                                               MPFROM2SHORT(0, TRUE),
  801.                                               MPFROMP(&menu_item));
  802.                                  }
  803.                             }
  804.                             else
  805.                             {
  806.                                         /* If setting text in menu, do it.   */
  807.                                  set_messages_menu();
  808.                             }
  809.                                         /* Check proper item in menu.        */
  810.                             WinCheckMenuItem(hwnd_menu, MENU_LANGS_LANG0 +
  811.                                              cur_mess_locale, TRUE);
  812.                             break;
  813.            case MENU_LANGS_LANG0:
  814.            case MENU_LANGS_LANG1:
  815.            case MENU_LANGS_LANG2:
  816.            case MENU_LANGS_LANG3:
  817.            case MENU_LANGS_LANG4:
  818.            case MENU_LANGS_LANG5:
  819.            case MENU_LANGS_LANG6:
  820.            case MENU_LANGS_LANG7:
  821.            case MENU_LANGS_LANG8:
  822.            case MENU_LANGS_LANG9:
  823.            case MENU_LANGS_LANG10:
  824.            case MENU_LANGS_LANG11:
  825.                                         /* If they select a new message lang.*/
  826.                                         /*  Get the menu item number.        */
  827.                                         /*  If they selected a new language  */
  828.                                         /*   Save the old locale number.     */
  829.                                         /*   Set up the new locale number.   */
  830.                                         /*   If changing the message catalog */
  831.                                         /*    and setting the menu texts went*/
  832.                                         /*    OK...                          */
  833.                                         /*    Uncheck the old locale item.   */
  834.                                         /*    Check the new locale menu item.*/
  835.                                         /*    Change the main program icon to*/
  836.                                         /*     one appropriate for the new   */
  837.                                         /*     locale.                       */
  838.                                         /*   Otherwise...                    */
  839.                                         /*    Restore the original locale num*/
  840.                             t_menu = SHORT1FROMMP(mpParm1);
  841.                             if ((t_menu - MENU_LANGS_LANG0) != cur_mess_locale)
  842.                             {
  843.                                old_locale = cur_mess_locale;
  844.                                cur_mess_locale = t_menu - MENU_LANGS_LANG0;
  845.                                if   (set_text_for_menus())
  846.                                {
  847.                                     WinCheckMenuItem(hwnd_menu,
  848.                                                      MENU_LANGS_LANG0 +
  849.                                                      old_locale, FALSE);
  850.                                     WinCheckMenuItem(hwnd_menu, t_menu, TRUE);
  851.                                     set_locale_based_icon();
  852.                                }
  853.                                else
  854.                                {
  855.                                     cur_mess_locale = old_locale;
  856.                                }
  857.                             }
  858.                             break;
  859.            default:
  860.                             return WinDefWindowProc(hwndWnd, ulMsg, mpParm1,
  861.                                                     mpParm2);
  862.          }
  863.          break;
  864.     default: return WinDefWindowProc(hwndWnd, ulMsg, mpParm1, mpParm2);
  865.   }
  866.   return MRFROMSHORT(FALSE);
  867. }
  868.  
  869. /*****************************************************************************/
  870. /***     Clean up at end of program                                        ***/
  871. /*****************************************************************************/
  872.  
  873. void clean_up(void)
  874. {
  875.   int count;                            /* Loop counter.                     */
  876.  
  877.                                         /* Get rid of the minimized icon.    */
  878.                                         /* Get rid of all locale bitmaps.    */
  879.   WinDestroyPointer(icon_pointer);
  880.   for (count = 0; count < NUM_LOCALES; count++)
  881.   {
  882.       GpiDeleteBitmap(locale_bitmaps[count]);
  883.   }
  884.  
  885. }
  886.  
  887. /*****************************************************************************/
  888. /***     Main program                                                      ***/
  889. /*****************************************************************************/
  890.  
  891. INT main(void)
  892. {
  893.   HAB            habAnchor;             /* Anchor block for program.         */
  894.   HMQ            hmqQueue;              /* Message queue for program.        */
  895.   QMSG           qmMsg;                 /* A message to pull from queue.     */
  896.   ULONG          ulFlags;               /* Creation flags for window frame.  */
  897.  
  898.                                         /* Initialize values for the program.*/
  899.   initialize();
  900.  
  901.                                         /* Get the anchor block for program. */
  902.                                         /* Create message queue for program. */
  903.   habAnchor = WinInitialize(0);
  904.   hmqQueue = WinCreateMsgQueue(habAnchor, 0);
  905.  
  906.                                         /* Open the message catalog          */
  907.   open_message_catalog();
  908.  
  909.                                         /* Register main window class        */
  910.                                         /* Define flags for frame window for */
  911.                                         /*  main window.  Standard window    */
  912.                                         /*  except: no maximize box, and we  */
  913.                                         /*  will position the window.        */
  914.                                         /* Create the main window.           */
  915.                                         /*  NOTE: The title for the window   */
  916.                                         /*  is gotten from the message       */
  917.                                         /*  catalog.                         */
  918.   WinRegisterClass(habAnchor, CLS_CLIENT, ClientWndProc, CS_SIZEREDRAW, 0);
  919.   ulFlags = FCF_STANDARD & ~FCF_MAXBUTTON & ~FCF_SHELLPOSITION &
  920.             ~FCF_ICON;
  921.   hwndFrame = WinCreateStdWindow(HWND_DESKTOP, 0, &ulFlags, CLS_CLIENT, "",
  922.                                  0, NULLHANDLE, RES_CLIENT, &hwndClient);
  923.   set_locale_based_icon();
  924.  
  925.                                         /* Get a handle to the menu window   */
  926.                                         /*  (will need this later to change  */
  927.                                         /*   the text of the menu items).    */
  928.                                         /* Set the language for the menus    */
  929.                                         /*  (and title) based on the locale  */
  930.                                         /*  settings.                        */
  931.   hwnd_menu = WinWindowFromID(hwndFrame, FID_MENU);
  932.   set_text_for_menus();
  933.  
  934.                                         /* If window created OK...           */
  935.                                         /*  Get the width and height of the  */
  936.                                         /*   screen, so we can center.       */
  937.                                         /*  Center the window in the screen. */
  938.   if (hwndFrame != NULLHANDLE)
  939.   {
  940.      screen_width = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  941.      screen_height = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  942.      WinSetWindowPos(hwndFrame, NULLHANDLE,
  943.                      (SHORT) (screen_width - WIN_WIDTH) / 2,
  944.                      (SHORT) (screen_height - WIN_HEIGHT) / 2,
  945.                      WIN_WIDTH, WIN_HEIGHT,
  946.                      SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_SHOW);
  947.  
  948.                                         /*  Main message loop:               */
  949.                                         /*  While there are more messages... */
  950.                                         /*   Dispatch this message.          */
  951.      while (WinGetMsg(habAnchor, &qmMsg, NULLHANDLE, 0, 0))
  952.      {
  953.        WinDispatchMsg(habAnchor, &qmMsg);
  954.      }
  955.  
  956.                                         /*  We're done.  Get rid of the main */
  957.                                         /*   window.                         */
  958.      WinDestroyWindow(hwndFrame);
  959.   }
  960.  
  961.                                         /* Close the active message catalog. */
  962.   catclose(msg_handle);
  963.  
  964.                                         /* Get rid of the message queue.     */
  965.                                         /* Get rid of the anchor block.      */
  966.                                         /* Clean up anything that needs it.  */
  967.                                         /* Terminate the program.            */
  968.   WinDestroyMsgQueue(hmqQueue);
  969.   WinTerminate(habAnchor);
  970.   clean_up();
  971.   return(EXIT_NORMAL);
  972. }
  973.