1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
| #include "MenuBarDlg.h"
CMenuBarDlg* CMenuBarDlg::ptr = NULL;
CMenuBarDlg::CMenuBarDlg(void){
ptr = this;
bShowStatusBar = TRUE;
}
void CMenuBarDlg::Cls_OnClose(HWND hwnd){
EndDialog(hwnd, 0);
}
HMENU hMenu = LoadMenu(GetModuleHandle(0), MAKEINTRESOURCE(IDR_MENU2));
HMENU hMenu2 = LoadMenu(GetModuleHandle(0), MAKEINTRESOURCE(IDR_MENU3));
BOOL CMenuBarDlg::Cls_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) {
hDialog = hwnd;
// Получим дескриптор текстового поля
hEdit = GetDlgItem(hDialog, IDC_EDIT1);
// Создадим строку состояния
hStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_TOOLTIPS | SBARS_SIZEGRIP, 0, hDialog, WM_USER);
// Загрузим меню из ресурсов приложения
SetMenu(hDialog, hMenu2);
return TRUE;
}
// Обработчик сообщения WM_COMMAND будет вызван при выборе пункта меню
void CMenuBarDlg::Cls_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify){
switch(id){
case ID_UNDO:
case ID_SETTING_CANCEL:
// Отменим последнее действие
SendMessage(hEdit, WM_UNDO, 0, 0);
break;
case ID_CUT:
case ID_SETTING_CUT:
// Удалим выделенный фрагмент текста в буфер обмена
SendMessage(hEdit, WM_CUT, 0, 0);
break;
case ID_COPY:
case ID_SETTING_COPY:
// Скопируем выделенный фрагмент текста в буфер обмена
SendMessage(hEdit, WM_COPY, 0, 0);
break;
case ID_PASTE:
case ID_SETTING_PASTE:
// Вставим текст в Edit Control из буфера обмена
SendMessage(hEdit, WM_PASTE, 0, 0);
break;
case ID_DEL:
case ID_SETTING_DELETE:
// Удалим выделенный фрагмент текста
SendMessage(hEdit, WM_CLEAR, 0, 0);
break;
case ID_SELECTALL:
case ID_SETTING_SELECTALL:
// Выделим весь текст в Edit Control
SendMessage(hEdit, EM_SETSEL, 0, -1);
break;
case ID_STATUSBAR:
case ID_VIEW_STATUSBAR:
// Если флаг равен TRUE, то строка состояния отображена
if(bShowStatusBar) {
// Получим дескриптор главного меню
HMENU hMenu = GetMenu(hDialog);
// Снимем отметку с пункта меню "Строка состояния"
CheckMenuItem(hMenu, ID_STATUSBAR, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_VIEW_STATUSBAR, MF_BYCOMMAND | MF_UNCHECKED);
// Скроем строку состояния
ShowWindow(hStatus, SW_HIDE);
}
else{
// Получим дескриптор главного меню
HMENU hMenu = GetMenu(hDialog);
// Установим отметку на пункте меню "Строка состояния"
CheckMenuItem(hMenu,ID_STATUSBAR, MF_BYCOMMAND | MF_CHECKED);
// Отобразим строку состояния
ShowWindow(hStatus, SW_SHOW);
}
bShowStatusBar = !bShowStatusBar;
}
}
// Обработчик сообщения WM_SIZE будет вызван при изменении размеров главного окна
// либо при сворачивании/восстановлении главного окна
void CMenuBarDlg::Cls_OnSize(HWND hwnd, UINT state, int cx, int cy){
RECT rect1, rect2;
// Получим координаты клиентской области главного окна
GetClientRect(hDialog, &rect1);
// Получим координаты единственной секции строки состояния
SendMessage(hStatus, SB_GETRECT, 0, (LPARAM)&rect2);
// Установим новые размеры текстового поля
MoveWindow(hEdit, rect1.left, rect1.top, rect1.right, rect1.bottom - (rect2.bottom - rect2.top), 1);
// Установим размер строки состояния,
// равный ширине клиентской области главного окна
SendMessage(hStatus, WM_SIZE, 0, 0);
}
// Обработчик WM_INITMENUPOPUP будет вызван непосредственно
// перед активизацией всплывающего меню
void CMenuBarDlg::Cls_OnInitMenuPopup(HWND hwnd, HMENU hMenu, UINT item, BOOL fSystemMenu) {
if(item == 0) {
// Получим границы выделения текста
DWORD dwPosition = SendMessage(hEdit, EM_GETSEL, 0, 0);
WORD wBeginPosition = LOWORD(dwPosition);
WORD wEndPosition = HIWORD(dwPosition);
if(wEndPosition != wBeginPosition){
// Если имеется выделенный текст,
// то сделаем разрешёнными пункты меню "Копировать", "Вырезать" и "Удалить"
EnableMenuItem(hMenu, ID_COPY, MF_BYCOMMAND | MF_ENABLED);
EnableMenuItem(hMenu, ID_CUT, MF_BYCOMMAND | MF_ENABLED);
EnableMenuItem(hMenu, ID_DEL, MF_BYCOMMAND | MF_ENABLED );
}
else{
// Если отсутствует выделенный текст,
// то сделаем недоступными пункты меню "Копировать", "Вырезать" и "Удалить"
EnableMenuItem(hMenu, ID_COPY, MF_BYCOMMAND | MF_GRAYED );
EnableMenuItem(hMenu, ID_CUT, MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(hMenu, ID_DEL, MF_BYCOMMAND | MF_GRAYED);
}
if(IsClipboardFormatAvailable(CF_TEXT)) // Имеется ли текст в буфере обмена?
// Если имеется текст в буфере обмена,
// то сделаем разрешённым пункт меню "Вставить"
EnableMenuItem(hMenu, ID_PASTE, MF_BYCOMMAND | MF_ENABLED);
else
// Если отсутствует текст в буфере обмена,
// то сделаем недоступным пункт меню "Вставить"
EnableMenuItem(hMenu, ID_PASTE, MF_BYCOMMAND | MF_GRAYED);
// Существует ли возможность отмены последнего действия?
if(SendMessage(hEdit, EM_CANUNDO, 0, 0))
// Если существует возможность отмены последнего действия,
// то сделаем разрешённым пункт меню "Отменить"
EnableMenuItem(hMenu, ID_UNDO, MF_BYCOMMAND | MF_ENABLED);
else
// Если отсутствует возможность отмены последнего действия,
// то сделаем недоступным пункт меню "Отменить"
EnableMenuItem(hMenu, ID_UNDO, MF_BYCOMMAND | MF_GRAYED);
// Определим длину текста в Edit Control
int length = SendMessage(hEdit, WM_GETTEXTLENGTH, 0, 0);
// Выделен ли весь текст в Edit Control?
if(length != wEndPosition - wBeginPosition)
//Если не весь текст выделен в Edit Control,
// то сделаем разрешённым пункт меню "Выделить всё"
EnableMenuItem(hMenu, ID_SELECTALL, MF_BYCOMMAND | MF_ENABLED);
else
// Если выделен весь текст в Edit Control,
// то сделаем недоступным пункт меню "Выделить всё"
EnableMenuItem(hMenu, ID_SELECTALL, MF_BYCOMMAND | MF_GRAYED);
}
}
void CMenuBarDlg::Cls_OnMenuSelect(HWND hwnd, HMENU hmenu, int item, HMENU hmenuPopup, UINT flags){
if(flags & MF_POPUP) // Проверим, является ли выделенный пункт меню заголовком выпадающего подменю?
{
// Выделенный пункт меню является заголовком выпадающего подменю
SendMessage(hStatus, SB_SETTEXT, 0, 0); // Убираем текст со строки состояния
}
else{
// Выделенный пункт меню является конечным пунктом (пункт меню "команда")
TCHAR buf[200];
// Получим дескриптор текущего экземпляра приложения
HINSTANCE hInstance = GetModuleHandle(0);
// Зарузим строку из таблицы строк, расположенной в ресурсах приложения
// При этом идентификатор загружаемой строки строго соответствует идентификатору выделенного пункта меню
LoadString(hInstance, item, buf, 200);
// Выводим в строку состояния контекстную справку, соответствующую выделенному пункту меню
SendMessage(hStatus, SB_SETTEXT, 0, LPARAM(buf));
}
}
BOOL CALLBACK CMenuBarDlg::DlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
switch(message){
HANDLE_MSG(hwnd, WM_CLOSE, ptr->Cls_OnClose);
HANDLE_MSG(hwnd, WM_INITDIALOG, ptr->Cls_OnInitDialog);
HANDLE_MSG(hwnd, WM_COMMAND, ptr->Cls_OnCommand);
HANDLE_MSG(hwnd, WM_SIZE, ptr->Cls_OnSize);
HANDLE_MSG(hwnd, WM_INITMENUPOPUP, ptr->Cls_OnInitMenuPopup);
HANDLE_MSG(hwnd, WM_MENUSELECT, ptr->Cls_OnMenuSelect);
}
return FALSE;
} |