Лекция
Многооконный интерфейс
В настоящее время любые программы,
работающие с документами, позволяют
одновременно открывать два, три и более
файлов. Естественно предположить, что
операционная система должна как-то
поддерживать эту возможность и
предоставлять программам специальные
функции 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); } |