Все эти действия можно объединить в
группу и проверить одновременно. Для этого достаточно составить один сценарий,
в котором будут следующие действия:
a) в поле “название трека” диалога вписать название “Трек X” (вместо “X” в первой итерации записать “1”);
e) должна произойти проверка введенной информации на допустимость
введенных значений, добавление данных и вывестись отчет “Данные добавлены”,
изображенный на рисунке 15 (диалог не должен закрыться т.к. он предполагает
множественное добавление информации);
3) выполнить многократное выполнение пунктов a, b, c и d с получение
результата из пункта e в количестве четырех итераций с
начальным значением 2, в качестве данных брать те же значения изменяя “X” на номер итерации.
В результате всех действий получим
пример, изображенный на рисунке 7.
Проделав значительную работу я изучил
возможности работы с winapi (и в частности способы
манипулирования данными в элементах управления). Изучил механизмы создания
пользовательских классов и принципы наследования в языке C++.
|
#include
"includes.h"
#include "main.h"
#define WX 600
#define WY 300
#define COLOR
RGB(0xff,0xff,0xff)
#define WIN_STYLE
WS_OVERLAPPED|WS_SYSMENU|WS_CAPTION|WS_BORDER|WS_MINIMIZEBOX
#define Error_title
"Error"
#define AplicationTitle
"Картотека дисков"
#define ClassName
"MY_CLASS"
HINSTANCE ghInst;
/*
############################### */
/* ### ВСПОМОГАТЕЛЬНЫЕ
ФУНКЦИИ ### */
/*
############################### */
char buf[10]; char*
toString(int value,int radix=10){
itoa(value,buf,radix);
return
buf;};
/*
######################################### */
/* ### ДИАЛОГИ -
ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ### */
/*
######################################### */
bool getFileDlg(HWND
hWnd,char *name,char *mask,int mask_size=0){
char
szF[1024]="";
OPENFILENAME
ofn;
memset(&ofn,0,sizeof(OPENFILENAME));
ofn.lStructSize=sizeof(OPENFILENAME);
ofn.hwndOwner=hWnd;
ofn.lpstrFile=szF;
ofn.nMaxFile=sizeof(szF);
ofn.lpstrFilter=mask;
ofn.nFilterIndex=2;
ofn.lpstrFileTitle=NULL;
ofn.nMaxFileTitle=0;
ofn.lpstrInitialDir=NULL;
ofn.Flags=OFN_FILEMUSTEXIST;
if(GetOpenFileName(&ofn)==TRUE){
sprintf(name,"%s",ofn.lpstrFile);
return
1;}
sprintf(name,"%s","");
return 0;}
/*
##################################### */
/* ### ДИАЛОГИ - ОБРАБОТКА
СООБЩЕНИЙ ### */
/*
##################################### */
LRESULT CALLBACK
addTrackDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
int
id=LOWORD(wParam);
static int
ind=lParam,pos=0;
int i;
switch
(uMsg)
{
case
WM_INITDIALOG:
ind=lParam;
for
(i=0;i<dwWkCount;i++)
if
(WkRec[i].ind==ind)
pos
= i;
SetDlgItemText(hwndDlg,IDC_EDIT_TRACK,WkRec[pos].cTrack);
SetDlgItemText(hwndDlg,IDC_EDIT_SINGER,WkRec[pos].cSinger);
SetDlgItemText(hwndDlg,IDC_EDIT_DATE,WkRec[pos].cDate);
return
FALSE;
break;
case
WM_COMMAND:
switch
(id)
{
case
IDC_OK:
GetDlgItemText(hwndDlg,IDC_EDIT_TRACK,WkRec[pos].cTrack,100);
GetDlgItemText(hwndDlg,IDC_EDIT_SINGER,WkRec[pos].cSinger,30);
GetDlgItemText(hwndDlg,IDC_EDIT_DATE,WkRec[pos].cDate,20);
EndDialog(hwndDlg,0);
break;
case
IDC_CANCEL:
EndDialog(hwndDlg,1);
break;
}
break;
default:
return
FALSE;
}
}
int GetMaxInd()
{
int
maxind=0;
for (int
i=0;i<dwWkCount;i++)
{
if
(WkRec[i].iNum>maxind)
{
maxind=WkRec[i].iNum;
}
}
return
maxind;
}
LRESULT CALLBACK
addDiskDlgProc(HWND hwndDlg,UINT uMsg,
WPARAM
wParam,LPARAM lParam)
{
int
id=LOWORD(wParam);
static int
ind=lParam,pos=0;
int i;
switch
(uMsg)
{
case
WM_INITDIALOG:
ind=lParam;
for
(i=0;i<dwWkCount;i++)
if
(WkRec[i].ind==ind)
pos
= i;
SetDlgItemText(hwndDlg,IDC_EDIT_GROUP,WkRec[pos].cGroup);
SetDlgItemText(hwndDlg,IDC_EDIT_ALBUM,WkRec[pos].cDisc);
return
FALSE;
break;
case
WM_COMMAND:
switch
(id)
{
case
IDC_OK:
GetDlgItemText(hwndDlg,IDC_EDIT_GROUP,WkRec[pos].cGroup,50);
GetDlgItemText(hwndDlg,IDC_EDIT_ALBUM,WkRec[pos].cDisc,30);
WkRec[pos].iNum=GetMaxInd()+1;
EndDialog(hwndDlg,0);
break;
case
IDC_CANCEL:
EndDialog(hwndDlg,1);
break;
}
break;
default:
return
FALSE;
}
}
LRESULT CALLBACK
AboutDlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case
WM_INITDIALOG: {return TRUE;};
case
WM_COMMAND:
switch(LOWORD(wParam)){
case
IDOK:{
EndDialog(hDlg,0);
return
TRUE;}}
break;
default:
return(FALSE);
}
return(TRUE);
}
UINT AddNewItem(UINT
iType,UINT iParent)
{
//Создаем
временную рабочую структуру
WorkRecord
*temp;
temp=new
WorkRecord[dwWkCount];
UINT
max=WkRec[0].ind;
//Копируем
во временную структуру рабочую. Находим последний индекс
// в
рабочей структуре
for (int
i=0;i<dwWkCount;i++)
{
if
(max<WkRec[i].ind)
max=WkRec[i].ind;
temp[i]=WkRec[i];
}
//
Пересоздаем рабочую структуру с новым размером
delete []
WkRec;
WkRec=new
WorkRecord[++dwWkCount];
//Копируем
записи из временной структуры в рабочую
for
(i=0;i<dwWkCount-1;i++)
{
//ZeroMemory(&WkRec[i],sizeof(WorkRecord));
WkRec[i]=temp[i];
}
// Очищаем
последний "новый" элемент рабочей
//
структуры и заносит значения по умолчанию
ZeroMemory(&WkRec[dwWkCount-1],sizeof(WorkRecord));
WkRec[dwWkCount-1].ind=++max;
WkRec[dwWkCount-1].iType=iType;
WkRec[dwWkCount-1].indParent=iParent;
delete
[]temp;
return max;
}
BOOL DeleteRec(int index)
{
//
Проверяем есть ли связанные записи
for (int
i=0;i<dwWkCount;i++)
if
(WkRec[i].indParent==index)
{
MessageBox(NULL,"Удалите
связанные данные","Ошибка",MB_OK);
return
FALSE;
}
// Ищем
позицию удаляемого элемента
int pos;
for
(i=0;i<dwWkCount;i++)
if
(WkRec[i].ind==index)
pos=index;
// Если
удаляемый элемент не последний,
//то
переносим последний на место удаляемого.
dwWkCount--;
if
(pos!=dwWkCount)
WkRec[pos]
= WkRec[dwWkCount];
// Копируем
записи во временную структуру
WorkRecord
*temp;
temp=new
WorkRecord[dwWkCount];
for (
i=0;i<dwWkCount;i++)
{
temp[i]=WkRec[i];
}
//Удаляет
рабочие записи
delete []
WkRec;
// Создает
новые рабочие записи
WkRec=new
WorkRecord[dwWkCount];
for
(i=0;i<dwWkCount;i++)
{
WkRec[i]=temp[i];
}
delete
[]temp;
return
TRUE;
}
void MakeTree()
{
TV_DeleteAll();
WkRec[0].ind=0;
WkRec[0].indParent=0;
WkRec[0].iType=5;
WkRec[0].hTree=
TV_InsertItem("Коллекция", HANDLES.hWndTreeView, TVI_ROOT, 0,0);
HTREEITEM
parent=WkRec->hTree;
//
Инициализация дисков
for (int
i=1;i<dwWkCount;i++)
{
if
(WkRec[i].iType==0)
WkRec[i].hTree=TV_InsertItem(WkRec[i].cDisc,
HANDLES.hWndTreeView,parent,1,WkRec[i].ind);
if
(WkRec[i].iType==1)
for
(int j=1;j<dwWkCount;j++)
if
(WkRec[i].indParent==WkRec[j].ind)
WkRec[i].hTree=TV_InsertItem(WkRec[i].cTrack,
HANDLES.hWndTreeView,WkRec[j].hTree,2,WkRec[i].ind);
}
LV_RemoveAllItems(HANDLES.hWndListView);
}
// Инициализация списка при
выборе нового элемента
void MakeList(UINT selDisk)
{
LV_RemoveAllItems(HANDLES.hWndListView);
for (int
i=0;i<dwWkCount;i++)
{
if
(WkRec[i].indParent==selDisk)
LV_AddItem(HANDLES.hWndListView,
0, WkRec[i].cTrack,&WkRec[i]);
}
}
void InitTree()
{
TV_DeleteAll();
lstrcpy(FileName,
"");
dwWkCount=1;
delete
[]WkRec;
WkRec=new
WorkRecord[dwWkCount];
ZeroMemory(WkRec,sizeof(WorkRecord));
HANDLES.iSelDisk=-1;
HANDLES.iSelTrack=-1;
MakeTree();
}
/* #######################################
*/
bool WndProc_OnCreate(HWND
hWnd,LPCREATESTRUCT lpCreateStruct)
{
HANDLES.hWndMain=hWnd;
if
(!SB_Create(hWnd))
return
FALSE;
if
(!TB_Create(hWnd))
return
FALSE;
if
(!LV_Create(hWnd))
return
FALSE;
if
(!TV_Create(hWnd))
return
FALSE;
InitTree();
ResizeWindows(hWnd);
return
TRUE;
return 1;
}
void WndProc_OnResize(HWND
hWnd,int cx, int cy, int cz)
{
if
(!ResizeWindows(hWnd))
MessageBox(NULL, "Window resizing failed!", NULL, MB_OK);
}
void WndProc_OnDestroy(HWND
hWnd)
{
PostQuitMessage(0);
}
void Main_OnCommand( HWND
hWnd, int iCmd, HWND hwndCtl, UINT uCode )
{
int
wCommand = iCmd;
int
iTypeEdit,iNumRec;
GetStateOfCommonControls();
switch(iCmd)
{
case
IDM_FILE_NEW:
iTypeEdit=MessageBox(NULL,"Вы
хотите сохранить изменения?",
"Предупреждение",MB_YESNO);
if
(iTypeEdit==IDYES)
{
if
(strlen(FileName)==0)
{
if
(!GetFlNameDialog(HANDLES.hWndMain,1))
break;
else
{
if
(!SaveItems(FileName))
MessageBox(NULL,"Ошибка
сохранения файла.","Ошибка",MB_OK);
else
InitTree();
}
}
else
{
if
(!SaveItems(FileName))
MessageBox(NULL,"Ошибка
сохранения файла.","Ошибка",MB_OK);
else
InitTree();
}
}
else
{
InitTree();
}
break;
case
IDM_FILE_OPEN:
if
(GetFlNameDialog(HANDLES.hWndMain,0))
{
if
(!LoadItems(FileName))
MessageBox(NULL,"Ошибка
загрузки файла.","Ошибка",MB_OK);
else
MakeTree();
}
else
MessageBox(NULL,"Файл
не выбран.","Ошибка",MB_OK);
break;
case
IDM_FILE_SAVEAS:
if
(!GetFlNameDialog(HANDLES.hWndMain,1))
{
MessageBox(NULL,"Файл
не выбран.","Ошибка",MB_OK);
}
else
if
(!SaveItems(FileName))
MessageBox(NULL,"Ошибка
сохранения файла.","Ошибка",MB_OK);
break;
case
IDM_FILE_SAVE:
if
(strlen(FileName)==0)
{
if
(!GetFlNameDialog(HANDLES.hWndMain,1))
{
break;
// MessageBox(NULL,"Файл
не выбран.","Ошибка",MB_OK);
}
else
if
(!SaveItems(FileName))
MessageBox(NULL,"Ошибка
сохранения файла.","Ошибка",MB_OK);
break;
case
IDM_EDIT_ADD:
if
(HANDLES.iSelDisk<0)
{
iNumRec=AddNewItem(0,0);
iTypeEdit=DialogBoxParam(ghInst,MAKEINTRESOURCE(IDD_DIALOG_ADD_DISK),
hWnd,(DLGPROC)addDiskDlgProc,
(LPARAM)
iNumRec);
if
(iTypeEdit)
DeleteRec(iNumRec);
}
else
{
iNumRec=AddNewItem(1,HANDLES.iSelDisk);
iTypeEdit=DialogBoxParam(ghInst,MAKEINTRESOURCE(IDD_DIALOG_ADD_TRACK),
hWnd,(DLGPROC)addTrackDlgProc,(LPARAM)
iNumRec);
if
(iTypeEdit)
DeleteRec(iNumRec);
}
MakeTree();
break;
case
IDM_EDIT_CHANGE:
if
(HANDLES.iSelTrack>=0)
{
DialogBoxParam(ghInst,MAKEINTRESOURCE(IDD_DIALOG_ADD_TRACK),
hWnd,(DLGPROC)addTrackDlgProc,(LPARAM)
HANDLES.iSelTrack);
MakeTree();
break;
}
if
(HANDLES.iSelDisk>=0)
{
DialogBoxParam(ghInst,MAKEINTRESOURCE(IDD_DIALOG_ADD_DISK),
hWnd,(DLGPROC)addDiskDlgProc,
(LPARAM)
HANDLES.iSelDisk);
MakeTree();
}
break;
case
IDM_EDIT_DELETE:
if
(HANDLES.iSelTrack>=0)
{
DeleteRec(HANDLES.iSelTrack);
MakeTree();
break;
}
if
(HANDLES.iSelDisk>=0)
{
DeleteRec(HANDLES.iSelDisk);
MakeTree();
}
break;
case
IDM_PROPERTY:
if
(HANDLES.iSelTrack>=0)
CreatePropertySheet(hWnd,1);
break;
case
IDM_VIEW_BIG:
case
IDM_VIEW_SMALL:
case
IDM_VIEW_LIST:
case
IDM_VIEW_TABLE:
LV_ChangeView(wCommand);
break;
case
IDM_HELP_ABOUT:
DialogBox(ghInst,MAKEINTRESOURCE(IDD_DIALOG_HELP_ABOUT),hWnd,(DLGPROC)AboutDlgProc);
break;
case
IDM_FILE_EXIT:
SendMessage(hWnd,WM_DESTROY,0,0);
break;
default:
break;
}
}
void WndProc_OnMenu(HWND
hwnd, HWND hwndCtl, UINT xPos, UINT yPos)
{
HMENU
hMenu,hMenuTrackPopup ;
if
(hwndCtl == HANDLES.hWndListView)
{
// Get
the context menu from the resource file.
hMenu
= LoadMenu(HANDLES.hInst, MAKEINTRESOURCE(IDR_TRACKPOPUP));
//
Get the first item in the menu for TrackPopupMenu().
hMenuTrackPopup
= GetSubMenu(hMenu, 0);
//
Draw and track the "floating" menu.
TrackPopupMenu(hMenuTrackPopup,
TPM_LEFTALIGN
| TPM_RIGHTBUTTON,
xPos,
yPos,
0,
HANDLES.hWndMain, NULL);
//
Destroy the menu
DestroyMenu(hMenu);
}
}
LRESULT WINAPI CALLBACK
WndProc(HWND hWnd, UINT msg, WPARAM wParam,
LPARAM
lParam)
{
switch(msg)
{
HANDLE_MSG(hWnd,
WM_CONTEXTMENU, WndProc_OnMenu );
HANDLE_MSG(hWnd,WM_CREATE,WndProc_OnCreate);
HANDLE_MSG(hWnd,WM_DESTROY,WndProc_OnDestroy);
HANDLE_MSG(hWnd,
WM_SIZE, WndProc_OnResize);
HANDLE_MSG(hWnd,
WM_COMMAND, Main_OnCommand );
case
WM_NOTIFY:
if
(TV_NotifyHandler(hWnd, msg, wParam, lParam))
{
break;
}
if
(TT_NotifyHandler(hWnd, msg, wParam, lParam))
{
break;
}
if
(LV_NotifyHandler(hWnd, msg, wParam, lParam))
{
break;
}
default:
return(DefWindowProc(hWnd,msg,wParam,lParam));
}
return 0;}
ATOM
RegisterAppClass(HINSTANCE hInstance)
{
WNDCLASSEX
wcex;
wcex.cbSize=sizeof(WNDCLASSEX);
wcex.style=CS_HREDRAW|CS_VREDRAW;
wcex.lpfnWndProc=(WNDPROC)WndProc;
wcex.cbClsExtra=0;
wcex.cbWndExtra=0;
wcex.hInstance=hInstance;
wcex.hIcon=LoadIcon(hInstance,(LPCTSTR)IDI_ICON_APP);
wcex.hIconSm=LoadIcon(hInstance,(LPCTSTR)IDI_ICON_APP);
wcex.hCursor=NULL;
wcex.hbrBackground=CreateSolidBrush(COLOR);
wcex.lpszMenuName=MAKEINTRESOURCE(IDM_MENU_MAIN);
wcex.lpszClassName=ClassName;
return
RegisterClassEx(&wcex);
}
BOOL
InitInstanceWindow(HINSTANCE hInstance,int nCmdShow)
{
HWND
hWnd=CreateWindow(ClassName,AplicationTitle,
WS_OVERLAPPEDWINDOW
| WS_MAXIMIZE,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,
hInstance,NULL);
if(!hWnd)
return 0;
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
return 1;
};
int WINAPI
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR
lpCmdLine,int nCmdShow)
{
HANDLES.hInst=hInstance;
InitCommonControls();
if(!RegisterAppClass(hInstance))
{
MessageBox(NULL,"Ошибка
регистрации класса окна!!!",
Error_title,MB_OK|MB_ICONERROR);
return
0;
}
if(!InitInstanceWindow(hInstance,nCmdShow))
{
MessageBox(NULL,"Ошибка
создания окна!!!",
Error_title,MB_OK|MB_ICONERROR);
return
0;
}
HWND
hwndDlg=(HWND)0;
MSG msg;
while(GetMessage(&msg,NULL,0,0)){
if(!IsDialogMessage(PropHandle,&msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);}}
return
msg.wParam;
}