Проектирование программы Текстовый Редактор Блокнот
Ознакомление с историей изобретение языка программирования C. Рассмотрение компонентов программы Блокнот. Проектирование основных кнопок окна, строки заголовка, меню верхнего уровня, панели инструментов для меню второго уровня и статусной панели.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 19.07.2014 |
Размер файла | 198,0 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Введение
программа блокнот панель меню
Язык C был изобретён и реализован Дэнисом Ритчи в операционной системе Unix. Этот язык был разработан на основе более старого языка BCPL, созданного в своё время Мартином Ричардсом. В свою очередь развитие языка B привело к созданию в 1970 году языка C. Стандарт ANSI был окончательно принят в декабре 1989 года и впервые опубликован в начале 1990 года. Этот стандарт был окончательно принят организацией ISO.
Любая программа на C состоит из одной или нескольких функций. Функции в C служат для реализации отдельных исполнителей. Обязательно должна быть определена единственная главная функция main, именно с неё начинается выполнение программы. Именно она выполняет всю работу, обращаясь при необходимости к другим функциям. Язык Си разрабатывался как замена или дополнение языка Assembler` а для задач системного программирования. На этом языке была написана первая мультиплатформенная ОС UNIX.
1. Необходимое программное обеспечение
В качестве программного обеспечения используется студия Microsoft Visual C++ 6.0, стандартная виндоузовская программа Paint, а также программа Help&Manual для создания файла справки.
2. Основные файлы, используемые в проекте
Pr5.cpp - основной файл программы;
Pr5.res - файл ресурсов;
Resource.h - заголовочный файл ресурсов;
Toolbar.bmp - графический файл, изображающий панель для меню второго уровня;
Pr5.hlp - файл справки о программе.
3. Проектирование программы
Сначала программа Текстовый Редактор Блокнот проектируется на листе бумаги.
Первый этап проектирования программы. Нужно продумать, из каких компонентов будет состоять программа. Окно должно иметь три основные кнопки и иметь возможность изменяться в размере. Также основными компонентами окна должны быть: строка заголовка, меню верхнего уровня, панель инструментов для меню второго уровня и статусная панель.
Рисунок 1.
Чтобы создать меню верхнего уровня, нужно его тоже спроектировать на листе бумаги и тщательно продумать, какой пункт меню какие подпункты должен содержать и нарисовать схему меню. Пункт с названием "О программе" тоже должен быть но для простоты его действие не прописывается.
Второй этап проектирования программы. Нужно продумать и нарисовать программу со всеми составляющими её компонентами, включая меню второго уровня с пиктограммами (Сохранить, открыть и печать), статусную панель и саму рабочую область, в качестве которой используется элемент richedit. Макет этой программы приведён на рисунке 3.
Рисунок 2.
Рисунок 3.
В первую очередь программно создаётся само окно. Для этого нужно подключить библиотеку windows.h и объявить главную функцию программы WinMain() а также оконную функцию WndProc(). Эта функция также называется оконной процедурой. Она связана с циклом обработки сообщений через обратный вызов CALLBACK. Любая программа начинается писаться с функции WinMain, то есть с основной функции программы под Microsoft Windows. Для более простых компиляторов она имеет структуру WINAPI. Функция начинается с объявления структуры типа класса WNDCLASS, создания переменной w и её инициализации. Затем для более подробного описания окна через эту переменную нужное число раз вызываются поля (методы класса) и этим методам присваиваются нужные значения. После описания окна через функцию ветвления происходит регистрация окна с возвращением значения 1, а иначе - 0. Затем после инициализации нужно функцией CreateWindow создавать как само окно, так и все дочерние окна. Функция CreateWindow имеет такие параметры как класс окна, заголовок окна, константы для подробного описания окна через логический оператор ИЛИ, координаты окна по осям x и y относительно точки находящейся в верхнем углу слева, размеры окна (длину и ширину), взаимосвязи с дочерними окнами, если они имеются и главный дескриптор окна hInstance а также редко используемые параметры.
Затем нужно отобразить окно при помощи функции ShowWindow и по необходимости его обновить (функция UpdateWindow), но для этого нужно осуществить проверку через функцию ветвления if(), создано ли окно. Если окно не создано, то функция возвращает нулевое значение. После отображения окна в программе идёт главный цикл обработки сообщений (MessageLoop). В этом цикле содержится функция GetMessage, которая считывает сообщение, в pамках диапазона фильтpации, из очеpеди сообщений пpикладной задачи и оставляет упpавление дpугим пpикладным задачам, если сообщений нет или если следующим сообщением является WM_PAINT или WM_TIMER. Она имеет параметры: Msg: пpинимающая стpуктуpа TMsg, Wnd: Окно назначения сообщений или 0 для всех окон в пpикладной задаче. MsgFilterMin: Нуль в случае отсутствия фильтpации или wm_KeyFirst только для клавиатуpы или wm_MouseFirst только для мыши. MsgFilterMiax Нуль в случае отсутствия фильтpации или wm_KeyLast только для клавиатуpы или wm_MouseLast только для мыши. Также в основном цикле программы содержится функция TranslateMessage для перевода комбинаций сообщений и перенаправления их в очередь сообщений (громадный switch) и функция DispatchMessage для осуществления всех взаимосвязей между двумя основными функциями программы. Основная функция программы должна возвращать значение msg.wParam, то есть младшее слово Windows-сообщений. Затем идёт функция WndProc. Она при помощи функции обратного вызова CALLBACK взаимосвязана с циклом обработки сообщений и имеет структуру LRESULT. Основным содержимым этой функции является очередь сообщений. Метки case можно писать в любом порядке. Основными метками являются метки связанные с закрытием окна WM_CLOSE и WM_DESTROY. В метке default jgbcsdftncz любое сообщение, которое не обрабатывает оконная процедура. Оно отправляется на обработку в функцию DefWindowProc.
Далее создаётся меню верхнего уровня, то есть основное меню программы. Для наипростейшего создания этого меню в первую очередь нужно объявить константы в качестве глобальных констант, а также все глобальные переменные типа HMENU. Затем функцию CreatePopupMenu необходимо присвоить переменным самого меню, например hFileMenu. Далее в самой очереди сообщений прописывается сами элементы меню с помощью функции AppendMenu() через ветвление if. Также нужно присоединить меню к главной панели управления и к самому окну тоже при помощи функции AppendMenu(). Класс UNDO предназначен для пункта меню Отмена, он прописывается в качестве глобальной переменной. Этот класс называется стеком.
После создания меню верхнего уровня создаётся статусная панель. Для её создания объявляются переменные двух типов HWND и UINT и правильного закрепления, то есть чтобы она могла менять размеры в зависимости от изменения размеров окна как вручную, так и автоматически. Так же для создания этой панели нужно подключить библиотеку commctrl.h и написать функцию hStatusWindow типа HWND. Затем переменной hStatusWindow присваивается функция с названием CreateStatusWindow создающая эту панель и конструкция if:
hStatusWindow = CreateStatusWindow(WS_CHILD|WS_VISIBLE,"Блокнот Ярослава",hWnd, wld);
if(!hStatusWindow)
{
MessageBox(NULL,"Cannot create window","Error",MB_OK);
return 0;
}
На следующем этапе создаются акселераторы, то есть "горячие" клавиши. Для этого нужно создать переменные типа HACCEL и ACCEL, а также в цикле обработки прописать своего рода конструкцию, то есть if(!TranslateAccelerator(hWnd,hAccel,&Msg)), а также все функции для работы с акселераторами.
Для более полного описания функции работы с акселераторами используется следующая структура:
TBBUTTON buttons[3] =
{
{0,IDP_Save, TBSTATE_ENABLED,TBSTYLE_BUTTON, 0, NULL},
{1,IDP_Open, TBSTATE_ENABLED,TBSTYLE_BUTTON, 0, NULL},
{2,IDP_Print,TBSTATE_ENABLED,TBSTYLE_BUTTON, 0, NULL}
};
toolbar2=CreateToolbarEx(hWnd, WS_CHILD|WS_VISIBLE|TBSTYLE_TOOLTIPS,
103, 3, hInstance, IDB_BITMAP1, buttons, 3, 22, 22, 20, 20, sizeof(TBBUTTON));
Далее нужно к меню верхнего уровня присоединить меню второго уровня. Для этого нужно панель управления для данного меню прорисовать в программе PAINT и создать файл с названием toolbar.bmp.
Она присоединяется при помощи специального файла ресурсов "resource.h", структуры MAKEINRESOURE и других функций. Также она описывается следующей структурой:
INITCOMMONCONTROLSEX icx;
icx.dwICC = ICC_BAR_CLASSES;
icx.dwSize = sizeof(icx);
InitCommonControlsEx(&icx);
if(!toolbar2)
{
MessageBox(NULL,"Cannot create toolbar window","Error",MB_OK);
return 0;
}
Самым важным этапом в проектировании программы является создание основного элемента управления, то есть самого текстового поля. Для этого необходимо подключить библиотеку richedit.h а также подключить специальную lib-библиотеку. В шестой студии она называется Msftedit.dll. Также нужна константа с названием _RICHEDIT_VER 0x0200. Она объявляется через ключевое слово #define. Окно для редактирования считается дочерним окном для программы и создаётся при помощи функции, но с названием CreateWindowExW и присваивается переменной edit.
edit = CreateWindowExW (WS_EX_CLIENTEDGE, L"RICHEDIT50W",
L"",WS_VISIBLE|WS_CHILD|ES_MULTILINE, 10, 10, 300, 300, hWnd, (HMENU)10,
hInstance, NULL);
…
if (!edit)
{
MessageBox (hWnd,"e","e",MB_OK);
return 0;
}
Затем нужно прописать само меню верхнего уровня в метках case. Оно прописывается в самой оконной процедуре, то есть в очереди сообщений. Чтобы прописать метку, имеющую название созданной константы, необходимо сначала создать метку с названием WM_COMMAND и в неё вставить отдельный switch с параметром LOWORD(wparam) и в нём прописывать метки-константы для меню верхнего уровня. Метка IDM_Enable_Disable переключает меню выход, метки case IDP_Open и IDP_Save предназначены для открытия и сохранения текстового файла, метка IDP_Print соответственно для распечатки документов. В меню "Правка" входят такие метки как: IDP_Undo, IDP_Cut, IDP_Copy, IDP_Paste и IDP_Find. В меню "Вставка" входят следующие метки: IDP_Datetime, IDP_Symbol, IDP_Alpha, IDP_Sigma=19 и IDP_Omega. В меню "Формат" входит метка IDP_Font, а в меню "Справка" - IDP_Help. Метка WM_Notifi используется в качестве вспомогательной метки для отмены действия а также она взаимосвязана с классом Undo.
4. Описание меню верхнего уровня
Для того, чтобы прописать все подпункты меню верхнего уровня, нужно в первую очередь создать конструкцию с меткой WM_COMMAND, имеющую вид:
…
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
// Все метки меню и подменю
… … …
}
}
…
Каждое меню или подменю описывается в своей метке case.
Меню Файл.
Это меню состоит из пунктов: Открыть, Сохранить, Печать, Включить/выключить выход, Выход.
Каждый подпункт меню описывается соответствующим классом, встроенным в саму библиотеку данного компилятора
case IDP_Open: {
//Открытие файла
char filename[300];
filename[0] = 0;
OPENFILENAME of;
of.lStructSize = sizeof(of);
of.hwndOwner = hWnd;
of.hInstance = hInst;
of.lpstrFilter = "texts files\0*.txt\0\0";
of.lpstrCustomFilter = NULL;
of.nMaxCustFilter = 0;
of.nFilterIndex = 1;
of.lpstrFile = filename;
of.nMaxFile = sizeof(filename);
of.lpstrFileTitle = NULL;
of.nMaxFileTitle = 0;
of.lpstrInitialDir = NULL;
of.lpstrTitle = "Открытие файла";
of.Flags = OFN_FILEMUSTEXIST;
of.lpstrDefExt = "bmp";
of.lCustData = 0;
of.lpfnHook = NULL;
of.lpTemplateName = NULL;
BOOL result=GetOpenFileName(&of);
if(!result)
{
MessageBox(hWnd,"Error","Ошибка",MB_OK);
break;
}
ifstream f;
f.open(filename);
f.seekg(0, f.end);
int size = f.tellg();
f.seekg(0, f.beg);
char * m = new char [size];
f.read(m, size);
SetWindowText(edit, m);
UpdateWindow(edit);
delete m;
}
break;
case IDP_Save:
Save();
break;
case IDP_Print:
{
PRINTDLG print_dlg = {0};
print_dlg.lStructSize = sizeof(print_dlg);
print_dlg.Flags = PD_RETURNDC;
BOOL result=PrintDlg(&print_dlg);
if(!result)
{
MessageBox(hWnd,"Print Error", "Не выдаёт печать", MB_OK);
break;
}
//Вывод тестового текста на принтер
HDC hdc = print_dlg.hDC;
DOCINFO di = { sizeof(di) };
di.lpszDocName = "qqq.txt";
//Подключение к RichEdit
StartDoc(hdc,&di);
SendMessage(edit,EM_SETTARGETDEVICE,(WPARAM)hdc,0);
StartPage(hdc);
SendMessage(edit,EM_SETSEL,0,-1); // Выделить всё
FORMATRANGE fr;
fr.hdc=hdc;
fr.hdcTarget = hdc;
fr.rcPage.left=0;
fr.rcPage.right=100;
fr.rcPage.top = 0;
fr.rcPage.bottom = 100;
SendMessage(edit,EM_EXGETSEL,0,(LPARAM)&fr.chrg);
SendMessage(edit,EM_FORMATRANGE,TRUE,(LPARAM)&fr);
EndPage(hdc);
EndDoc(hdc);
}
break;
case IDM_Exit:
SendMessage(hWnd,WM_CLOSE,NULL,NULL);
break;
case IDM_Enable_Disable:
EnableMenuItem(hFileMenu,IDM_Exit,MF_BYCOMMAND | nFlag);
nFlag=(nFlag==MF_ENABLED)?MF_GRAYED:MF_ENABLED;
nIndex=(nIndex==0)?1:0;
ModifyMenu(hFileMenu,IDM_Enable_Disable,MF_BYCOMMAND|
MF_STRING,IDM_Enable_Disable,pContent[nIndex]);
break;
Меню Правка. Это меню состоит из подпунктов: Отменить, Вырезать, Копировать, Вставить, Найти. Для отмены последнего действия используется класс Undo, который называется стеком. Метка IDP_Undo ссылается на этот класс через указатель-ссылку.
case IDP_Undo:
{
char * m = undo.removecopy();
SetWindowText(edit, m);
UpdateWindow(edit);
delete [] m;
}
break;
case IDP_Cut: SendMessage(edit,WM_CUT,0,0);
break;
case IDP_Copy: SendMessage(edit,WM_COPY,0,0);
break;
case IDP_Paste: SendMessage(edit,WM_PASTE,0,0);
break;
case IDP_Find:
{
find.hInstance=hInst;
find.lStructSize=sizeof(find);
find.hwndOwner=hWnd;
find.Flags=FR_DOWN|FR_NOMATCHCASE;
find.lpstrFindWhat=str;
find.wFindWhatLen=200;
find.lpstrReplaceWith=NULL;
find.wReplaceWithLen=0;
find.lCustData=0;
find.lpfnHook=NULL;
find.lpTemplateName=NULL;
poisk=FindText(&find);
}
break;
Меню Вставка. Это меню состоит из основных пунктов: Дата и время и Символ. Пункт "Символ" состоит из трёх подпунктов, которые по отдельности прописываются в очереди сообщений (IDP_Alpha, IDP_Sigma, IDP_Omega). Таймер в данной программе используется для самой вставки даты и времени.
case IDP_Datetime:
{
int size = GetWindowTextLength(edit);
char * m = new char [size + 100];
GetWindowText(edit, m, size + 1);
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
char* txt=asctime(timeinfo);
strcpy(m+size, txt);
//SendMessage(edit,WM_SETTEXT,(WPARAM)txt,0);
SetWindowText(edit, m);
delete[] m;
}
break;
case IDP_Alpha:
//Вставка символа "Альфа"
{
CHARRANGE cr;
cr.cpMin=-1;
cr.cpMax=-1;
//Становится в конец Richedit
SendMessage(edit,EM_EXSETSEL,0,(LPARAM)&cr);
wchar_t str[] = L"0x0391";
SendMessage(edit,EM_REPLACESEL,0,(LPARAM)str);
}
break;
case IDP_Sigma:
//Вставка символа "Сигма"
break;
case IDP_Omega:
//Вставка символа "Омега"
break;
Меню Формат. Это меню состоит из одного пункта Шрифт, то есть IDP_Font. Это меню состоит из двух основных структур - логического и встроенного шрифтов (т.е. LOGFONT и CHOOSEFONT), а также из множества функций для работы со шрифтом. В качестве справочника, для этих целей используется сайт с названием msdn.microsoft.com.
case IDP_Font:
{
LOGFONT lf;
CHOOSEFONT cf;
cf.lStructSize=sizeof(cf);
cf.hwndOwner=hWnd;
cf.lpLogFont=&lf;
cf.Flags=CF_EFFECTS|CF_SCREENFONTS;
cf.hInstance=0;
BOOL result=ChooseFont(&cf);
if(!result)
{
MessageBox(hWnd,"E","E",MB_OK);
break;
}
else
{
font=CreateFontIndirect(&lf);
textcolor = cf.rgbColors;
//Размер выделения для всего текста
CHARRANGE cr;
cr.cpMin = 0;
cr.cpMax = -1;
SendMessage(edit, EM_EXSETSEL, 0, (LPARAM)&cr);
CHARFORMAT cf2;
cf2.cbSize=sizeof(cf2);
cf2.dwMask=CFM_COLOR|CFM_FACE|CFM_ITALIC|CFE_BOLD;
cf2.dwEffects = cf.lpLogFont->lfItalic ? CFE_ITALIC : 0;
cf2.dwEffects |= cf.lpLogFont->lfWeight >= 300 ? CFE_BOLD : 0;
cf2.yHeight = 20;
cf2.yOffset = 10;
strcpy (cf2.szFaceName, cf.lpLogFont->lfFaceName);
cf2.crTextColor=cf.rgbColors;
int res = SendMessage(edit, EM_SETCHARFORMAT,
SCF_SELECTION,(LPARAM)&cf2);
if(res == 0)
MessageBox(hWnd, "qqqq", "qq", MB_OK);
//SendMessage(edit, WM_SETFONT, (WPARAM)font, TRUE);
}
}
break;
Меню Справка. Для простоты решения задачи, проектируется меню содержащее только один пункт с названием Вызов справки. Второй пункт в данном проекте не используется. Пункт "Вызов справки" описан следующим образом:
case IDP_Help:
WinHelp(hWnd,"myhelp.hlp", HELP_CONTENTS, 0);
break;
Для описания всех вложенных меню используется следующая конструкция:
case WM_MENUSELECT:
if(((UINT)HIWORD(wParam)==0xffff)&((HMENU)lParam==0))
{
SendMessage(hStatusWindow,SB_SETTEXT,(WPARAM)0,
(LPARAM)pMessages[5]);
return 0;
}
if((UINT)HIWORD(wParam)&MF_SYSMENU)
{
SendMessage(hStatusWindow,SB_SETTEXT,(WPARAM)0,
(LPARAM)pMessages[6]);
return 0;
}
if((UINT)HIWORD(wParam)&MF_POPUP)
{
SendMessage(hStatusWindow,SB_SETTEXT,(WPARAM)0,
(LPARAM)pMessages[3+LOWORD(wParam)]);
return 0;
}
SendMessage(hStatusWindow, SB_SETTEXT, (WPARAM)0, (LPARAM)pMessages [LOWORD(wParam)]);
return 0;
//Описывается контекстное меню
case WM_RBUTTONDOWN:
{
HMENU hMenu1=CreatePopupMenu();
AppendMenu(hMenu1, MFT_STRING, IDP_All, "&Выделить всё");
AppendMenu(hMenu1, MFT_SEPARATOR, 0, NULL);
AppendMenu(hMenu1, MFT_STRING, IDM_Exit, "&Выход");
TrackPopupMenu(hMenu1, TPM_RIGHTBUTTON | TPM_TOPALIGN| TPM_LEFTALIGN,
LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL);
DestroyMenu(hMenu1);
}
break;
5. Листинг программы
// Программа БЛОКНОТ
#define _RICHEDIT_VER 0x0200
#include <windows.h>
#include <richedit.h>
#include <iostream.h>
#include <fstream.h>
#include <commctrl.h>
#include <time.h>
#include <stdlib.h>
//Библиотека <commctrl.h> создаётся для создания строки состояния
#include "resource.h"
//Для создания шрифта используются следующие константы
HFONT font;
//Для поиска текста
HWND poisk; //Хэндл диалога поиска
char str[200];
FINDREPLACE find;
UINT find_msg;
//Для создания меню нужно объявить следующие константы
const IDM_Enable_Disable=0;
const IDM_Exit=1;
const IDM_About=2;
const IDP_File=3;
const IDP_Help=4;
const IDP_Open=5;
const IDP_Save=6;
const IDP_Print=7;
const IDP_Undo=8;
const IDP_Cut=9;
const IDP_Copy=10;
const IDP_Paste=11;
const IDP_Datetime=12;
const IDP_Symbol=13;
const IDP_Font=14;
const IDP_All=15;
const IDP_Find=16;
const IDP_Alpha=17;
const IDP_Sigma=18;
const IDP_Omega=19;
//Объявляется массив для комментариев в нижней строке состояния
char* pMessages[] =
{
"Включить или отключить выход",
"Выйти из программы",
"О программе",
"Меню Файл",
"","","","","","","","","","","",
"Меню Правка",
"Меню Вставка",
"Меню Формат",
"Меню Справка",
"Пустой блокнот. Написал Алексей",
};
//Глобальная переменная для состояния
//документа (для закрытия окна)
BOOL change=FALSE;
LRESULT CALLBACK WndProc (HWND,UINT, WPARAM, LPARAM);
//Для команды "Отмена" объявляется этот класс
class Undo
{
public:
char* stack_u[10]; // на 10 действий назад массив будет хранить
int number;//сколько проделано действий
//Объявляется конструктор
Undo ()
{ number=0;}
//Добавление новой копии
void addcopy(char *copy);
char * removecopy();
};
void Undo::addcopy(char *copy)
{
if (number == 10)
{
delete [] stack_u[0];
for(int i=1; i<number; i++) {
stack_u[i-1] = stack_u[i];
}
number--;
}
stack_u[number] = copy;
number++;
}
char* Undo::removecopy()
{
if(number == 0)
{
return "";
}
//Откатить счётчик последних действий на единицу
number--;
return stack_u[number];
}
Undo undo;
HWND hStatusWindow; //Переменная для создания строки состояния
HWND toolbar2;
UINT wld=2; //Переменная для строки состояния
HMENU hMenu,hFileMenu,hPravkaMenu,hPasteMenu,hFormatMenu,hHelpMenu;
HINSTANCE hInst;
HWND edit;
HWND hWnd;
//Для пункта меню "Включить/отключить віход"
RECT Rect;
static UINT nFlag=MF_ENABLED;
char* pContent[] =
{
"Включить выход", "Отключить выход"
};
static UINT nIndex=0;
//static HBITMAP hBitmap;
int nDimension;
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpszCmdParam, int nCmdShow)
{
WNDCLASS WndClass={0};
MSG Msg;
hInst=hInstance;
WndClass.style=CS_HREDRAW|CS_VREDRAW;
WndClass.lpfnWndProc= WndProc;
WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hInstance=hInstance;
WndClass.hIcon=NULL;
WndClass.hCursor=NULL;
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.lpszMenuName=NULL;
WndClass.lpszClassName="MenuExample";
if(!RegisterClass(&WndClass))
{
MessageBox(NULL,"Cannot register class","Error",MB_OK);
return 0;
}
find_msg=RegisterWindowMessage(FINDMSGSTRING);
hWnd=CreateWindow("MenuExample","Блокнот Ярослава",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT,500,300,
NULL,NULL,hInstance,NULL);
if(!hWnd)
{
MessageBox(NULL,"Cannot create window","Error",MB_OK);
return 0;
}
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
//Окно для редактирования
//В зависимости от версии большое текстовой поле называется по-разному
LoadLibrary("Msftedit.dll");
edit=CreateWindowExW(WS_EX_CLIENTEDGE,L"RICHEDIT50W",
L"",WS_VISIBLE|WS_CHILD| ES_MULTILINE,10, 10,
300, 300,hWnd,(HMENU)10,hInstance,NULL);
if (!edit)
{
MessageBox(hWnd,"e","e",MB_OK);
return 0;
}
//Создание второй панели инструментов
INITCOMMONCONTROLSEX icx;
icx.dwICC = ICC_BAR_CLASSES;
icx.dwSize = sizeof(icx);
InitCommonControlsEx(&icx);
TBBUTTON buttons[3] =
{
{0,IDP_Save, TBSTATE_ENABLED,TBSTYLE_BUTTON, 0, NULL},
{1,IDP_Open, TBSTATE_ENABLED,TBSTYLE_BUTTON, 0, NULL},
{2,IDP_Print,TBSTATE_ENABLED,TBSTYLE_BUTTON, 0, NULL}
};
toolbar2=CreateToolbarEx(hWnd,WS_CHILD|WS_VISIBLE|TBSTYLE_TOOLTIPS,103,3,hInstance,IDB_BITMAP1,buttons,3,22,22,20,20,sizeof(TBBUTTON));
if(!toolbar2)
{
MessageBox(NULL,"Cannot create toolbar window","Error",MB_OK);
return 0;
}
InitCommonControls();
hStatusWindow=CreateStatusWindow(WS_CHILD|WS_VISIBLE,"Блокнот Ярослава",hWnd,wld);
if(!hStatusWindow)
{
MessageBox(NULL,"Cannot create window","Error",MB_OK);
return 0;
}
//Описывается меню File
hFileMenu=CreatePopupMenu();
if(hFileMenu)
{
//IDP_Save
AppendMenu(hFileMenu,MF_ENABLED|MF_STRING,IDP_Open,"&Открыть");
AppendMenu(hFileMenu,MF_ENABLED|MF_STRING,IDP_Save,"&Сохранить");
AppendMenu(hFileMenu, MFT_SEPARATOR, 0, NULL);
AppendMenu(hFileMenu,MF_ENABLED|MF_STRING,IDP_Print,"&Печать");
AppendMenu(hFileMenu, MF_ENABLED|MF_STRING, IDM_Enable_Disable,
"&Включить выход");
AppendMenu(hFileMenu,MF_GRAYED|MF_STRING,IDM_Exit,"В&ыход");
}
//Описывается меню Правка
hPravkaMenu=CreatePopupMenu();
if(hPravkaMenu)
{
AppendMenu(hPravkaMenu,MF_ENABLED|MF_STRING,IDP_Undo,"&Отменить");
AppendMenu(hPravkaMenu,MF_ENABLED|MF_STRING,IDP_Cut,"&Вырезать");
AppendMenu(hPravkaMenu,MF_ENABLED|MF_STRING,IDP_Copy,"&Копировать");
AppendMenu(hPravkaMenu,MF_ENABLED|MF_STRING,IDP_Paste,"&Вставить");
AppendMenu(hPravkaMenu,MF_ENABLED|MF_STRING,IDP_Find,"&Найти");
}
//Описывается меню Вставка
hPasteMenu = CreatePopupMenu();
if(hPasteMenu)
{
AppendMenu(hPasteMenu, MF_ENABLED|MF_STRING, IDP_Datetime,
"&Дата и время");
HMENU symbol_menu=CreatePopupMenu();
AppendMenu(symbol_menu,MF_ENABLED|MF_STRING,IDP_Alpha,"ALPHA");
AppendMenu(symbol_menu,MF_ENABLED|MF_STRING,IDP_Sigma,"SIGMA");
AppendMenu(symbol_menu,MF_ENABLED|MF_STRING,IDP_Omega,"OMEGA");
AppendMenu(hPasteMenu, MF_ENABLED|MF_POPUP,
(DWORD)symbol_menu,"Символ");
}
//Описывается меню Формат
hFormatMenu=CreatePopupMenu();
if(hFormatMenu)
{
AppendMenu(hFormatMenu,MF_ENABLED|MF_STRING, IDP_Font,"&Шрифт");
}
//Описывается меню Help
hHelpMenu=CreatePopupMenu();
if(hHelpMenu)
{
AppendMenu(hHelpMenu,MF_ENABLED|MF_STRING,IDP_Help,"&Вызов справки");
AppendMenu(hHelpMenu, MFT_SEPARATOR, 0, NULL);
AppendMenu(hHelpMenu,MF_ENABLED|MF_STRING,IDM_About,"&О программе");
}
//Функцию CreateMenu() обязательно нужно присвоить этой переменной
hMenu=CreateMenu();
//Присоединяется меню к главной панели управления и к окну
AppendMenu(hMenu,MF_ENABLED|MF_POPUP, (DWORD)hFileMenu,"&Файл");
AppendMenu(hMenu,MF_ENABLED|MF_POPUP, (DWORD)hPravkaMenu,"&Правка");
AppendMenu(hMenu,MF_ENABLED|MF_POPUP, (DWORD)hPasteMenu,"&Вставка");
AppendMenu(hMenu,MF_ENABLED|MF_POPUP, (DWORD)hFormatMenu,"&Формат");
AppendMenu(hMenu,MF_ENABLED|MF_POPUP, (DWORD)hHelpMenu,"&Справка");
SetMenu(hWnd,hMenu);
//Загрузка акселераторов
ACCEL actable[] =
{
{ FCONTROL|FVIRTKEY, 0x53, IDP_Save },
{ FALT|FVIRTKEY, 0x50, IDP_Print }
};
HACCEL hAccel=CreateAcceleratorTable(actable, 2);
if (!hAccel)
{
MessageBox(hWnd,"E","E",MB_OK);
}
nDimension=GetSystemMetrics(SM_CYMENU);
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&Msg,NULL,0,0))
{
if(!TranslateAccelerator(hWnd,hAccel,&Msg))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
return Msg.wParam;
}
int x;
int y;
int nWidth;
int nHeight;
char *lpszChar;
HDC hdc; // контекст устройства
COLORREF textcolor;
void Save()
{
//Сохранение файла
char filename_s[300];
filename_s[0] = 0;
OPENFILENAME of;
of.lStructSize = sizeof(of);
of.hwndOwner = hWnd;
of.hInstance = hInst;
of.lpstrFilter = "texts files\0*.txt\0\0";
of.lpstrCustomFilter = NULL;
of.nMaxCustFilter = 0;
of.nFilterIndex = 1;
of.lpstrFile = filename_s;
of.nMaxFile = sizeof(filename_s);
of.lpstrFileTitle = NULL;
of.nMaxFileTitle = 0;
of.lpstrInitialDir = NULL;
of.lpstrTitle = "Сохранение файла";
of.Flags = OFN_FILEMUSTEXIST;
of.lpstrDefExt = "bmp";
of.lCustData = 0;
of.lpfnHook = NULL;
of.lpTemplateName = NULL;
BOOL result=GetSaveFileName(&of);
ofstream fout;
fout.open(filename_s,ios::out|ios::binary);
if(!fout)
{
MessageBox(hWnd,"Error","Открыть не удалось",MB_OK);
return;
}
ofstream f;
f.open(filename_s);
int size = GetWindowTextLength(edit);
char * m = new char [size];
GetWindowText(edit, m, size);
f.write(m, size);
delete m;
fout.close();
}
LRESULT CALLBACK WndProc (HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam)
{
//Для поиска
if(Message==find_msg)
{
if(find.Flags & FR_FINDNEXT)
//Выделяется найденное слово
/*FINDTEXT ft;
ft.lpstrText=str;
ft.chrg.cpMin=0;
ft.chrg.cpMax=-1;
SendMessage(edit,EM_FINDTEXT,FR_DOWN,&ft);*/
return 0;
}
switch (Message)
{
case WM_CREATE:
return 0;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDM_Enable_Disable:
EnableMenuItem(hFileMenu,IDM_Exit,MF_BYCOMMAND | nFlag);
nFlag=(nFlag==MF_ENABLED)?MF_GRAYED:MF_ENABLED;
nIndex=(nIndex==0)?1:0;
ModifyMenu(hFileMenu,IDM_Enable_Disable,MF_BYCOMMAND|MF_STRING,IDM_Enable_Disable,
pContent[nIndex]);
break;
case IDP_Open:
{
//Открытие файла
char filename[300];
filename[0] = 0;
OPENFILENAME of;
of.lStructSize = sizeof(of);
of.hwndOwner = hWnd;
of.hInstance = hInst;
of.lpstrFilter = "texts files\0*.txt\0\0";
of.lpstrCustomFilter = NULL;
of.nMaxCustFilter = 0;
of.nFilterIndex = 1;
of.lpstrFile = filename;
of.nMaxFile = sizeof(filename);
of.lpstrFileTitle = NULL;
of.nMaxFileTitle = 0;
of.lpstrInitialDir = NULL;
of.lpstrTitle = "Открытие файла";
of.Flags = OFN_FILEMUSTEXIST;
of.lpstrDefExt = "bmp";
of.lCustData = 0;
of.lpfnHook = NULL;
of.lpTemplateName = NULL;
BOOL result=GetOpenFileName(&of);
if(!result)
{
MessageBox(hWnd,"Error","Ошибка",MB_OK);
break;
}
ifstream f;
f.open(filename);
f.seekg(0, f.end);
int size = f.tellg();
f.seekg(0, f.beg);
char * m = new char [size];
f.read(m, size);
SetWindowText(edit, m);
UpdateWindow(edit);
delete m;
}
break;
case IDP_Save:
Save();
break;
case IDP_Undo:
{
char * m = undo.removecopy();
SetWindowText(edit, m);
UpdateWindow(edit);
delete [] m;
}
break;
case IDP_Print:
{
PRINTDLG print_dlg = {0};
print_dlg.lStructSize = sizeof(print_dlg);
print_dlg.Flags = PD_RETURNDC;
BOOL result=PrintDlg(&print_dlg);
if(!result)
{
MessageBox(hWnd,"Print Error", "Не выдаёт печать", MB_OK);
break;
}
//Вывод тестового текста на принтер
HDC hdc = print_dlg.hDC;
DOCINFO di = { sizeof(di) };
di.lpszDocName = "qqq.txt";
//Подключение к RichEdit
StartDoc(hdc,&di);
SendMessage(edit,EM_SETTARGETDEVICE,(WPARAM)hdc,0);
StartPage(hdc);
//Выделить всё
SendMessage(edit,EM_SETSEL,0,-1);
FORMATRANGE fr;
fr.hdc=hdc;
fr.hdcTarget = hdc;
fr.rcPage.left=0;
fr.rcPage.right=100;
fr.rcPage.top = 0;
fr.rcPage.bottom = 100;
SendMessage(edit,EM_EXGETSEL,0,(LPARAM)&fr.chrg);
SendMessage(edit,EM_FORMATRANGE,TRUE,(LPARAM)&fr);
EndPage(hdc);
EndDoc(hdc);
}
break;
case IDM_Exit:
SendMessage(hWnd,WM_CLOSE,NULL,NULL);
break;
case IDP_Cut:
SendMessage(edit,WM_CUT,0,0);
break;
case IDP_Copy:
SendMessage(edit,WM_COPY,0,0);
break;
case IDP_Paste:
SendMessage(edit,WM_PASTE,0,0);
break;
case IDP_Find:
{
find.hInstance=hInst;
find.lStructSize=sizeof(find);
find.hwndOwner=hWnd;
find.Flags=FR_DOWN|FR_NOMATCHCASE;
find.lpstrFindWhat=str;
find.wFindWhatLen=200;
find.lpstrReplaceWith=NULL;
find.wReplaceWithLen=0;
find.lCustData=0;
find.lpfnHook=NULL;
find.lpTemplateName=NULL;
poisk=FindText(&find);
}
break;
case IDP_Font:
{
LOGFONT lf;
CHOOSEFONT cf;
cf.lStructSize=sizeof(cf);
cf.hwndOwner=hWnd;
cf.lpLogFont=&lf;
cf.Flags=CF_EFFECTS|CF_SCREENFONTS;
cf.hInstance=0;
BOOL result=ChooseFont(&cf);
if(!result)
{
MessageBox(hWnd,"E","E",MB_OK);
break;
}
else
{
font=CreateFontIndirect(&lf);
textcolor = cf.rgbColors;
//Размер выделения для всего текста
CHARRANGE cr;
cr.cpMin = 0;
cr.cpMax = -1;
SendMessage(edit, EM_EXSETSEL, 0, (LPARAM)&cr);
CHARFORMAT cf2;
cf2.cbSize=sizeof(cf2);
cf2.dwMask=CFM_COLOR|CFM_FACE|CFM_ITALIC|CFE_BOLD;
cf2.dwEffects = cf.lpLogFont->lfItalic ? CFE_ITALIC : 0;
cf2.dwEffects |= cf.lpLogFont->lfWeight >= 300 ? CFE_BOLD : 0;
cf2.yHeight = 20;
cf2.yOffset = 10;
strcpy(cf2.szFaceName, cf.lpLogFont->lfFaceName);
cf2.crTextColor=cf.rgbColors;
int res = SendMessage(edit,EM_SETCHARFORMAT,SCF_SELECTION,(LPARAM)&cf2);
if(res == 0)
MessageBox(hWnd, "qqqq", "qq", MB_OK);
//SendMessage(edit, WM_SETFONT, (WPARAM)font, TRUE);
}
}
break;
case IDP_Datetime:
{
int size = GetWindowTextLength(edit);
char * m = new char [size + 100];
GetWindowText(edit, m, size + 1);
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
char* txt=asctime(timeinfo);
strcpy(m+size, txt);
//SendMessage(edit,WM_SETTEXT,(WPARAM)txt,0);
SetWindowText(edit, m);
delete[] m;
}
break;
case IDP_Alpha:
//Вставка символа "Альфа"
{
CHARRANGE cr;
cr.cpMin=-1;
cr.cpMax=-1;
//Становится в конец Richedit
SendMessage(edit,EM_EXSETSEL,0,(LPARAM)&cr);
wchar_t str[] = L"0x0391";
SendMessage(edit,EM_REPLACESEL,0,(LPARAM)str);
}
break;
case IDP_Sigma:
//Вставка символа "Сигма"
break;
case IDP_Omega:
//Вставка символа "Омега"
break;
case IDP_Help:
WinHelp(hWnd,"myhelp.hlp", HELP_CONTENTS, 0);
break;
default:
return DefWindowProc(hWnd,Message,wParam,lParam);
}
return 0;
case WM_SIZE:
SetWindowPos(edit,0,0,25,LOWORD(lParam),HIWORD(lParam)-25-20,0);
UpdateWindow(edit);
SendMessage(hStatusWindow, Message, wParam, lParam);
break;
case WM_MENUSELECT:
if(((UINT)HIWORD(wParam)==0xffff)&((HMENU)lParam==0))
{
SendMessage(hStatusWindow,SB_SETTEXT,(WPARAM)0,
(LPARAM)pMessages[5]);
return 0;
}
// ??
if((UINT)HIWORD(wParam)&MF_SYSMENU)
{
SendMessage(hStatusWindow,SB_SETTEXT,(WPARAM)0,
(LPARAM)pMessages[6]);
return 0;
}
if((UINT)HIWORD(wParam)&MF_POPUP)
{
SendMessage(hStatusWindow,SB_SETTEXT,(WPARAM)0,
(LPARAM)pMessages[3+LOWORD(wParam)]);
return 0;
}
SendMessage(hStatusWindow,SB_SETTEXT,(WPARAM)0,(LPARAM)pMessages[LOWORD(wParam)]);
return 0;
//Описывается контекстное меню
case WM_RBUTTONDOWN:
{
HMENU hMenu1=CreatePopupMenu();
AppendMenu(hMenu1, MFT_STRING, IDP_All, "&Выделить всё");
AppendMenu(hMenu1, MFT_SEPARATOR, 0, NULL);
AppendMenu(hMenu1, MFT_STRING, IDM_Exit, "&Выход");
TrackPopupMenu(hMenu1, TPM_RIGHTBUTTON | TPM_TOPALIGN| TPM_LEFTALIGN,
LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL);
DestroyMenu(hMenu1);
}
break;
//Уведомление об изменении
case WM_NOTIFY:
{
int size = GetWindowTextLength(edit);
char * m = new char [size+1];
GetWindowText(edit, m, size);
m[size] = 0;
undo.addcopy(m);
change = TRUE;
}
break;
case WM_CLOSE:
{
if(change)
{
int res = MessageBox(hWnd,"Cохранить изменения в документе?",
"Cохранение документа",MB_YESNO);
if(res==IDYES)
Save();
}
}
return DefWindowProc(hWnd,Message,wParam,lParam);
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd,Message,wParam,lParam);
}
return 0;
}
Литература
1. П.В. Румянцев. Азбука программирования в Win32 API.
2. П.В. Румянцев. Работа с файлами в Win32 API.
3. К.Г. Финогенов. Win32 Основы программирования.
4. Джеффри Ріхтер. Создание эффективных Win32 приложений.
5. Джефф Элджер. Библиотека программиста.
6. Герберт Шилдт. С++ Базовый курс.
7. Т.А. Павловская, Ю.А. Щупак С++ Объектно-ориентированное программирование.
8. Msdn.microsoft.com - основной сайт для решения сложных задач по программированию.
9. http://www.ixbt.com/soft/help-and-manual.shtml - ссылка для создания файлов справки.
Размещено на Allbest.ru
Подобные документы
Разработка базы данных, содержащей сведения о студентах, их успеваемости и предпочтениях. Создание таблиц, пользовательских форм, запросов, отчетов, строки меню, панели инструментов, контекстного меню в Access. Настройка параметров запуска приложения.
контрольная работа [682,4 K], добавлен 08.05.2015Рассмотрение истории создания, особенностей (интеллектуальное обесцвечивание, динамика кистей), преимуществ и недостатков бесплатного растрового графического редактора GIMP. Ознакомление с интерфейсом программы. Описание меню панели инструментов.
реферат [62,6 K], добавлен 04.08.2010Общий вид окна MathCad, меню панели инструментов исследуемой программы. Документ MathCad, его общая характеристика и методы редактирования. Разделение областей и контекстное меню, выражения. Определение дискретного аргумента, переменных и констант.
презентация [656,5 K], добавлен 29.09.2013Описание текстового редактора MS WORD, его возможности. Основные элементы интерфейса редактора: кнопка Office, главные команды панели быстрого доступа, лента, контекстное меню и полоса прокрутки. Рабочая область приложения, настройка строки состояния.
реферат [24,0 K], добавлен 23.10.2014Задачи, выполняемые главным меню оперативной системы. Разделы меню "пуск". Запуск программ компьютера. Использование поля поиска. Ссылки правой панели на часто используемые компоненты. Кнопка "Завершение работы". Настройка отображения элементов на панели.
презентация [1,2 M], добавлен 21.03.2015Принцип программной реализации классических криптографических методов. Метод шифрования с использованием таблицы Виженера. Создание текстового редактора "Блокнот", содержащего методы шифрования. Вербальный алгоритм и программа для методов шифрования.
курсовая работа [2,0 M], добавлен 20.01.2010Разработка клиент-серверного приложения под управлением Windows на языке программирования Delphi, реализующего функции дистанционного обучения (тесты). Основная форма программы, которая состоит из меню, панели активации пользователя и панели чата.
курсовая работа [4,3 M], добавлен 15.04.2019Характеристика структурированного языка программирования С, его основных структурных компонентов, области памяти, библиотеки. Методы поиска в массивах данных. Описание программы, функции сортировки и меню выбора, последовательного и бинарного поиска.
курсовая работа [1,7 M], добавлен 19.05.2014Понятие и функциональные особенности, классификация и разновидности текстовых редакторов и процессоров, характеристика некоторых из них: Блокнот, Microsoft Word. Оценка их возможностей по созданию и форматированию документов. Расчет и оформление баланса.
контрольная работа [100,1 K], добавлен 27.04.2013Разработка алгоритма и программы, которая позволяет создавать программное обеспечение для языка программирования Паскаль. Функциональная спецификация программы. Выбор и обоснование комплекса технических средств. Пользовательское меню и интерфейс.
курсовая работа [1,3 M], добавлен 02.02.2014