Программирование для Windows NT (том 2)

       

Исходные тексты приложения SETLOCAL


Главный файл исходных текстов приложения SETLOCAL приведен в листинге 4.1.

Листинг 4.1. Файл setlocal\setlocal.c

// ==================================================

// Приложение SETLOCAL

// Работа с национальными языками

//

// (С) Фролов А.В., 1996

// Email: frolov@glas.apc.org

// ==================================================

#define STRICT

#include <windows.h>

#include <windowsx.h>

#include "resource.h"

#include "afxres.h"

#include "setlocal.h"

HINSTANCE hInst;



char szAppName[]  = "SetLocalApp";

char szAppTitle[] = "Set and Get Local Info";

// Количество установленных раскладок клавиатуры

UINT uLayouts;

// Указатель на массив идентификаторов

// раскладок клавиатуры

HKL * lpList;

// -----------------------------------------------------

// Функция WinMain

// -----------------------------------------------------

int APIENTRY

WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

        LPSTR lpCmdLine, int nCmdShow)

{

  WNDCLASSEX wc;

  HWND hWnd;

  MSG msg;

 

  // Сохраняем идентификатор приложения

  hInst = hInstance;

  // Проверяем, не было ли это приложение запущено ранее

  hWnd = FindWindow(szAppName, NULL);

  if(hWnd)

  {

    // Если было, выдвигаем окно приложения на

    // передний план

    if(IsIconic(hWnd))

      ShowWindow(hWnd, SW_RESTORE);

    SetForegroundWindow(hWnd);

    return FALSE;

  }

  // Определяем количество установленных

  // раскалдок клавиатуры

  uLayouts = GetKeyboardLayoutList(0, NULL);

  // Заказываем массив для хранения идентификаторов

  // раскладок клавиатуры

  lpList = malloc(uLayouts * sizeof(HKL));

  // Заполнение массива идентификаторов

  // раскладок клавиатуры

  uLayouts = GetKeyboardLayoutList(uLayouts, lpList);

 

  // Регистрируем класс окна

  memset(&wc, 0, sizeof(wc));

  wc.cbSize = sizeof(WNDCLASSEX);

  wc.hIconSm = LoadImage(hInst,


    MAKEINTRESOURCE(IDI_APPICONSM),

    IMAGE_ICON, 16, 16, 0);

  wc.style = 0;

  wc.lpfnWndProc = (WNDPROC)WndProc;

  wc.cbClsExtra  = 0;

  wc.cbWndExtra  = 0;

  wc.hInstance = hInst;

  wc.hIcon = LoadImage(hInst,

    MAKEINTRESOURCE(IDI_APPICON),

    IMAGE_ICON, 32, 32, 0);

  wc.hCursor = LoadCursor(NULL, IDC_ARROW);

  wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);

  wc.lpszMenuName = MAKEINTRESOURCE(IDR_APPMENU);

  wc.lpszClassName = szAppName;

  if(!RegisterClassEx(&wc))

    if(!RegisterClass((LPWNDCLASS)&wc.style))

         return FALSE;

   

  // Создаем главное окно приложения

  hWnd = CreateWindow(szAppName, szAppTitle,

     WS_OVERLAPPEDWINDOW,

     CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,

     NULL, NULL, hInst, NULL);

  if(!hWnd) return(FALSE);

  // Отображаем окно и запускаем цикл

  // обработки сообщений

  ShowWindow(hWnd, nCmdShow);

  UpdateWindow(hWnd);

  while(GetMessage(&msg, NULL, 0, 0))

  {

    TranslateMessage(&msg);

    DispatchMessage(&msg);

  }

  // Перед завершением работы приложения освобождаем

  // память, полученную для хранения идентификаторов

  // раскладок клавиатуры

  free(lpList);

 

  return msg.wParam;

}

// -----------------------------------------------------

// Функция WndProc

// -----------------------------------------------------

LRESULT WINAPI

WndProc( HWND hWnd, UINT msg, WPARAM wParam,

        LPARAM lParam)

{

  switch(msg)

  {

    HANDLE_MSG(hWnd, WM_COMMAND, WndProc_OnCommand);

    HANDLE_MSG(hWnd, WM_DESTROY, WndProc_OnDestroy);

    default:

      return(DefWindowProc(hWnd, msg, wParam, lParam));

  }

}

// -----------------------------------------------------

// Функция WndProc_OnDestroy

// -----------------------------------------------------

#pragma warning(disable: 4098)

void WndProc_OnDestroy(HWND hWnd)

{

  PostQuitMessage(0);

  return 0L;

}

// -----------------------------------------------------



// Функция WndProc_OnCommand

// -----------------------------------------------------

#pragma warning(disable: 4098)

void WndProc_OnCommand(HWND hWnd, int id,

  HWND hwndCtl, UINT codeNotify)

{

  char szBuf[1024];

  char szBuf1[1024];

  char szKbLayoutName[KL_NAMELENGTH];

  BOOL fRc;

 

  switch (id)

  {

    case ID_FILE_EXIT: 

    {

       // Завершаем работу приложения

       PostQuitMessage(0);

       return 0L;

       break;

    }

        

    // Установка набора национальных параметров для Англии

    case ID_LOCALINFO_SETENGLISH:

    {

      // Выполнение установки для текущей задачи

      fRc = SetThreadLocale(MAKELCID(

        MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL),

        SORT_DEFAULT));

     

      // При возникновении ошибки получаем и отображаем ее код

      if(fRc == FALSE)

      {

        wsprintf(szBuf1,"SetThreadLocale: Error %ld\n",

          GetLastError());

        MessageBox(hWnd, szBuf1, "Error", MB_OK);

      }

      break;

    }

   

    // Установка набора национальных параметров для России

    case ID_LOCALINFO_SETRUSSIAN:

    {

      fRc = SetThreadLocale(MAKELCID(

        MAKELANGID(LANG_RUSSIAN, SUBLANG_NEUTRAL),

        SORT_DEFAULT));

      if(fRc == FALSE)

      {

        wsprintf(szBuf1,"SetThreadLocale: Error %ld\n",

          GetLastError());

        MessageBox(hWnd, szBuf1, "Error", MB_OK);

      }

      break;

    }

   

    // Получение и отображение некоторых

    // национальных параметров

    case ID_LOCALINFO_GETLOCALINFO:

    {

      // Отображение полного названия национального языка

      strcpy(szBuf, "LOCALE_SLANGUAGE: ");

      GetLocaleInfo(

        GetThreadLocale(), LOCALE_SLANGUAGE, szBuf1, 512);

      strcat(szBuf, szBuf1);

      // Отображение кода страны

      strcat(szBuf, "\nLOCALE_ICOUNTRY: ");

      GetLocaleInfo(

        GetThreadLocale(), LOCALE_ICOUNTRY, szBuf1, 512);



      strcat(szBuf, szBuf1);

      // Отображение кодовой страницы OEM

      strcat(szBuf, "\nLOCALE_IDEFAULTCODEPAGE: ");

      GetLocaleInfo(

        GetThreadLocale(), LOCALE_IDEFAULTCODEPAGE,

          szBuf1, 512);

      strcat(szBuf, szBuf1);

      // Отображение кодовой страницы ANSI

      strcat(szBuf, "\nLOCALE_IDEFAULTANSICODEPAGE: ");

      GetLocaleInfo(

        GetThreadLocale(), LOCALE_IDEFAULTANSICODEPAGE,

          szBuf1, 512);

      strcat(szBuf, szBuf1);

      MessageBox(hWnd, szBuf, szAppTitle, MB_OK);

           break;

    }

    // Определение и отображение идентификатора

    // текущей раскладки клавиатуры

    case ID_KEYBOARD_GETLAYOUTID:

    {

      GetKeyboardLayoutName(szKbLayoutName);

      wsprintf(szBuf1,"Layout ID: %s", szKbLayoutName);

     

      MessageBox(hWnd, szBuf1, szAppTitle, MB_OK);

           break;

    }

    // Установка новой раскладки клавиатуры

    case ID_KEYBOARD_SETLAYOUT:

    {

      // Отображение диалоговой панели для выбора

      // раскладки клавиатуры

      DialogBox(hInst,

        MAKEINTRESOURCE(IDD_DIALOG_SETLAYOUT),

        hWnd, DlgProc);

      break;     

    }

    

    // Просмотр текущей даты и времени в формате,

    // принятом для выбранной страны

    case ID_LOCALINFO_GETDATE:

    {

      strcpy(szBuf, "Date: ");

      // Получаем строку даты

      GetDateFormat(

        GetThreadLocale(),

        LOCALE_NOUSEROVERRIDE | DATE_LONGDATE,

        NULL, NULL, szBuf1, 512);

     

      strcat(szBuf, szBuf1);

      strcat(szBuf, "\nTime: ");

     

      // Получаем строку времени

      GetTimeFormat(

        GetThreadLocale(),

        LOCALE_NOUSEROVERRIDE,

        NULL, NULL, szBuf1, 512);

      strcat(szBuf, szBuf1);

     

      // Отображаем время и дату

      MessageBox(hWnd, szBuf, szAppTitle, MB_OK);

      break;     

    }



    case ID_HELP_ABOUT:

    {

      MessageBox(hWnd,

        "Set and Get Local Information\n"

        "(C) Alexandr Frolov, 1996\n"

        "Email: frolov@glas.apc.org",

        szAppTitle, MB_OK | MB_ICONINFORMATION);

            return 0L;

            break;

    }

    default:

      break;

  }

  return FORWARD_WM_COMMAND(hWnd, id, hwndCtl, codeNotify,

    DefWindowProc);

}

// -----------------------------------------------------

// Функция DlgProc

// -----------------------------------------------------

LRESULT WINAPI

DlgProc( HWND hdlg, UINT msg, WPARAM wParam,

        LPARAM lParam)

{

  switch(msg)

  {

    HANDLE_MSG(hdlg, WM_INITDIALOG, DlgProc_OnInitDialog);

    HANDLE_MSG(hdlg, WM_COMMAND,    DlgProc_OnCommand);

       default:

    return FALSE;

  }

}

// -----------------------------------------------------

// Функция DlgProc_OnInitDialog

// -----------------------------------------------------

BOOL DlgProc_OnInitDialog(HWND hdlg, HWND hwndFocus,

                          LPARAM lParam)

{

  UINT i;

  HKL hklCurrent;

  char szBuf[256];

  // При инициализации диалоговой панели получаем в цикле

  // идентификаторы установленных раскладок клавиатуры

  // и заполняем названиями соответствующих национальных

  // языков список типа COMBOBOX, расположенный в

  // диалоговой панели

  for(i=0; i<uLayouts; i++)

  {

    // Берем очередной идентификатор раскладки

    hklCurrent = *(lpList + i);

    // Получаем название национального языка

    GetLocaleInfo(

      MAKELCID(((UINT)hklCurrent & 0xffffffff),

      SORT_DEFAULT),

      LOCALE_SLANGUAGE, szBuf, 512);

    // Вставляем название национального языка в список

    // типа COMBOBOX

    SendMessage(GetDlgItem(hdlg, IDC_COMBO1),

      CB_ADDSTRING, 0, (LPARAM)(LPSTR)szBuf);

  }

  return TRUE;

}

// -----------------------------------------------------



// Функция DlgProc_OnCommand

// -----------------------------------------------------

#pragma warning(disable: 4098)

void DlgProc_OnCommand(HWND hdlg, int id,

  HWND hwndCtl, UINT codeNotify)

{

  // Номер выбранной строки в списке типа COMBOBOX

  LRESULT uSelectedItem;

  switch (id)

  {

    // Когда пользователь нажимает клавишу OK,

    // устанавливаем выбранную раскладку клавиатуры

    // и завершаем работу диалоговой панели

    case IDOK:

    {

      // Определяем номер выбранной в списке строки

      uSelectedItem = SendMessage(

        GetDlgItem(hdlg, IDC_COMBO1),

        CB_GETCURSEL, 0, 0);

      // Активизируем выбранную раскладку клавиатуры

      ActivateKeyboardLayout(*(lpList + uSelectedItem), 0);

      // Завершаем работу диалоговой панели

      EndDialog(hdlg, 1);

      return TRUE;

    }

    // Когда пользователь нажимает клавишу Set layout,

    // устанавливаем выбранную раскладку клавиатуры,

    // не завершая работы диалоговой панели

    case IDC_BUTTON1:

    {

      uSelectedItem = SendMessage(

        GetDlgItem(hdlg, IDC_COMBO1),

        CB_GETCURSEL, 0, 0);

      ActivateKeyboardLayout(*(lpList + uSelectedItem), 0);

      return TRUE;

    }

    // Если пользователь нажал кнопку Cancel, отменяем

    // смену расклдаки клавиатуры, завершая

    // работу диалоговой панели

    case IDCANCEL:

    {

      EndDialog(hdlg, 0);

      return TRUE;

    }

       default:

           break;

  }

  return FALSE;

}

Файл setlocal.h (листинг 4.2) содержит прототипы функций, определенных в приложении SETLOCAL.

Листинг 4.2. Файл setlocal\setlocal.h

// -----------------------------------------------------

// Описание функций

// -----------------------------------------------------

LRESULT WINAPI

WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

void WndProc_OnCommand(HWND hWnd, int id,

  HWND hwndCtl, UINT codeNotify);

void WndProc_OnDestroy(HWND hWnd);



LRESULT WINAPI

DlgProc( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam);

BOOL DlgProc_OnInitDialog(HWND hdlg, HWND hwndFocus,

                          LPARAM lParam);

void DlgProc_OnCommand(HWND hdlg, int id,

  HWND hwndCtl, UINT codeNotify);

В файле resource.h (листинг 4.3), который создается автоматически системой разработки приложений Microsoft Visual C++, находятся определения констант для файла описания ресурсов.

Листинг 4.3. Файл setlocal\resource.h

//{{NO_DEPENDENCIES}}

// Microsoft Developer Studio generated include file.

// Used by setlocal.rc

//

#define IDR_MENU1                       101

#define IDR_APPMENU                     101

#define IDI_APPICON                     102

#define IDI_APPICONSM                   103

#define IDD_DIALOG_SETLAYOUT            104

#define IDC_COMBO1                      1003

#define IDC_EDIT1                       1004

#define IDC_BUTTON1                     1005

#define ID_FILE_EXIT                    40001

#define ID_HELP_ABOUT                   40002

#define ID_KEYBOARD_SETLAYOUT           40004

#define ID_KEYBOARD_GETLAYOUTID         40005

#define ID_LOCALINFO_GETLOCALINFO       40006

#define ID_LOCALINFO_SETENGLISH         40007

#define ID_LOCALINFO_SETRUSSIAN         40008

#define ID_LOCALINFO_GETDATE            40009

// Next default values for new objects

//

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE        105

#define _APS_NEXT_COMMAND_VALUE         40010

#define _APS_NEXT_CONTROL_VALUE         1006

#define _APS_NEXT_SYMED_VALUE           101

#endif

#endif

Файл описания ресурсов приложения setlocal.rc приведен в листинге 4.4. В нем определены меню, диалоговая панель, пиктограммы и текстовые строки.

Листинг 4.4. Файл setlocal\setlocal.rc

//Microsoft Developer Studio generated resource script.

//

#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS

//////////////////////////////////////////////////////////////



//

// Generated from the TEXTINCLUDE 2 resource.

//

#include "afxres.h"

//////////////////////////////////////////////////////////////

#undef APSTUDIO_READONLY_SYMBOLS

//////////////////////////////////////////////////////////////

// Russian resources

#if !defined(AFX_RESOURCE_DLL) defined(AFX_TARG_RUS)

#ifdef _WIN32

LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT

#pragma code_page(1251)

#endif //_WIN32

//////////////////////////////////////////////////////////////

//

// Menu

//

IDR_APPMENU MENU DISCARDABLE

BEGIN

    POPUP "&File"

    BEGIN

        MENUITEM "E&xit",           ID_FILE_EXIT

    END

    POPUP "&Keyboard"

    BEGIN

        MENUITEM "&Set Layout",     ID_KEYBOARD_SETLAYOUT

        MENUITEM "&Get Layout ID",  ID_KEYBOARD_GETLAYOUTID

    END

    POPUP "Local Info"

    BEGIN

        MENUITEM "&Get Local Info", ID_LOCALINFO_GETLOCALINFO

        MENUITEM "Get &Date and Time", ID_LOCALINFO_GETDATE

        MENUITEM SEPARATOR

        MENUITEM "Set &English",    ID_LOCALINFO_SETENGLISH

        MENUITEM "Set &Russian",    ID_LOCALINFO_SETRUSSIAN

    END

    POPUP "&Help"

    BEGIN

        MENUITEM "&About...",       ID_HELP_ABOUT

    END

END

#ifdef APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////

//

// TEXTINCLUDE

//

1 TEXTINCLUDE DISCARDABLE

BEGIN

    "resource.h\0"

END

2 TEXTINCLUDE DISCARDABLE

BEGIN

    "#include ""afxres.h""\r\n"

    "\0"

END

3 TEXTINCLUDE DISCARDABLE

BEGIN

    "\r\n"

    "\0"

END

#endif    // APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////

//

// Icon

//

// Icon with lowest ID value placed first to ensure



// application icon

// remains consistent on all systems.

IDI_APPICON             ICON    DISCARDABLE     "setlocal.ico"

IDI_APPICONSM           ICON    DISCARDABLE     "setlocsm.ico"

//////////////////////////////////////////////////////////////

//

// Dialog

//

IDD_DIALOG_SETLAYOUT DIALOG DISCARDABLE  0, 0, 248, 143

STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU

CAPTION "Set Keyboard Layout"

FONT 8, "MS Sans Serif"

BEGIN

    DEFPUSHBUTTON   "OK",IDOK,191,7,50,14

    PUSHBUTTON      "Cancel",IDCANCEL,191,24,50,14

    COMBOBOX        IDC_COMBO1,14,65,102,64,CBS_DROPDOWN |

                    CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL |

                    WS_TABSTOP

    EDITTEXT        IDC_EDIT1,14,28,150,14,ES_AUTOHSCROLL

    LTEXT           "Keyboard layouts:",IDC_STATIC,14,51,57,8

    LTEXT           "Enter text to test layout:",

                       IDC_STATIC,14,14,75,8

    PUSHBUTTON      "Set layout",IDC_BUTTON1,191,64,50,14

END

//////////////////////////////////////////////////////////////

//

// DESIGNINFO

//

#ifdef APSTUDIO_INVOKED

GUIDELINES DESIGNINFO DISCARDABLE

BEGIN

    IDD_DIALOG_SETLAYOUT, DIALOG

    BEGIN

        LEFTMARGIN, 7

        RIGHTMARGIN, 241

        TOPMARGIN, 7

        BOTTOMMARGIN, 136

    END

END

#endif    // APSTUDIO_INVOKED

#endif    // Russian resources

//////////////////////////////////////////////////////////////

#ifndef APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////

//

// Generated from the TEXTINCLUDE 3 resource.

//

//////////////////////////////////////////////////////////////

#endif    // not APSTUDIO_INVOKED


Содержание раздела