Исходные тексты приложения 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