Электронная библиотека книг Александра Фролова и Григория Фролова.
 
Библиотека
Братьев
Фроловых
Электронная библиотека книг Александра Фролова и Григория Фролова.
Библиотека системного программиста
Программирование на JAVA
ПК. Шаг за шагом
Другие книги
Восстановление данных
Антивирусная защита
Статьи для
программистов
Пользователю компьютера

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

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

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

3.5. Приложение List Application

В качестве примера мы приведем исходные тексты приложения List Application, отображающего список приложений из 15 тома "Библиотеки системного программиста", посвященного созданию систем мультимедиа для Microsoft Windows.

В режиме детального отчета (рис. 3.1) для каждого приложения отображается его пиктограмма, название приложения, а также такие дополнительные элементы, как имя файла, содержащего приложение и стоимость в USD (не подумайте только, что мы и в самом деле продаем их по такой бешеной цене!).

Рис. 3.1. Просмотр списка в виде детального отчета

Нажимая заголовки столбцов, вы сможете отсортировать список по названию, по имени файла пиктограммы, или по цене. Ширина столбцов поддается регулировке. Причем, если сделать двойной щелчок левой клавишей мыши по разделителю заголовка столбцов, ширина столбца, расположенного слева от разделителя, станет такой, чтобы в столбце поместилась самая длинная текстовая строка.

Если из меню Options выбрать строку Icon view, режим просмотра списка изменится (рис. 3.2).

Рис. 3.2. Просмотр списка в виде пиктограмм стандартного размера

С помощью строки Small icon view можно просматривать список в виде пиктограмм уменьшенного размера (рис. 3.3).

Рис. 3.3. Просмотр списка в виде пиктограмм уменьшенного размера

И, наконец, выбрав из меню Options строку List view, вы можете перевести окно органа управления List View в режим просмотра простого списка (рис. 3.4).

Рис. 3.4. Простой список с пиктограммами уменьшенного размера

В любом режиме просмотра вы сможете редактировать название приложения, выбрав его и затем сделав по имени щелчок левой клавишей мыши.

Если же вы сделаете двойной щелчок левой клавишей мыши по пиктограмме или названию любого приложения, на экране появится диалоговая панель, в которой отображаются атрибуты выбранного вами элемента списка (рис. 3.5).

Рис. 3.5. Отображение информации, связанной с выбранным элементом списка

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

Все функции приложения List Application определены в файле list.c (листинг 3.1).

Листинг 3.1. Файл list\list.c


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

typedef struct tagAPPLINFO
{
  char szAppName[40];
  char szIconName[20];
  UINT iCost;
} APPLINFO;

// -----------------------------------------------------
// Глобальные переменные
// -----------------------------------------------------
APPLINFO rgApplInfo[]=
{
  {"Generic",           "appicon.ico ",   5},
  {"Book",              "book1.ico   ",   2},
  {"Driver List",       "drvlist.ico ",  22},
  {"MCI CD Player",     "mcicdpl.ico ", 345},
  {"MCI String Player", "mcistrvw.ico",  54},
  {"MCI Wave Player",   "mciwaver.ico",  32},
  {"MCI Window Demo",   "mciwnd.ico  ",   0},
  {"Sound Play",        "sndplay.ico ",   0},
  {"Wave Play",         "wave.ico    ",   4}
};
HINSTANCE hInst;
char szAppName[]  = "ListApp";
char szAppTitle[] = "List Application";
HWND hwndList;

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

  // Отображаем окно и запускаем цикл обработки сообщений
  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_NOTIFY,     WndProc_OnNotify);
    HANDLE_MSG(hWnd, WM_SIZE,       WndProc_OnSize);

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

// -----------------------------------------------------
// Функция WndProc_OnCreate
// -----------------------------------------------------
BOOL WndProc_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
  int i;
  RECT rc;
  HIMAGELIST himlSmall;
  HIMAGELIST himlLarge;
  HICON hIcon;
  LV_COLUMN lvc;
  LV_ITEM lvi;

  // Определяем размеры внутренней области главного окна
  GetClientRect(hWnd, &rc);

  // Инициализируем библиотеку стандартных органов управления
  InitCommonControls();

  // Создаем орган управления List View
  hwndList = CreateWindowEx(0L, WC_LISTVIEW, "",
    WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_REPORT | 
    LVS_EDITLABELS,
    0, 0, rc.right - rc.left, rc.bottom - rc.top,
    hWnd, (HMENU) IDC_LISTVIEW, hInst, NULL);

  if(hwndList == NULL)
    return FALSE;

  // Создаем список изображений
  himlSmall = ImageList_Create(
  GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),
    ILC_MASK, 9, 1);
  himlLarge = ImageList_Create(
    GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON),
    ILC_MASK, 9, 1);

  for(i = IDI_ICON1; i <= IDI_ICON9; i++)
  {
    hIcon = LoadIcon(hInst, MAKEINTRESOURCE(i));
    ImageList_AddIcon(himlSmall, hIcon);
    ImageList_AddIcon(himlLarge, hIcon);
}
  
  // Добавляем списки изображений
  ListView_SetImageList(hwndList, himlSmall, LVSIL_SMALL);
  ListView_SetImageList(hwndList, himlLarge, LVSIL_NORMAL);

  // Вставляем столбцы
  memset(&lvc, 0, sizeof(lvc));

  lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  lvc.fmt = LVCFMT_LEFT;
  lvc.cx = (rc.right - rc.left) / 4;
  
  lvc.iSubItem = 0;
  lvc.pszText = "Application Name";
  ListView_InsertColumn(hwndList, 0, &lvc);

  lvc.iSubItem = 1;
  lvc.pszText = "Icon Name";
  ListView_InsertColumn(hwndList, 1, &lvc);

  lvc.iSubItem = 2;
  lvc.pszText = "Cost, USD";
  ListView_InsertColumn(hwndList, 2, &lvc);
  ListView_SetColumnWidth(hwndList,2,(rc.right-rc.left) / 8);

  // Вставляем строки
  memset(&lvi, 0, sizeof(lvi));

  lvi.mask = LVIF_IMAGE | LVIF_TEXT | LVIF_PARAM;
  lvi.pszText = LPSTR_TEXTCALLBACK;
  
  for(i=0; i<9; i++)
  {
    lvi.iItem = i;
    lvi.iSubItem = 0;
    lvi.cchTextMax = 40;
    lvi.lParam = (LPARAM)&rgApplInfo[i];
	
    lvi.iImage = i;
    ListView_InsertItem(hwndList, &lvi);

    lvi.iItem = i;
    lvi.iSubItem = 1;
    ListView_InsertItem(hwndList, &lvi);

    lvi.iItem = i;
    lvi.iSubItem = 2;
    ListView_InsertItem(hwndList, &lvi);
  }
  return TRUE;
}

// -----------------------------------------------------
// Функция WndProc_OnDestroy
// -----------------------------------------------------
#pragma warning(disable: 4098)
void WndProc_OnDestroy(HWND hWnd)
{
  DestroyWindow(hwndList);
  PostQuitMessage(0);
  return 0L;
}

// -----------------------------------------------------
// Функция WndProc_OnCommand
// -----------------------------------------------------
#pragma warning(disable: 4098)
void WndProc_OnCommand(HWND hWnd, int id, 
  HWND hwndCtl, UINT codeNotify)
{
  DWORD dwStyle = 0;
  switch (id)
  {
    case ID_OPTIONS_ICONVIEW:
    {
      dwStyle = GetWindowLong(hwndList, GWL_STYLE);
      if((dwStyle & LVS_TYPEMASK) != LVS_ICON)
        SetWindowLong(hwndList, GWL_STYLE, 
          (dwStyle & ~LVS_TYPEMASK) | LVS_ICON);
      break;
    }

    case ID_OPTIONS_SMALLICONVIEW:
    {
      dwStyle = GetWindowLong(hwndList, GWL_STYLE);
  
      if((dwStyle & LVS_TYPEMASK) != LVS_SMALLICON)
        SetWindowLong(hwndList, GWL_STYLE, 
          (dwStyle & ~LVS_TYPEMASK) | LVS_SMALLICON);
      break;
    }
  	
    case ID_OPTIONS_LISTVIEW:
    {
      dwStyle = GetWindowLong(hwndList, GWL_STYLE);
  
      if((dwStyle & LVS_TYPEMASK) != LVS_LIST)
        SetWindowLong(hwndList, GWL_STYLE, 
          (dwStyle & ~LVS_TYPEMASK) | LVS_LIST);
      break;
    }
  	
    case ID_OPTIONS_REPORTVIEW:
    {
      dwStyle = GetWindowLong(hwndList, GWL_STYLE);
  
      if((dwStyle & LVS_TYPEMASK) != LVS_REPORT)
        SetWindowLong(hwndList, GWL_STYLE, 
          (dwStyle & ~LVS_TYPEMASK) | LVS_REPORT);
      break;
    }

    case ID_FILE_EXIT:
      PostQuitMessage(0);
      return 0L;
      break;
	  
    case ID_HELP_ABOUT:
      break;

    default:
      break;
  }
  return FORWARD_WM_COMMAND(hWnd, id, hwndCtl, codeNotify,
    DefWindowProc);
}

// -----------------------------------------------------
// Функция WndProc_OnNotify
// -----------------------------------------------------
LRESULT WndProc_OnNotify(HWND hWnd, int idFrom, NMHDR* pnmhdr)
{
  LV_DISPINFO * lpLvdi = (LV_DISPINFO *)pnmhdr;
  APPLINFO * lpAppinfo = (APPLINFO *)(lpLvdi->item.lParam);
  static char szBuf[20];
  NM_LISTVIEW *lpNm = (NM_LISTVIEW *)pnmhdr;

  if(idFrom != IDC_LISTVIEW)
    return 0L;

  switch(pnmhdr->code)
  {
    case LVN_GETDISPINFO:
    {
      if(lpLvdi->item.mask & LVIF_TEXT)
      {
        switch(lpLvdi->item.iSubItem)
        {
          case 0:
            lpLvdi->item.pszText = lpAppinfo->szAppName;
            break;

          case 1:
            lpLvdi->item.pszText = lpAppinfo->szIconName;
            break;

          case 2:
            itoa(lpAppinfo->iCost, szBuf, 10);
            lpLvdi->item.pszText = szBuf;
            break;

          default:
            break;
        }
        break;
      }
    }

    case LVN_COLUMNCLICK:
    {
      ListView_SortItems(lpNm->hdr.hwndFrom, 
        LVCompareProc, (LPARAM)(lpNm->iSubItem));
      return 0L;
      break;
    }

    case LVN_BEGINLABELEDIT:
    {
      return 0L;
      break;
    }

    case LVN_ENDLABELEDIT:
    {
      if((lpLvdi->item.iItem != -1) &&
         (lpLvdi->item.pszText != NULL))
         lstrcpy(lpAppinfo->szAppName, lpLvdi->item.pszText);
      return 0L;
      break;
    }

    case NM_DBLCLK:
    {
      int index;
      LV_ITEM lvi;
      char szBuf[256];

      strcpy(szBuf, "Selected item:\n");

      // Определяем номер выделенного элемента
      index = ListView_GetNextItem(hwndList,
        -1, LVNI_ALL | LVNI_SELECTED);

      if(index == -1)
        return 0;

      // Подготавливаем структуру типа LV_ITEM
      // для получения текстовой информации об элементах
      memset(&lvi, 0, sizeof(lvi));
      lvi.mask = LVIF_TEXT;

      // Получаем название элемента
      lvi.iItem = index;
      lvi.iSubItem = 0;
      ListView_GetItem(hwndList, &lvi);
      strcat(szBuf, lvi.pszText);

      // Получаем текстовую строку, связанную
      // с первым и вторым дополнительным элементом
      lvi.iItem = index;
      lvi.iSubItem = 1;
      ListView_GetItem(hwndList, &lvi);
      strcat(szBuf, " : ");
      strcat(szBuf, lvi.pszText);

      lvi.iItem = index;
      lvi.iSubItem = 2;
      ListView_GetItem(hwndList, &lvi);
      strcat(szBuf, " : $");
      strcat(szBuf, lvi.pszText);

      // Выводим на экран текстовые строки
      // для выбранного элемента
      MessageBox(hWnd, szBuf, szAppName, MB_OK);
      return 0L;
      break;
    }
  }
  return 0L;
}

// -----------------------------------------------------
// Функция WndProc_OnSize       
// -----------------------------------------------------
#pragma warning(disable: 4098)
void WndProc_OnSize(HWND hwnd, UINT state, int cx, int cy)
{
  MoveWindow(hwndList, 0, 0, cx, cy, TRUE);
  return FORWARD_WM_SIZE(hwnd, state, cx, cy, DefWindowProc);
}

// -----------------------------------------------------
// Функция LVCompareProc      
// -----------------------------------------------------
int CALLBACK 
LVCompareProc(LPARAM lParam1, LPARAM lParam2, 
  LPARAM lParamSort)
{
  APPLINFO *pAppInfo1 = (APPLINFO *)lParam1;
  APPLINFO *pAppInfo2 = (APPLINFO *)lParam2;
  LPSTR lpStr1, lpStr2;
  int iResult;

  if(pAppInfo1 && pAppInfo2)
  {
    switch(lParamSort)
    {
      case 0: 
        lpStr1 = pAppInfo1->szAppName;
        lpStr2 = pAppInfo2->szAppName;
        iResult = strcmpi(lpStr1, lpStr2);
         break;

      case 1:  
        lpStr1 = pAppInfo1->szIconName;
        lpStr2 = pAppInfo2->szIconName;
        iResult = lstrcmpi(lpStr1, lpStr2);
        break;

      case 2:  
        iResult = pAppInfo1->iCost - pAppInfo2->iCost;
        break;

      default:
        iResult = 0;
        break;
    }
  }
  return(iResult);
}

Файл list.h (листинг 3.2) содержит описание функций и определение константы IDC_LISTVIEW (идентификатора органа управления List View).

Листинг 3.2. Файл list\list.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);
LRESULT WndProc_OnNotify(HWND hWnd, int idFrom, 
  NMHDR FAR * pnmhdr);
void WndProc_OnSize(HWND hwnd, UINT state, int cx, int cy);
void WndProc_OnDrawItem(HWND hwnd, 
  const DRAWITEMSTRUCT * lpDrawItem);
int CALLBACK 
LVCompareProc(LPARAM lParam1, LPARAM lParam2, 
  LPARAM lParamSort);
#define IDC_LISTVIEW 1234

Файл описания ресурсов приложения, созданный для нашего проекта автоматически системой разработки Microsoft Visual C++, приведен в листинге 3.3. В нем определено главное меню приложения, пиктограммы, из которых формируются списки изображений для органа управления List View и таблица строк описания меню (в нашем приложении не используется, однако вы можете найти для нее применение, добавив орган управления Statusbar).

Листинг 3.3. Файл list\list.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 "E&xit",                       ID_FILE_EXIT
    END
    POPUP "&Options"
    BEGIN
      MENUITEM "&Icon view",        ID_OPTIONS_ICONVIEW
      MENUITEM "&Small icon view",  ID_OPTIONS_SMALLICONVIEW
      MENUITEM "&List view",        ID_OPTIONS_LISTVIEW
      MENUITEM "&Report view",      ID_OPTIONS_REPORTVIEW
    END
    POPUP "&Help"
    BEGIN
        MENUITEM "&About List Application...",  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     "list.ico"
IDI_APPICONSM           ICON    DISCARDABLE     "listsm.ico"
IDI_ICON1               ICON    DISCARDABLE     "appicon.ico"
IDI_ICON2               ICON    DISCARDABLE     "book1.ico"
IDI_ICON3               ICON    DISCARDABLE     "drvlist.ico"
IDI_ICON4               ICON    DISCARDABLE     "mcicdpl.ico"
IDI_ICON5               ICON    DISCARDABLE     "mcistrwv.ico"
IDI_ICON6               ICON    DISCARDABLE     "mciwaver.ico"
IDI_ICON7               ICON    DISCARDABLE     "mciwnd.ico"
IDI_ICON8               ICON    DISCARDABLE     "sndplay.ico"
IDI_ICON9               ICON    DISCARDABLE     "wave.ico"

//////////////////////////////////////////////////////////////
// String Table
//
STRINGTABLE DISCARDABLE 
BEGIN
    ID_FILE_EXIT            "Quits the application"
    ID_HELP_ABOUTLISTAPPLICATION 
          "Displays program information and copyright"
    ID_OPTIONS_ICONVIEW     "Each item appears as a full-sized icon"
    ID_OPTIONS_SMALLICONVIEW "Each item appears as a small icon"
    ID_OPTIONS_LISTVIEW     "Each item appears as a small icon arranged in columns"
    ID_OPTIONS_REPORTVIEW   "Each item appears with subitems arranged in columns"
END

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

Файл resource.h (листинг 3.4) также создается автоматически. В нем находятся определения констант для ресурсов приложения.

Листинг 3.4. Файл list\resource.h


//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by list.rc
//
#define IDR_APPMENU                     102
#define IDI_APPICON                     103
#define IDI_APPICONSM                   104
#define IDI_ICON1                       105
#define IDI_ICON2                       106
#define IDI_ICON3                       107
#define IDI_ICON4                       108
#define IDI_ICON5                       109
#define IDI_ICON6                       110
#define IDI_ICON7                       111
#define IDI_ICON8                       112
#define IDI_ICON9                       113
#define ID_FILE_EXIT                    40001
#define ID_HELP_ABOUTLISTAPPLICATION    40002
#define ID_HELP_ABOUT                   40003
#define ID_OPTIONS_ICONVIEW             40004
#define ID_OPTIONS_SMALLICONVIEW        40005
#define ID_OPTIONS_LISTVIEW             40006
#define ID_OPTIONS_REPORTVIEW           40007

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        115
#define _APS_NEXT_COMMAND_VALUE         40008
#define _APS_NEXT_CONTROL_VALUE         1000
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

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

Займемся описанием функций приложения List View. Так как раньше мы уже приводили отдельные фрагменты этих функций, ограничимся кратким описанием.

Глобальные переменные

Массив структур rgApplInfo предназначен для хранения элементов списка. Соответствующая структура имеет тип APPLINFO и определена следующим образом:

typedef struct tagAPPLINFO
{
  char szAppName[40];   // название приложения
  char szIconName[20];  // имя файла пиктограммы
  UINT iCost;           // стоимость приложения
} APPLINFO;

В переменной hInst хранится идентификатор приложения, полученный функцией WinMain. Строчные массивы szAppName и szAppTitle хранят, соответственно, имя и заголовок приложения.

Переменная hwndList нужна для хранения идентификатора созданного органа управления List View.

WinMain

Функция WinMain сохраняет идентификатор приложения и проверяет, не было ли это приложение запущено ранее. Если было, то активизируется окно работающего приложения.

Далее функция регистрирует класс главного окна приложения, создает и отображает это окно, а затем запускает обычный цикл обработки сообщений.

WndProc

В задачу функции WndProc входит обработка следующих сообщений: WM_CREATE, WM_DESTROY, WM_COMMAND, WM_NOTIFY, WM_SIZE. Обработка выполняется с использованием макрокоманды HANDLE_MSG.

WndProc_OnCreate

Эта функция обрабатывает сообщение WM_CREATE, создавая и инициализируя орган управления List View. Размеры окна органа управления устанавливаются равными размерам внутренней области главного окна приложения и в дальнейшем изменяются соответствующим образом обработчиком сообщения WM_SIZE.

WndProc_OnDestroy

Функция WndProc_OnDestroy вызывается, когда пользователь завершает работу приложения. Она уничтожает окно органа управления List View и останавливает цикл обработки сообщений, вызывая функцию PostQuitMessage.

WndProc_OnCommand

Эта функция обрабатывает сообщение WM-COMMAND, поступающее от главного меню приложения. Строки временного меню Options (Icon view, Small icon view, List view и Report view) имеют идентификаторы, соответственно, ID_OPTIONS_ICONVIEW, ID_OPTIONS_SMALLICONVIEW, ID_OPTIONS_LISTVIEW и ID_OPTIONS_REPORTVIEW. Обработчики изменяют режим отображения списка с помощью функций GetWindowLong и SetWindowLong, как это было описано раньше.

WndProc_OnNotify

Функция WndProc_OnNotify обрабатывает сообщение WM_NOTIFY, поступающее от органа управления List View.

Процедура обработки извещений была описана ранее. Отметим только, что из-за того что различные извещения используют разный формат структуры данных, адрес которой передается через параметр lParam сообщения WM_NOTIFY, мы выполняем преобразование указателя NMHDR* pnmhdr к типам LV_DISPINFO и NM_LISTVIEW.

Кроме того, функция WndProc_OnNotify проверяет параметр idFrom чтобы убедиться в том, что извещение пришло именно от органа управления List View с идентификатором IDC_LISTVIEW.

WndProc_OnSize

Для того чтобы размеры органа управления List View всегда соответствовали размерам внутренней области главного окна приложения List Application, обработчик сообщения WM_SIZE, расположенный в функции WndProc_OnSize, изменяет размеры окна органа управления. Изменения выполняются функцией WndProc_OnSize.

LVCompareProc

Функция LVCompareProc нужна для сортировки элементов списка. Она выполняет сравнение двух элементов списка. Через первые два параметра передаются адреса структур данных, соответствующих сравниваемым элементам. Последний параметр содержит номер дополнительного элемента или нуль, если сравниваются названия элементов.

Текстовые строки сравниваются при помощи функции strcmpi. Для сравнения численных значений мы использовали обычную операцию вычитания.

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


Создание интернет-магазинов: http://www.shop2you.ru/ © Александр Фролов, Григорий Фролов, 1991-2016