Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Операционная система Windows 95 для программиста

© Александр Фролов, Григорий Фролов
Том 22, М.: Диалог-МИФИ, 1993, 271 стр.

[Назад] [Содеожание] [Дальше]

7.7. Приложение UpDown

Несложное приложение UpDown демонстрирует, как это нетрудно догадаться из его названия, работу органа управления Up-Down. Дополнительно в этом приложении мы создаем комбинацию клавиш активизации, работаем с сообщением WM_SETHOTKEY и органом управления Hot Key.

Если выбрать строку Options из главного меню приложения File, на экране появится диалоговая панель Value Selection, показанная на рис. 7.9.

Рис. 7.9. Диалоговая панель Value Selection

В этой панели вы можете задать с помощью органа управления Up-Down некоторое значение, и посмотреть результат, нажав кнопку OK.

В процессе инициализации своего главного окна приложение определяет комбинацию клавиш активизации <Ctrl + Alt + V>. Если нажать эту комбинацию клавиш, появится все та же диалоговая панель.

Для изменения комбинации клавиш активизации вы можете передать фокус ввода органу управления Hot Key, нажать новую комбинацию клавиш и затем нажать кнопку Set HotKey. После этого новая комбинация клавиш может быть использована для активизации диалоговой панели Value Selection.

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

Исходные тексты всех функций приложения UpDown собраны в файле updown.c (листинг 7.6).

Листинг 7.6. Файл updown\updown.c



#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include "resource.h"
#include "afxres.h"
#include "updown.h"

HINSTANCE hInst;
char szAppName[]  = "UpDownApp";
char szAppTitle[] = "Up-Down and HotKey Demo";

HWND hwndEdit;
HWND hwndUpDown;
HWND hwndMainWindow;

HWND hwndHotKey;
WORD wHotKey;

// -----------------------------------------------------
// Функция 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;
  }

  // Регистрируем класс окна
  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);

  // Сохраняем идентификатор главного окна
  hwndMainWindow = hWnd;

  // Отображаем окно и запускаем цикл обработки сообщений
  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);
  while(GetMessage (&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return msg.wParam;
}

// -----------------------------------------------------
// Функция WndProc
// -----------------------------------------------------
LRESULT WINAPI
WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch(msg)
  {
    HANDLE_MSG(hWnd, WM_CREATE,     WndProc_OnCreate);
    HANDLE_MSG(hWnd, WM_DESTROY,    WndProc_OnDestroy);
    HANDLE_MSG(hWnd, WM_COMMAND,    WndProc_OnCommand);
    HANDLE_MSG(hWnd, WM_SYSCOMMAND, WndProc_OnSysCommand);

    default:
      return(DefWindowProc(hWnd, msg, wParam, lParam));
  }
}

// -----------------------------------------------------
// Функция WndProc_OnCreate
// -----------------------------------------------------
BOOL WndProc_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
  // Инициализируем библиотеку стандартных органов управления
  InitCommonControls();

  // Устанавливаем комбинацию клавиш активизации
  // диалоговой панели <Alt+Ctrl+V>
  SendMessage(hWnd, WM_SETHOTKEY, 
    (WPARAM)MAKEWORD('V', HOTKEYF_ALT | HOTKEYF_CONTROL), 0); 

  return TRUE;
}

// -----------------------------------------------------
// Функция 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)
{
  switch (id)
  {
    case ID_FILE_EXIT:  
      PostQuitMessage(0); // завершаем работу приложения
      return 0L;
      break;
      
      case ID_HELP_ABOUT:
      MessageBox(hWnd, 
        "Up-Down and HotKey Demo Application, v.1.0\n"
        "(C) Alexandr Frolov, 1995\n"
        "Email: frolov@glas.apc.org",
        szAppTitle, MB_OK | MB_ICONINFORMATION);
      return 0L;
      break;

    case ID_FILE_OPTIONS:  
    {
      DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), 
        NULL, DlgProc);
      return 0L;
      break;
    }
    default:
      break;
  }
  return FORWARD_WM_COMMAND(hWnd, id, hwndCtl, 
    codeNotify, DefWindowProc);
}

// -----------------------------------------------------
// Функция DlgProc
// -----------------------------------------------------
BOOL APIENTRY
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:
      break;
  }
  return FALSE;
}

// -----------------------------------------------------
// Функция DlgProc_OnInitDialog
// Вызывается при инициализации первой страницы
// -----------------------------------------------------
BOOL DlgProc_OnInitDialog(HWND hdlg, 
  HWND hwndFocus, LPARAM lParam)
{
  // Получаем идентификатор редактора текста
  hwndEdit   = GetDlgItem(hdlg, IDC_EDIT1);
  
  // Создаем орган управления Up-Down и подключаем
  // его к редактору текста. Задаем начальное
  // и конечное значение, инициализируем 
  // редактор текста
  hwndUpDown = CreateUpDownControl(
    WS_CHILD | WS_BORDER | WS_VISIBLE | 
    UDS_WRAP | UDS_ARROWKEYS | UDS_ALIGNRIGHT |
    UDS_SETBUDDYINT,     
    0, 0, 0, 0, hdlg, IDC_UPDOWN, hInst,
    hwndEdit,10, 1, 1);

  // Получаем идентификатор органа Hot Key
  hwndHotKey = GetDlgItem(hdlg, IDC_HOTKEY);

  // Получаем код комбинации клавиш, которая
  // используется для активизации диалоговой панели
  wHotKey = 
    (WORD)SendMessage(hwndMainWindow, WM_GETHOTKEY, 0, 0); 
  
  // Устанавливаем начальное состояние органа Hot Key
  // в соответствии с полученным кодом
  if(wHotKey != 0)
    SendMessage(hwndHotKey, HKM_SETHOTKEY, wHotKey, 0); 

  return TRUE;
}

// -----------------------------------------------------
// Функция DlgProc_OnCommand
// -----------------------------------------------------
#pragma warning(disable: 4098)
void DlgProc_OnCommand(HWND hdlg, int id, 
  HWND hwndCtl, UINT codeNotify)
{
  int nValue;
  char szBuf[80];
  BOOL fError;

  switch (id)
  {
    case IDOK:
    {
      // Определяем и отображаем выбранное значение
      nValue = (int)GetDlgItemInt(hdlg,
        IDC_EDIT1, &fError, FALSE);
      
      wsprintf(szBuf, "Value:\t%d", nValue);
      MessageBox(NULL, szBuf,
        szAppTitle, MB_OK | MB_ICONINFORMATION);
       
      EndDialog(hdlg, TRUE); 
      break;
    }

    case IDC_SETHOTKEYBUTTON:
    {
      // Получаем код комбинации клавиш, которая
      // используется для активизации диалоговой панели
      wHotKey = 
        (WORD)SendMessage(hwndHotKey, HKM_GETHOTKEY, 0, 0); 
      
      // Устанавливаем новую комбинацию клавиш для 
      // активизации диалоговой панели 
      SendMessage(hwndMainWindow, WM_SETHOTKEY, wHotKey, 0); 
        break;
    }

    case IDCANCEL:
    {
      EndDialog(hdlg, TRUE); 
      break;
    }
      
    default:
      return FALSE;
  }
  return TRUE;
}

// -----------------------------------------------------
// Функция WndProc_OnSysCommand
// -----------------------------------------------------
#pragma warning(disable: 4098)
void WndProc_OnSysCommand(HWND hwnd, UINT cmd, int x, int y)
{
  // Если пришло сообщение от клавиши активизации,
  // посылаем функции главного окна сообщение WM_COMMAND
  // с кодом, соответствующем строке Options меню File
  // для активизации диалоговой панели
  if(cmd == SC_HOTKEY)
  {
    SendMessage(hwndMainWindow, WM_COMMAND,
     (WPARAM)MAKELONG(ID_FILE_OPTIONS, 0), 0L);
    return 0;
  }
  return FORWARD_WM_SYSCOMMAND(hwnd, cmd, x, y, DefWindowProc);
}

Описания функция и идентификатор IDC_UPDOWN органа управления Up-Down находятся в файле updown.h (листинг 7.7).

Листинг 7.7 Файл updown\updown.h


// -----------------------------------------------------
// Описание функций
// -----------------------------------------------------
LRESULT WINAPI
WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL WndProc_OnCreate(HWND hWnd, 
  LPCREATESTRUCT lpCreateStruct);
void WndProc_OnDestroy(HWND hWnd);
void WndProc_OnCommand(HWND hWnd, int id, 
  HWND hwndCtl, UINT codeNotify);
BOOL APIENTRY
DlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL DlgProc_OnInitDialog(HWND hwnd, 
  HWND hwndFocus, LPARAM lParam);
void DlgProc_OnCommand(HWND hWnd, int id, 
  HWND hwndCtl, UINT codeNotify);
void WndProc_OnSysCommand(HWND hwnd, UINT cmd, int x, int y);
#define IDC_UPDOWN 1224

В файле resource.h (листинг 7.8), созданном автоматически, определены константы идентификаторов ресурсов приложения.

Листинг 7.8 Файл updown\resource.h


//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by UPDOWN.RC
//
#define IDR_APPMENU                     102
#define IDI_APPICON                     103
#define IDI_APPICONSM                   104
#define IDD_DIALOG1                     121
#define IDC_EDIT1                       1009
#define IDC_HOTKEY                      1010
#define IDC_SETHOTKEYBUTTON             1011
#define ID_FILE_EXIT                    40001
#define ID_HELP_ABOUT                   40003
#define ID_FILE_OPTIONS                 40029

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        126
#define _APS_NEXT_COMMAND_VALUE         40030
#define _APS_NEXT_CONTROL_VALUE         1012
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

Файл updown.rc (листинг 7.9) содрежит определения ресурсов приложения.

Листинг 7.9 Файл updown\updown.rc


//Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
//////////////////////////////////////////////////////////////
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

//////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

//////////////////////////////////////////////////////////////
// Menu
//

IDR_APPMENU MENU DISCARDABLE 
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "&Options...",                 ID_FILE_OPTIONS
        MENUITEM SEPARATOR
        MENUITEM "E&xit",                       ID_FILE_EXIT
    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
//

IDI_APPICON             ICON    DISCARDABLE     "updown.ico"
IDI_APPICONSM           ICON    DISCARDABLE     "updownsm.ico"

//////////////////////////////////////////////////////////////
// Dialog
//

IDD_DIALOG1 DIALOG DISCARDABLE  0, 0, 194, 95
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Value selection"
FONT 8, "MS Sans Serif"
BEGIN
    EDITTEXT        IDC_EDIT1,15,9,40,13,ES_AUTOHSCROLL
    DEFPUSHBUTTON   "OK",IDOK,130,6,50,14
    PUSHBUTTON      "Cancel",IDCANCEL,130,23,50,14
    CONTROL         "Generic1",IDC_HOTKEY,"msctls_hotkey32",WS_TABSTOP,13,66,
                    80,12
    PUSHBUTTON      "Set HotKey",IDC_SETHOTKEYBUTTON,130,65,50,14
    GROUPBOX        "Hot Key",IDC_STATIC,8,49,178,40
END

//////////////////////////////////////////////////////////////
// String Table
//

STRINGTABLE DISCARDABLE 
BEGIN
    ID_FILE_EXIT            "Quits the application"
END

#ifndef APSTUDIO_INVOKED
//////////////////////////////////////////////////////////////
// Generated from the TEXTINCLUDE 3 resource.
//////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

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

Расскажем о наиболее важных функциях, определенных в приложении Up-Down.

WndProc_OnCreate

Функция WndProc_OnCreate обрабатывает сообщение WM_CREATE , поступающее в функцию главного окна приложения при его инициализации.

После инициализации библиотеки стандартных органов управления функция WndProc_OnCreate определяет комбинацию клавиш <Alt+Ctrl+V> как комбинацию клавиш активизации диалоговой панели Value Selection (рис. 7.9). Для этого главному окну приложения посылается сообщение WM_SETHOTKEY .

WndProc_OnCommand

Функция WndProc_OnCommand содержит обработчик сообщения WM_COMMAND , поступающего от главного меню приложения, а также в том случае, если пользователь нажимает комбинацию клавиш активизации диалоговой панели Value Selection.

Если вместе с этим сообщением приходит код команды ID_FILE_OPTIONS, с помощью функции DialogBox создается указанная выше диалоговая панель.

DlgProc_OnInitDialog

Функция DlgProc_OnInitDialog вызывается при инициализации диалоговой панели Value Selection, когда в окно этой диалоговой панели приходит сообщение WM_INITDIALOG .

При этом вначале соответствующий обработчик получает идентификатор окна редактора текста, к которому будет привязан орган управления Up-Down, и сохраняет его в переменной hwndEdit.

Затем с помощью функции CreateUpDownControl создается орган управления Up-Down. Функция CreateUpDownControl привязывает созданный орган управления к редактору текста hwndEdit и выполняет все необходимые инициализирующие действия.

Далее функции главного окна приложения посылается сообщение WM_GETHOTKEY . Если для приложения определена комбинация клавиш активизации, то эта комбинация используется для инициализации органа управления Hot Key, расположенного в диалоговой панели Value Selection.

DlgProc_OnCommand

Эта функция обрабатывает сообщение WM_COMMAND , поступающее в функцию окна диалоговой панели Value Selection от органов управления, расположенных в этой диалоговой панели.

Если пользователь нажимает кнопку OK, обработчик получает целое значение, соответствующее текстовой строке из редактора IDC_EDIT1. Так как последний был привязан к органу управления Up-Down, полученное значение соответствует текущему для органа Up-Down.

В том случае, когда пользователь нажимает клавишу Set HotKey, обработчик считывает новую комбинацию клавиш активизации из органа управления Hot Key, посылая последнему сообщение HKM_GETHOTKEY , и записывает ее в переменную wHotKey.

Далее полученная комбинация клавиш устанавливается в качестве комбинации клавиш активизации при помощи сообщения WM_SETHOTKEY .

WndProc_OnSysCommand

Функция WndProc_OnSysCommand обрабатывает сообщение WM_SYSCOMMAND , поступающее в главное окно приложения в том случае, если пользователь нажмет комбинацию клавиш активизации.

Этот обработчик посылает главному окну приложения сообщение WM_COMMAND с кодом команды ID_FILE_OPTIONS. В результате на экране появится диалоговая панель Value Selection.

[Назад] [Содеожание] [Дальше]