Организация многооконной обработки информации в windows

Работа по теме: Лекция 11 MDI. Глава: Элементы mdi. ВУЗ: ХНУРЭ.

Лекция
Многооконный интерфейс

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

Многооконный интерфейс
(Multiple Document Interface, MDI) является спецификацией
для приложений, которые
обрабатывают
документы в Microsoft Windows. Спецификация
описывает структуру
окон и пользовательский
интерфейс, который
позволяет пользователю работать с
несколькими документами внутри одного
приложения
(с документами в
текстовом процессоре или с таблицами
в программе электронных
таблиц). Точно
также, как Windows
поддерживает несколько окон приложений
на одном экране, приложение MDI поддерживает
несколько окон
документов в одной рабочей области.
Первым приложением MDI для Windows была
первая версия
Microsoft Excel. Microsoft Word
for Windows и Microsoft Access являются приложениями
MDI. Хотя
спецификация MDI была введена, уже начиная
с Windows 2, в то время писать приложения
MDI было трудно,
и от программиста требовалось большая
очень сложная работа. Однако, начиная
с Windows 3, большая
часть этой работы
была сделана. Windows 95 добавляет только
одну новую функцию и одно новое сообщение
к набору
функций, структурам данных и сообщениям,
которые существуют специально для
упрощения создания
приложений MDI.

Главное окно приложения
программы MDI обычно: в нем имеется строка
заголовка, меню, рамка изменения
размера, значок
системного меню и значки свертывания.
Рабочая область, однако, не используется
непосредственно
для вывода выходных данных программы.
В этой рабочей области может находиться
несколько
дочерних окон, в
каждом из которых отображается какой
— документ.

Эти дочерние окна выглядят
совершенно так же, как обычные окна
приложений. В них имеется строка
заголовка,
рамка изменения
размера, значок системного меню, значки
свертывания и, возможно, полосы
прокрутки. Однако,
ни в одном из окон документов нет меню.
Меню главного окна приложения относится
и к окнам
документов.

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

Поначалу, MDI для
Windows-программиста кажется совершенно
понятным. Все, что нужно сделать — это
создать для
каждого документа окно WS_CHILD, делая
главное окно приложения родительским
окном для окна
документа. Но при
более близком знакомстве с приложением
MDI, таким как Microsoft Excel, обнаруживаются
определенные
трудности, требующие сложного
программирования. Например:

Окно документа MDI может быть
свернуто. Соответствующий значок
выводится в нижней части рабочей
области ( правило:
в приложении MDI для главного окна
приложения и для каждого типа окна
документа будут
использоваться разные значки).

Окно документа MDI может быть
развернуто. В этом случае строка заголовка
окна документа (обычно используется
для вывода в окне имени файла документа)
исчезает, и имя файла оказывается
присоединенным к
имени приложения в строке заголовка
окна приложения. Значок системного меню
окна документа
становится первым пунктом строки
основного меню окна приложения. Значок
для восстановления
размера окна документа становится
последним пунктом строки основного
меню и
оказывается крайним
справа.

Системные быстрые клавиши
для закрытия окна документа те же , что
и для закрытия главного окна, за
исключением того,
что клавиша <Ctrl> используется вместо
клавиши <Alt>. Таким образом, комбинация
<Alt>+<F4> закрывает
окно приложения, а комбинация <Ctrl>+<F4>
закрывает окно документа. Вдобавок к
остальным быстрым клавишам,
комбинация <Ctrl>+<F6> позволяет
переключаться между дочерними окнами
документов активного приложения MDI.
Комбинация <Alt>+<Spacebar>, как обычно,
вызывает системное меню
главного окна. Комбинация <Alt>+<->
() вызывает системное меню активного
дочернего окна документа
.

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

Если приложение имеет возможность
поддерживать несколько типов дочерних
окон (электронные таблицы и диаграммы
в Microsoft Excel), то меню должно отражать
операции, ассоциированные
с каждым типом документа. Для этого
требуется, чтобы программа изменяла
меню программы, когда
становится активным окно документа
другого типа. Кроме этого, при отсутствии
окна документа, в меню
должны быть представлены только операции,
связанные с открытием нового
документа.

В строке основного меню имеется пункт
Window. По соглашению, он является последним
пунктом строки основного
меню, исключая Help. В подменю Window обычно
имеются опции для упорядочивания окон
документов внутри рабочей области.
Окна документов можно расположить
cascaded, начиная от верхнего
левого угла , или tiled так , что окно каждого
документа будет полностью видимо .

Кроме того, в этом подменю имеется
перечень всех окон документов. При
выборе одного из окон
документов, оно выходит на передний
план.

Все эти аспекты MDI поддерживаются в
Windows.

Windows и MDI

При знакомстве с поддержкой MDI в Windows
требуется новая терминология. Окно
приложения в целом
называется главным окном (frame window). Также
как в традиционной программе для Windows,
это окно имеет стиль
WS_OVERLAPPEDWINDOW.

Приложение MDI также создает окно — (client
window) на основе предопределенного класса
окна MDICLIENT. Окно создается
с помощью вызова функции CreateWindow с
использованием этого класса
окна и стиля WS_CHILD. Последним параметром
функции CreateWindow является указатель
на небольшую структуру
типа CLIENTCREATESTRUCT. Это окно — охватывает
всю рабочую область главного окна
и обеспечивает основную поддержку
MDI. Цветом окна — является системный цвет
COLOR_APPWORKSPACE.

Рис . 11.1. Иерархия родительских и
дочерних окон приложения MDI в Windows

Окна документов называются дочерними
окнами (child windows). Эти окна создаются
путем инициализации структуры
типа MDICREATESTRUCT и посылки окну — сообщения
WM_MDICREATE с указателем на
эту структуру.

Окна документов являются дочерними
окнами окна-клиента, которое, в свою
очередь, является дочерним
окном главного окна. Эта иерархия
показана на рис. 11.1

Для главного окна и для каждого типа
дочерних окон, которые поддерживаются
в приложении, необходим класс
окна ( оконная процедура ). Для окна
администратора — оконная процедура не
нужна, поскольку ее класс окна
предварительно зарегистрирован в
системе.

Для поддержки MDI в Windows имеется один
класс окна, пять функций, две структуры
данных и двенадцать сообщений.
О классе окна MDICLIENT и структурах данных
CLIENTCREATESTRUCT и MDICREATESTRUCT уже
упоминалось. Две из пяти функций заменяют
в приложениях MDI функцию DefWindowProc:
вместо вызова функции
DefWindowProc для всех необрабатываемых
сообщений, оконная процедура главного
окна вызывает функцию
DefFrameProc, а оконная процедура дочернего
окна вызывает функцию DefMDIChildProc.
Другая характерная функция
MDI TranslateMDISysAccel используется также,
как функция TranslateAccelerator, о которой
рассказывалось в Лекции 10.

Если в дочерних окнах MDI выполняются
протяженные во времени операции,
рассмотрите возможность их
запуска в отдельных потоках. Это позволит
пользователю покинуть дочернее окно и
продолжить работу в другом окне,
пока первое дочернее окно решает свою
задачу в фоновом режиме. В Windows
специально для этой цели имеется
новая функция CreateMDIWindow. Поток вызывает
функцию CreateMDIWindow для
создания дочернего окна MDI; таким образом
окно действует исключительно внутри
контекста потока. В программе,
имеющей один поток, для создания дочернего
окна функция CreateMDIWindow не
требуется, поскольку то же самое
выполняет сообщение WM_MDICREATE.

Приведем пример — потоковую программы,
в которой будет показано девять из
двенадцати сообщений
MDI. Эти сообщения имеют префикс WM_MDI.
Главное окно посылает
одно из этих сообщений окну — для
выполнения операции над дочерним
окном или для получения информации
о дочернем окне (главное окно посылает
сообщение WM_MDICREATE окну —
для создания дочернего окна). Исключение
составляет сообщение
WM_MDIACTIVATE: в то время, как главное окно
может послать это сообщение окну – для
активизации одного из дочерних
окон, окно — также посылает сообщение
тем дочерним окнам, которые
будут активизированы и тем, которые
потеряют активность, чтобы проинформировать
их о предстоящем изменении.

Соседние файлы в папке Конспект лекций

  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #

Марат Хайрулин, эксперт Microsoft в России, продолжает исследовать нюансы работы с несколькими задачами и рассказывает о совмещении окон и разделении экрана, о вашей личной машине времени для сайтов и документов, и о реальной пользе виртуальных столов.

В прошлой заметке мы писали о том, как современная наука относится к многозадачности и делились небольшими приемами, которые помогут сосредоточиться на одной задаче. А теперь хочтим напомнить (а кого-то может быть и познакомить) с полезными возможностями, которые помогут, если решение вашей задачи требует работы сразу с несколькими приложениями.

Переключение по-старому и по-новому

Переключение между приложениями – наверное то, что большинство из нас делает «на автомате», и никого, конечно, не удивит сочетание клавиш Alt + Tab. Но если одновременно нажать также и Ctrl (то есть Ctrl + Alt + Tab), то эта комбинация зафиксирует меню со всеми открытыми окнами на экране и позволит выбрать нужное приложение одним кликом мыши или касанием пальца (выбрать окно можно также с помощью стрелок на клавиатуре, а открыть – с помощью Enter). Может быть полезно, когда у вас открыто много окон.

Чуть менее известное, но тоже классическое сочетание клавиш Windows + Tab дает больше возможностей, чем кажется на первый взгляд.

Нажимая эти клавиши в актуальных версиях Windows 10, мы попадаем в раздел «Представление задач». Здесь можно не только переключаться между приложениями, но и воспользоваться «Временной шкалой» и «Виртуальными рабочими столами». К слову, вместо горячих клавиш вы можете кликнуть по кнопке «Представление задач» (обычно она расположена рядом с кнопкой «Пуск») или провести пальцем от левого края к центру сенсорного экрана. Кстати, если у вас современный ноутбук – попробуйте жест для тачпада: проведите по нему тремя пальцами вверх.


Режим Представление задач

«Временная шкала»

«Временная шкала» появилась в Windows 10 два года назад. Она помогает вернуться к задачам, над которыми вы работали ранее на вашем компьютере. При необходимости вы также сможете синхронизировать ее и с другими устройствами с вашей учетной записью*.

Для меня «Временная шкала» стала своеобразной машиной времени. Работа над многими проектами длится несколько дней. И если, допустим, в прошлую пятницу я работал с определенными сайтами и документами, вернувшись к этому проекту в среду, я смогу легко восстановить картину. Я просто отмотаю шкалу до нужной даты – той самой пятницы, увижу и смогу открыть те самые сайты и документы, в которые я тогда был погружен.


Поиск на Временной шкале

Поиск на «Временной шкале» тоже не раз меня выручал. В отличие от обычного поиска по файлам, я смогу искать не среди всех документов на устройстве (а их может быть очень много), а именно среди тех, с которыми я работал в последние дни. Возможно, вам знакомо сочетание Ctrl + F, запускающее поиск в Проводнике и во многих приложениях. Эта комбинация сработает и на экране «Представление задач»: то есть можно нажать сначала Windows + Tab, а затем – Ctrl + F и ввести искомое слово для поиска по «Временной шкале».

* Подробная справка по настройкам «Временной шкалы».

Виртуальные рабочие столы Windows 10

Концепция виртуальных рабочих столов далеко не нова. Если говорить о Windows, то одним из вариантов их использования была утилита Desktops, которую когда-то (последняя версия вышла в 2012 году) разработал Марк Руссинович. В Windows 10 виртуальные рабочие столы встроены в систему и помогают разделять потоки задач, переключаться между ними.

Если раньше вы не работали с виртуальными столами, для понимания их логики представьте такую аналогию: вам доступно несколько мониторов, на каждом вы можете открыть нужные программы, разделив их по рабочим потокам, например: на одном мониторе – работа с почтой и календарем, на другом – работа с несколькими документами Word, а на третьем – работа с браузером и OneNote. В каждый момент вы смотрите только на один монитор (виртуальный рабочий стол) со своим набором приложений. А переключаясь между виртуальными столами, вы как будто переводите взгляд с одного монитора на другой.


Перетаскивание окна для переноса его на новый виртуальный рабочий стол

Создать новый виртуальный рабочий стол можно на экране «Представление задач»: нажмите Windows + Tab и перетащите нужные окна открытых приложений на поле с надписью «+ Создать рабочий стол», и они будут перемещены на другой виртуальный рабочий стол. Можно также создать новый, пустой виртуальный стол (Windows + Ctrl + D) и уже затем открыть на нем нужные программы.

«Переводить взгляд» (то есть переключаться между настроенными рабочими столами) можно, выбирая нужный стол на экране «Представление задач», но намного удобнее переключаться с помощью горячих клавиш: Windows + Ctrl + стрелки вправо/влево, а на современных тачпадах – 4 пальца влево или вправо.

Полезные решения для работы с несколькими приложениями

Теперь еще об одной повседневной необходимости – работе с несколькими приложениями одновременно.

Разделение экрана

Первой возможности, о которой хочу напомнить, уже много лет, и в первоначальном виде (под названием Aero Snap) она появилась еще в Windows 7. В Windows 10 ее возможности расширили и назвали Snap Assist. Речь про разделение экрана для закрепления двух (а в Windows 10 – до четырех) приложений.


Snap Assist предлагает выбрать второе окно для закрепления справа

Чтобы это сделать, нужно взять приложение за самую верхнюю полоску, поднести его к правой или левой границе экрана до появления на экране его «тени» и отпустить (тем самым, закрепив первое приложение), а затем в появившихся рядом миниатюрах других приложений выбрать второе для закрепления рядом.  Сценарий несложный, работает и для мыши, и для пальца. Еще проще это можно сделать с помощью сочетания клавиш Windows + клавиши со стрелками вправо/влево. Этому сочетанию уже больше 10 лет, но у тех, кто применяет его впервые, и сейчас порой возникает ощущение «цифровой магии».

Любознательным пользователям также напомню, что в Windows 10 можно отправлять приложение в «четвертинку» экрана, перенеся его в угол (или используя дополнительно клавиши Windows + стрелки вверх/вниз). При закреплении двух приложений можно перемещать границу между ними, выделяя какому-то из приложений больше места. Чтобы выбрать приложения для закрепления на экране, можно кликнуть правой кнопкой мыши по их миниатюрам на экране «Представление задач».

Окно поверх

У меня было довольно мало ситуаций, когда требовалось закреплять окно одного приложения поверх другого (кажется, на телевизорах подобное называлось режимом «картинка в картинке»), но если у вас такая необходимость возникает, напомню в завершение заметки о двух небольших возможностях.

Мини-режим встроенного видеоплеера (приложение «Кино и ТВ», которое воспроизводит видео в Windows 10 по умолчанию). Запустите видео и нажмите на небольшую кнопку в правом нижнем углу (Воспроизвести в мини-режиме), окно с видеороликом будет размещено поверх всех окон.


Видео в режиме Окно поверх

Аналогичную возможность, только с закреплением поверх всех приложений окна браузера, можно получить с использованием отдельных утилит. Однажды мне потребовалось работать над документом, постоянно сверяясь при этом с сайтом одного онлайн-сервиса, и меня выручило приложение Always on Top, доступное в Microsoft Store. Оно встраивается в меню «Поделиться» в Edge и позволяет отправить любой сайт в окно, расположенное поверх всех приложений. Я мог бы пошутить, что этот вариант отлично подошел бы для просмотра каналов на YouTube «одним глазком» во время работы, например, над сводными таблицами в Excel. Но как мы и обсуждали в первой заметке, такая многозадачность скорее повредит и просмотру, и работе.

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

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Сколько из лайфхаков вы использовали?


46.15%
2-3. И они пригождаются
42


9.89%
Ни одного (и теперь это в прошлом)
9


34.07%
Сижу на Linux/MacOS
31

Проголосовал 91 пользователь.

Воздержались 9 пользователей.

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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <atlstr.h>
#include <stdio.h>
#include <string>
#include <synchapi.h>
 
//прототипы функций
 
BOOL ClassReg(HINSTANCE);
LRESULT CALLBACK WndFrameProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK WndChildProc(HWND, UINT, WPARAM, LPARAM);
 
 
enum
{
    IDM_FILE_NEW,
    IDM_FILE_OPEN
};
 
#define ID_FIRST_CHILD 10000
#define SIZE_BUFFER 1 << 20 //1Mb
 
 
LPWSTR Buffer;
HINSTANCE instance;
 
HWND Temp{};
 
HWND ClientWind{};
HWND ChildWind{};
HWND FrameWind{};
LPWSTR FileTitle = new WCHAR[512]{};
HMENU MenuCreate();
 
int CALLBACK wWinMain(HINSTANCE inst, HINSTANCE, PWSTR CmdLine, int nCmdShow)
{
 
    instance = inst;
 
    if (!ClassReg(inst))
 
        return FALSE;
 
    FrameWind = CreateWindowEx(
        WS_EX_ACCEPTFILES, //dwExStyle
        L"FrameClass", //lpClassName
        L"Лабораторная 3", //lpWindowName
        WS_OVERLAPPEDWINDOW, //dwStyle
        CW_USEDEFAULT, //x
        CW_USEDEFAULT, //y
        CW_USEDEFAULT, //nWidth
        CW_USEDEFAULT, //nHeight
        nullptr, //hWndParent
        MenuCreate(), //hMenu
        inst, //hInstance
        nullptr); //lpParam
 
    if (!FrameWind)
    {
        MessageBox((HWND)inst, L"Ошибка создания окна", L"Ошибка", MB_OK | MB_ICONERROR);
        return FALSE;
    }
 
 
    ShowWindow(FrameWind, nCmdShow);
    UpdateWindow(FrameWind);
 
    MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateMDISysAccel(ClientWind, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return msg.wParam;
 
}
BOOL ClassReg(HINSTANCE inst)
{
 
    WNDCLASS wc;
    memset(&wc, 0, sizeof(wc));
    wc.cbClsExtra = 0; //cbClsExtra
    wc.cbWndExtra = 0; //cbWndExtra
    wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1); //hbrBackground
    wc.hCursor = LoadCursor(nullptr, IDC_ARROW); //hCursor
    wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION); //hIcon
    wc.hInstance = inst; //hInstance
    wc.lpfnWndProc = WndFrameProc; //lpfnWndProc
    wc.lpszClassName = L"FrameClass"; //lpszClassName
    wc.lpszMenuName = nullptr; //lpszMenuName
    wc.style = CS_VREDRAW | CS_HREDRAW; //style
 
    if (!RegisterClass(&wc))
        return false;
 
    memset(&wc, 0, sizeof(wc));
    wc.cbClsExtra = 0; //cbClsExtra
    wc.cbWndExtra = DLGWINDOWEXTRA; //cbWndExtra
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); //hbrBackground
    wc.hCursor = LoadCursor(nullptr, IDC_ARROW); //hCursor
    wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION); //hIcon
    wc.hInstance = inst; //hInstance
    wc.lpfnWndProc = WndChildProc; //lpfnWndProc
    wc.lpszClassName = L"ChildClass"; //lpszClassName
    wc.lpszMenuName = nullptr; //lpszMenuName
    wc.style = CS_VREDRAW | CS_HREDRAW; //style
 
    if (!RegisterClass(&wc))
        return false;
 
    return true;
}
 
HMENU MenuCreate()
{
    HMENU mainMenu = CreateMenu(),
        fileSubMenu = CreatePopupMenu(),
        editSubMenu = CreatePopupMenu(),
        windowsSubMenu = CreatePopupMenu();
 
    AppendMenu(fileSubMenu, MF_STRING, IDM_FILE_NEW, L"Создать");
    AppendMenu(fileSubMenu, MF_STRING, IDM_FILE_OPEN, L"Открыть");
 
    AppendMenu(mainMenu, MF_POPUP, (UINT_PTR)fileSubMenu, L"Файл");
    return mainMenu;
}
 
LRESULT CALLBACK WndFrameProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) //Главное окно
{
    CLIENTCREATESTRUCT clcs; // Структура для создания окна Client Window (Родительского для Document WIndow и дочернего для Frame Window)
 
    MDICREATESTRUCT mdics; // Структура для создания дочернего окна Document Window
 
    switch (msg)
    {
    case WM_DESTROY:
    {
        PostQuitMessage(EXIT_SUCCESS);
        break;
    }
    case WM_CREATE:
    {
 
        clcs.hWindowMenu = GetSubMenu(GetMenu(hwnd), 2);
        clcs.idFirstChild = ID_FIRST_CHILD;
 
        ClientWind = CreateWindowEx(
            WS_EX_ACCEPTFILES,
            L"MDICLIENT",
            nullptr,
            WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL,
            0,
            0,
            0,
            0,
            hwnd,
            (HMENU)2,
            instance,
            (LPVOID)&clcs);
 
        if (ClientWind == INVALID_HANDLE_VALUE)
            MessageBox(hwnd, L"Ошибка создания Frame окна", L"Ошибка", MB_OK | MB_ICONERROR);
 
        break;
    }
 
 
    case WM_COMMAND:
    {
        switch (LOWORD(wParam))
        {
 
        case IDM_FILE_NEW:
        {
            //MessageBox(hwnd, L"Ошибка регистрации класса окна", L"Ошибка", MB_OK | MB_ICONERROR)
            mdics.szClass = L"ChildClass";
            mdics.szTitle = L"Новый файл";
            mdics.hOwner = instance;
            mdics.x = CW_USEDEFAULT;
            mdics.y = CW_USEDEFAULT;
            mdics.cx = CW_USEDEFAULT;
            mdics.cy = CW_USEDEFAULT;
            mdics.style = MDIS_ALLCHILDSTYLES | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL;
            mdics.lParam = NULL;
            ChildWind = (HWND)SendMessage(ClientWind, WM_MDICREATE, 0, (LPARAM)&mdics);
            SetWindowTextA(GetWindow(ChildWind, GW_CHILD), (LPCSTR)Buffer);
            break;
 
        }
        case EN_CHANGE:
        {
            MessageBox(hwnd, L"Изменение", L"ok", MB_OK | MB_ICONERROR);
            break;
        }
 
 
        }
        break;
    }
    default:
        return DefFrameProc(hwnd, ClientWind, msg, wParam, lParam);
    }
    return 0;
 
}
 
BOOL test = true;
 
LRESULT CALLBACK WndChildProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    HWND hChildEdit{};
    switch (msg)
    {
    case WM_DESTROY:
    {
 
        break;
    }
    case WM_CREATE:
    {
 
        RECT rect;
        GetClientRect(hwnd, &rect);
        hChildEdit = CreateWindow(
            L"EDIT",
            NULL,
            WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE,
            0,
            0,
            rect.right,
            rect.bottom,
            hwnd,
            NULL,
            instance,
            NULL);
 
        if (hChildEdit == INVALID_HANDLE_VALUE)
            MessageBox(hwnd, L"Ошибка создания дочернего окна", L"Ошибка", MB_OK | MB_ICONERROR);
        break;
    }
    case WM_SETFOCUS:
    {
        ChildWind = hwnd;
        break;
    }
 
    case WM_COMMAND:
    {
    case EN_CHANGE:
    {
 
 
        Buffer = (LPWSTR)GetWindowLongPtr(ChildWind, GWLP_WNDPROC);
 
        //SetWindowLongPtr(ChildWind, GWLP_WNDPROC, (LONG_PTR)Buffer);
 
        //SetWindowText(GetWindow(ChildWind, GW_CHILD), (LPCWSTR)Buffer);
 
        /*for (;;)
        {
            // Получаем идентификатор дочернего окна
            // для окна Client Window
            Temp = GetWindow(ClientWind, GW_CHILD);
            // Если дочерних окон больше нет, выходим из цикла
            if (!Temp)
                break;
 
            // Пропускаем окна-заголовки
            while (Temp && GetWindow(Temp, GW_OWNER))
                Temp = GetWindow(Temp, GW_HWNDNEXT);
 
            // Удаляем дочернее окно Document Window
            if (Temp)
                SetWindowTextA(GetWindow(ChildWind, GW_CHILD), (LPCSTR)Buffer);
            else
                break;
        }*/
 
 
        /*MessageBox(hwnd, L"Ошибка регистрации класса окна", L"Ошибка", MB_OK | MB_ICONERROR);
        int Size= GetWindowTextW(ChildWind, Buffer, 100);
 
 
        Buffer=(LPWSTR)GetWindowLongPtr(GetWindow(ChildWind, GW_CHILD), GWLP_USERDATA);
 
        MessageBox(hwnd, (LPCWSTR)Size, L"Ошибка", MB_OK | MB_ICONERROR);
        LPSTR TextWindow{};
        LPSTR Buffer = TextWindow; //заполнение буфера содержимым
        if (Buffer != nullptr) //Если буфер не пустой
        {
            //MessageBox(hwnd, L"Ошибка регистрации класса окна", L"Ошибка", MB_OK | MB_ICONERROR);
            //mdics.szTitle = FileTitle; //задаём заголовок
            //ChildWind = (HWND)SendMessage(ClientWind, WM_MDICREATE, 0, (LPARAM)&mdics);
            SetWindowTextA(GetWindow(ChildWind, GW_CHILD), (LPCSTR)Buffer);
            delete Buffer;
 
        }*/
 
        break;
    }
    break;
    }
 
    case WM_SIZE: //изменение размеров рабочей области дочернего окна
    {
        hChildEdit = GetWindow(hwnd, GW_CHILD);
        if (!SetWindowPos(hChildEdit, nullptr, 0, 0, LOWORD(lParam), HIWORD(lParam), SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER)) //если не получилось изменить размер окна
            MessageBox(hwnd, L"Ошибка изменения размера окна окна", L"Ошибка", MB_OK | MB_ICONERROR);
        break;
    }
    default:
        break;
 
    }
    return DefMDIChildProc(hwnd, msg, wParam, lParam);
 
}

Понравилась статья? Поделить с друзьями:
  • Оптимизация windows 10 pro для слабых ноутбуков
  • Оптимизация одним кликом для windows 10 скачать
  • Организация консоли администрирования в ос windows xp
  • Оптимизация windows 10 ltsc для игр
  • Оптимизация ноутбука windows 10 для игр программы