Проектирование программы Текстовый Редактор Блокнот

Ознакомление с историей изобретение языка программирования 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

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.