Так уж повелось, что утилиты командной строки стали частыми гостями нашей рубрики «RTFM». Нельзя сказать, что это случайность, скорее, закономерность. Ведь консольные программы при своем действительно миниатюрном размере предоставляют пользователю куда большую гибкость в работе, нежели оснащенные цветастым графическим интерфейсом исполины. Это, во-первых.
Во-вторых, ничто не мешает использовать их в составе CMD- или BAT-файлов, конструируя, тем самым, целые программные комплексы, настроенные на решение тех или иных, порой весьма нетривиальных задач. Наконец, в-третьих, в большинстве случаев они бесплатны, не требуют инсталляции, состоят из одного исполняемого файла и легко поддаются автоматизации при помощи любого планировщика задач Windows. Надеемся, приведенных критериев достаточно, чтобы без лишних слов приступить к обзору очередного приложения, не ускользнувшего от нашего пристального внимания.
Знакомьтесь, Cmdow — консольная утилита размером в 31 кб, включающая порядка 30 команд управления окнами приложений в операционных системах Windows NT4/2000/XP/2003 без использования мыши. Программа не требует установки и состоит всего из одного файла cmdow.exe, опции запуска которого разработчик разделил на четыре группы, в зависимости от области применения приложения. Рассмотрим их как можно более сжато.
Как удалить список загрузки Windows при включении
1. Получение информации об окнах запущенных в системе программ
Формат команды: cmdow.exe [window | /T] [/B] [/F] [/P], где
- window — название окна или его идентификатор (дескриптор) в шестнадцатеричном формате. Если в имени есть пробел или фигурируют какие-либо управляющие символы, используются кавычки, например, «untitled — notepad». В случае отсутствия этой опции, Cmdow отобразит список всех окон, включая их составляющие элементы — кнопки, поля ввода и прочее (см. наглядный пример использования данной функции в конце материала)
- /T — ключ, заставляющий утилиту работать только с программами, присутствующими в панели задач Windows
- /B — наличие этой опции отключает отображение заголовков столбцов в выводимом листинге
- /F — вывод наиболее полной информации об окнах
- /P — отображение размеров окон и их координат на рабочем столе
Результатом использования cmdow.exe будет листинг, содержащий следующие восемь полей (см. скриншот):
- Handle — шестнадцатеричный дескриптор окна
- Lev — уровень окна Windows
- Pid — идентификатор процесса, породившего данное окно
- Window status — статус окна (активное, минимизированное, скрытое, развернутое и т.п.)
- Left, Top — координаты окна (выводятся только в случае использования ключей /F и /P)
- Width, Height — размер окна в пикселях (выводятся только в случае использования опций /F и /P)
- Image — название процесса, породившего данное окно
- Caption — название окна
Еще раз напомним, что просматривать результаты гораздо удобнее, если не выводить их на дисплей, а перенаправлять в текстовый файл инструкцией «> название файла». Например, команда cmdow.exe /T > info.txt выведет полученную утилитой информацию об окнах программ из панели задач в файл info.txt.
Как изменить цвет выделения в Windows
2. Выполнение групповых операций с окнами
Формат команды: cmdow.exe /TH | /TV | /CW | /MA | /UW | /AT | /FS | /WM, где
- /TH — меняет расположение окон на рабочем столе и расставляет их друг под другом сверху вниз. Эта инструкция полностью эквивалентна команде Tile Windows Horizontally контекстного меню панели задач
- /TV — аналогична предыдущей инструкции, только меняет расположение окон слева направо
- /CW — располагает окна каскадом и является подобием команды Cascade Windows контекстного меню панели задач
- /MA — сворачивает все открытые окна в панель задач
- /UW — восстанавливает прежний вид окон (тот же эффект достигается нажатием клавишной комбинации Win+Shift+M)
- /AT — переключает окна в порядке их расположения в панели задач
- /FS — переводит приложение в полноэкранный режим работы (аналог нажатия Alt+Enter на клавиатуре)
- /WM — отключает полноэкранный режим
3. Манипулирование отдельным окном
- Window — уже упомянутый нами ранее дескриптор окна, с которым утилита Cmdow будет производить различные действия в зависимости от указанных в команде ключей
- /ACT — делает активным заданное окно (выводит на передний план)
- /INA — деактивирует выбранное окно (смещает фокус на другое приложение)
- /DIS — делает выбранное окно невосприимчивым к действиям пользователя (само приложение при этом продолжает работать)
- /ENA — отключает предыдущую функцию и делает окно доступным для управления мышью
- /HID — прячет окно
- /VIS — делает ранее спрятанное окно вновь видимым
- /MIN — сворачивает окно в панель задач. Естественно, данная опция не всесильна, например, использовать ее для диалоговых окон тщетно
- /MAX — разворачивает окно на весь экран
- /TOP — располагает окно поверх остальных
- /NOT — снимает атрибут «Поверх всех окон» с указанного окна программы
- /REN caption — используется для переименования выбранного окна
- /MOV left top — перемещает окно в соответствии с новыми координатами
- /SIZ width height — изменяет размеры окна
- /CLS — закрывает окно (действие команды аналогично нажатию пользователем кнопки «Закрыть», присутствующей на любом окне Windows)
- /END — убивает процесс, ассоциированный с указанным окном. Последствия от данного ключа могут быть самыми разными, поэтому применять его следует очень осторожно
4. Запуск приложений при помощи Cmdow
Формат команды: cmdow.exe /RUN [state] file [args], где
- /RUN — обязательная опция, переключающая утилиту в режим запуска выбранных приложений
- state — параметры окна загружаемого приложения. Могут использоваться ключи /MIN, /MAX и /HID
- file — путь к файлу на диске для запуска
- args — аргументы, передаваемые загружаемой программе
Примеры использования Cmdow
Теперь, когда теория позади, самое время заняться практикой и рассмотреть несколько примеров, демонстрирующих использование утилиты Cmdow.
Например, нам необходимо просмотреть список ключей, воспринимаемых программой. Проще говоря, нам нужна справка к Cmdow. Делается это так:
В случае если наш интерес ограничивается приложениями, присутствующими в панели задач Windows, и мы хотим узнать про них всю системную подноготную, тогда используем команду:
cmdow.exe /T /F
Следующая инструкция выведет данные о только что открытом «Блокноте» и запишет их в файл notepad.txt:
cmdow.exe «untitled — notepad» > notepad.txt
Эта команда расположит все окна на рабочем столе горизонтально друг под другом:
cmdow.exe /TH
А эта переименует калькулятор в Computerra:
cmdow.exe calculator /REN Computerra
Следующий код заставит утилиту открыть развернутый на весь экран браузер Internet Explorer и загрузит в нем страницу «Компьютерры-Онлайн»:
cmdow.exe /RUN /MAX iexplore www.computerra.ru
Любителям CMD-инструкций приводим на затравку два листинга. Первый переключает каждые пять секунд окна:
Второй код, более интересный, загрузит калькулятор Windows и последовательно удалит из него все кнопки.
Выглядеть это действо будет таким вот образом:
Источник: old.computerra.ru
Записки IT специалиста
Админу на заметку — 14. Как вывести информацию о системе на рабочий стол
Любой администратор, которому приходится работать сразу с несколькими однотипными серверами знает сколько порою времени уходит на то, чтобы определить на каком именно из серверов он сейчас находится и какие у него базовые настройки. И вопрос это далеко не праздный, ошибочно выполненное не на том сервере действие может иметь самые разнообразные последствия, иной раз очень неприятные. В тоже время каждый, наверное, видел системы, где такая информация отображается прямо на рабочем столе. Сегодня мы расскажем, как это сделать.
Научиться настраивать MikroTik с нуля или систематизировать уже имеющиеся знания можно на углубленном курсе по администрированию MikroTik. Автор курса, сертифицированный тренер MikroTik Дмитрий Скоромнов, лично проверяет лабораторные работы и контролирует прогресс каждого своего студента. В три раза больше информации, чем в вендорской программе MTCNA, более 20 часов практики и доступ навсегда.
В этот раз, вопреки традиции, начнем с конца, с того результата, который вы должны получить.
![]()
Удобно? Безусловно. Беглого взгляда на рабочий стол достаточно, чтобы понять где вы находитесь, какие сетевые настройки этого хоста и его основные аппаратные характеристики.
Как это сделать? Совершенно несложно, достаточно воспользоваться утилитой BgInfo от Sysinternals. Эта небольшая программа от Марка Руссиновича считывает всю необходимую информацию и выводит ее прямо на обоях рабочего стола. Т.е. достаточно запустить ее один раз и вся необходимая информация будет у вас перед глазами пока вы не смените обои.
Но будет гораздо лучше, если данные будут с определенной периодичностью обновляться, тем более что утилита позволяет выводить некоторые текущие параметры, такие как свободное место на дисках.
Прежде всего скачаем утилиту и разместим ее в удобном месте, например, в папке профиля пользователя, если пользоваться ей планируете вы лично. При запуске, если не было выполнено никаких действий, то программа через 9 секунд закроется, сформировав новые обои рабочего стола в соответствии с настройками. А настроек довольно много:

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

Нажав кнопку Preview можно посмотреть, что у нас получилось вживую, а нажав Apply — применить настройки. Затем сохраним их в конфигурационный файл чтобы их можно было применять впоследствии, для этого выберите File — Save as. Файл настроек с расширением bgi сохраните в одном каталоге с утилитой.
Теперь подумаем, как оперативно обновлять информацию. Самый простой способ — добавить утилиту в автозагрузку. Для этого создайте в том же каталоге пакетный файл bginfо.bat со следующим содержимым:
bginfo.exe interface31.bgi /timer:0 /NOLICPROMPT
Синтаксис записи прост, первым параметром передается файл конфигурации, в нашем случае interface31.bgi, затем опция timer, которая имеет значение 0, что позволяет утилите выполнять свою работу и не ожидать 9 секунд, опция NOLICPROMPT подавляет появление лицензионного соглашения. Полный список опций можно получить тут-же в разделе Help — Command line option:

Затем ярлык на данный пакетный файл следует поместить в автозагрузку, если вы хотите поместить туда не ярлык, а сам файл, то пути к утилите и файлу конфигурации потребуется изменить на абсолютные.
Однако автозагрузка — это не самый лучший вариант, сервера перезагружаются редко, поэтому самое время вспомнить о планировщике задач. Начиная с Windows Vista / Server 2008 это весьма гибкий и мощный инструмент, позволяющий решать самые разнообразные задачи.
Запустим планировщик и создадим простую задачу, рекомендуем давать задачам понятные имена и писать хотя бы пару строк в описание, чтобы потом вам и вашим коллегам было понятно, что делает та или иная задача.
![]()
Когда мы хотим обновлять информацию? Прежде всего при входе в систему, поэтому первый триггер выбираем именно таким, расписание добавим позже.
![]()
В качестве действия ставим запуск программы.
![]()
Проще всего, конечно, добавить в планировщик запуск уже созданного bat-файла, но этот метод имеет один существенный недостаток — на экране будет проскакивать окно командного интерпретатора, что весьма неудобно. К счастью, планировщик обладает широкими возможностями настройки запуска, чем мы и воспользуемся.
![]()
В поле Программа или сценарий добавляем саму утилиту bginfo.exe, аргументы и опции запуска добавляем в одноименное поле ниже, а именно строку:
interface31.bgi /timer:0 /NOLICPROMPT
Еще ниже обязательно задаем рабочую папку, это директория где физически располагается утилита и файл конфигурации к ней. На этом создание задачи заканчиваем и сразу переходим к ее свойствам, где на закладке Триггеры создаем еще один триггер.
![]()
Условия триггера просты: выполнять задачу ежедневно, каждый день, повторяя каждый час в течении бесконечного срока. Это условие, в сочетании с предыдущим триггером, будет обновлять информацию каждый час и при входе администратора в систему. Вы можете настроить условия согласно собственным предпочтениям.
После чего выбираем задачу и жмем кнопку Выполнить, чтобы проверить ее работу. Если все сделано правильно — информация на рабочем столе обновится.
![]()
Надеемся, что эта небольшая утилита позволит вам лучше организовать рабочее пространство и реже отвлекаться на мелочи, сосредоточив свое внимание на более важных задачах.
Научиться настраивать MikroTik с нуля или систематизировать уже имеющиеся знания можно на углубленном курсе по администрированию MikroTik. Автор курса, сертифицированный тренер MikroTik Дмитрий Скоромнов, лично проверяет лабораторные работы и контролирует прогресс каждого своего студента. В три раза больше информации, чем в вендорской программе MTCNA, более 20 часов практики и доступ навсегда.
Источник: interface31.ru
Использование диалоговых окон
Диалоговые окна используются для отображения сведений и запроса ввода данных от пользователя. Приложение загружает и инициализирует диалоговое окно, обрабатывает введенные пользователем данные и уничтожает диалоговое окно, когда пользователь завершает задачу. Процесс обработки диалоговых окон зависит от того, является ли диалоговое окно модальным или немодальным.
Модальное диалоговое окно требует, чтобы пользователь закрыл диалоговое окно перед активацией другого окна в приложении. Однако пользователь может активировать окна в разных приложениях. Диалоговое окно без режима не требует немедленного ответа от пользователя. Это похоже на главное окно, содержащее элементы управления.
В следующих разделах описывается использование обоих типов диалоговых окон.
- Отображение окна сообщения
- Создание модального диалогового окна
- Создание бессерверного диалогового окна
- Инициализация диалогового окна
- Создание шаблона в памяти
Отображение окна сообщения
Простейшая форма модального диалогового окна — это окно сообщения. Большинство приложений используют окна сообщений, чтобы предупреждать пользователя об ошибках и запрашивать указания о том, как продолжить работу после возникновения ошибки. Вы создаете окно сообщения с помощью функции MessageBox или MessageBoxEx , указывая сообщение и число и тип отображаемых кнопок. Система создает модальное диалоговое окно, предоставляя собственный шаблон диалогового окна и процедуру. Когда пользователь закроет окно сообщения, MessageBox или MessageBoxEx возвращает значение, определяющее кнопку, выбранную пользователем для закрытия окна сообщения.
В следующем примере приложение отображает окно сообщения, которое запрашивает у пользователя действие после возникновения условия ошибки. В окне сообщения отображается сообщение, описывающее условие ошибки и способ ее устранения. Стиль MB_YESNO направляет MessageBox на две кнопки, с помощью которых пользователь может выбрать, как продолжить:
int DisplayConfirmSaveAsMessageBox() < int msgboxID = MessageBox( NULL, L»temp.txt already exists.nDo you want to replace it?», L»Confirm Save As», MB_ICONEXCLAMATION | MB_YESNO ); if (msgboxID == IDYES) < // TODO: add code >return msgboxID; >
На следующем рисунке показаны выходные данные из предыдущего примера кода:

Создание модального диалогового окна
Модальное диалоговое окно создается с помощью функции DialogBox . Необходимо указать идентификатор или имя ресурса шаблона диалогового окна и указатель на процедуру диалогового окна. Функция DialogBox загружает шаблон, отображает диалоговое окно и обрабатывает все введенные пользователем данные, пока пользователь не закроет диалоговое окно.
В следующем примере приложение отображает модальное диалоговое окно, когда пользователь нажимает кнопку «Удалить элемент » из меню приложения. Диалоговое окно содержит элемент управления редактированием (в котором пользователь вводит имя элемента) и кнопки «ОК » и » Отмена «. Идентификаторы элементов управления для этих элементов управления — ID_ITEMNAME, IDOK и IDCANCEL соответственно.
Первая часть примера состоит из инструкций, создающих модальное диалоговое окно. Эти инструкции в процедуре окна для главного окна приложения создают диалоговое окно, когда система получает сообщение WM_COMMAND с идентификатором меню IDM_DELETEITEM. Вторая часть примера — это процедура диалогового окна, которая извлекает содержимое элемента управления редактированием и закрывает диалоговое окно после получения сообщения WM_COMMAND .
Следующие инструкции создают модальное диалоговое окно. Шаблон диалогового окна является ресурсом в исполняемом файле приложения и содержит идентификатор ресурса DLG_DELETEITEM.
case WM_COMMAND: switch (LOWORD(wParam)) < case IDM_DELETEITEM: if (DialogBox(hinst, MAKEINTRESOURCE(DLG_DELETEITEM), hwnd, (DLGPROC)DeleteItemProc)==IDOK) < // Complete the command; szItemName contains the // name of the item to delete. >else < // Cancel the command. >break; > return 0L;
В этом примере приложение указывает его главное окно в качестве окна владельца диалогового окна. Когда система изначально отображает диалоговое окно, его положение относительно верхнего левого угла клиентской области окна владельца. Приложение использует возвращаемое значение из DialogBox , чтобы определить, следует ли продолжить операцию или отменить ее. Следующие инструкции определяют процедуру диалогового окна.
char szItemName[80]; // receives name of item to delete. BOOL CALLBACK DeleteItemProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) < switch (message) < case WM_COMMAND: switch (LOWORD(wParam)) < case IDOK: if (!GetDlgItemText(hwndDlg, ID_ITEMNAME, szItemName, 80)) *szItemName=0; // Fall through. case IDCANCEL: EndDialog(hwndDlg, wParam); return TRUE; >> return FALSE; >
В этом примере процедура использует GetDlgItemText для извлечения текущего текста из элемента управления редактирования, определяемого ID_ITEMNAME. Затем процедура вызывает функцию EndDialog , чтобы задать возвращаемое значение диалогового окна как IDOK, так и IDCANCEL в зависимости от полученного сообщения и начала процесса закрытия диалогового окна. Идентификаторы IDOK и IDCANCEL соответствуют кнопкам «ОК » и » Отмена «. После того как процедура вызывает EndDialog, система отправляет дополнительные сообщения в процедуру для уничтожения диалогового окна и возвращает возвращаемое значение диалогового окна обратно в функцию, которая создала диалоговое окно.
Создание бессерверного диалогового окна
Диалоговое окно без режима создается с помощью функции CreateDialog , указывая идентификатор или имя ресурса шаблона диалогового окна и указатель на процедуру диалогового окна. CreateDialog загружает шаблон, создает диалоговое окно и при необходимости отображает его. Ваше приложение отвечает за получение и отправку сообщений, введенных пользователем, в процедуру диалогового окна.
В следующем примере приложение отображает бессерверное диалоговое окно ( если оно еще не отображается), когда пользователь нажимает кнопку «Перейти» из меню приложения. Диалоговое окно содержит элемент управления редактированием, флажок и кнопки «ОК » и » Отмена «. Шаблон диалогового окна — это ресурс в исполняемом файле приложения и имеет идентификатор ресурса DLG_GOTO. Пользователь вводит номер строки в элементе управления редактированием и проверяет флажок, чтобы указать, что номер строки относительно текущей строки. Идентификаторы элементов управления : ID_LINE, ID_ABSREL, IDOK и IDCANCEL.
Операторы в первой части примера создают диалоговое окно без режима. Эти инструкции в процедуре окна для главного окна приложения создают диалоговое окно, когда процедура окна получает сообщение WM_COMMAND с идентификатором меню IDM_GOTO, но только если глобальная переменная еще не содержит допустимый дескриптор. Вторая часть примера — это основной цикл сообщений приложения. Цикл включает функцию IsDialogMessage , чтобы убедиться, что пользователь может использовать интерфейс клавиатуры диалогового окна в этом бессерверном диалоговом окне. Третья часть примера — это процедура диалогового окна. Процедура извлекает содержимое элемента управления редактирования и флажок, когда пользователь нажимает кнопку «ОК «. Процедура уничтожает диалоговое окно, когда пользователь нажимает кнопку «Отмена «.
HWND hwndGoto = NULL; // Window handle of dialog box . case WM_COMMAND: switch (LOWORD(wParam)) < case IDM_GOTO: if (!IsWindow(hwndGoto)) < hwndGoto = CreateDialog(hinst, MAKEINTRESOURCE(DLG_GOTO), hwnd, (DLGPROC)GoToProc); ShowWindow(hwndGoto, SW_SHOW); >break; > return 0L;
В предыдущих инструкциях CreateDialog вызывается, только если hwndGoto не содержит допустимый дескриптор окна. Это гарантирует, что приложение одновременно не отображает два диалоговых окна. Для поддержки этого метода проверки процедура диалога должна иметь значение NULL при уничтожении диалогового окна.
Цикл сообщений для приложения состоит из следующих инструкций.
BOOL bRet; while ((bRet = GetMessage( if (bRet == -1) < // Handle the error and possibly exit >else if (!IsWindow(hwndGoto) || !IsDialogMessage(hwndGoto, TranslateMessage( DispatchMessage( >>
Цикл проверяет допустимость дескриптора окна в диалоговом окне и вызывает функцию IsDialogMessage , только если дескриптор действителен. IsDialogMessage обрабатывает сообщение только в том случае, если оно принадлежит диалоговому оккуму. В противном случае возвращается значение FALSE , а цикл отправляет сообщение в соответствующее окно.
Следующие инструкции определяют процедуру диалогового окна.
int iLine; // Receives line number. BOOL fRelative; // Receives check box status. BOOL CALLBACK GoToProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) < BOOL fError; switch (message) < case WM_INITDIALOG: CheckDlgButton(hwndDlg, ID_ABSREL, fRelative); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) < case IDOK: fRelative = IsDlgButtonChecked(hwndDlg, ID_ABSREL); iLine = GetDlgItemInt(hwndDlg, ID_LINE, if (fError) < MessageBox(hwndDlg, SZINVALIDNUMBER, SZGOTOERR, MB_OK); SendDlgItemMessage(hwndDlg, ID_LINE, EM_SETSEL, 0, -1L); >else // Notify the owner window to carry out the task. return TRUE; case IDCANCEL: DestroyWindow(hwndDlg); hwndGoto = NULL; return TRUE; > > return FALSE; >
В предыдущих инструкциях процедура обрабатывает сообщения WM_INITDIALOG и WM_COMMAND . Во время обработки WM_INITDIALOG процедура инициализирует флажок, передав текущее значение глобальной переменной в CheckDlgButton. Затем процедура возвращает значение TRUE , чтобы направить систему на настройку фокуса ввода по умолчанию.
При обработке WM_COMMAND процедура закрывает диалоговое окно только в том случае, если пользователь нажимает кнопку «Отмена «, то есть кнопку с идентификатором IDCANCEL. Процедура должна вызвать DestroyWindow , чтобы закрыть диалоговое окно без режима. Обратите внимание, что процедура также устанавливает для переменной значение NULL , чтобы другие инструкции, зависящие от этой переменной, работали правильно.
Если пользователь нажимает кнопку «ОК «, процедура извлекает текущее состояние флажка и назначает ее переменной fRelative . Затем она использует переменную для получения номера строки из элемента управления редактирования. GetDlgItemInt преобразует текст в элементе управления редактированием в целое число.
Значение fRelative определяет, интерпретирует ли функция число как подписанное или неподписаемое значение. Если текст элемента управления редактированием не является допустимым числом, Метод GetDlgItemInt задает для переменной fError значение nonzero. Процедура проверяет это значение, чтобы определить, следует ли отображать сообщение об ошибке или выполнять задачу. В случае ошибки процедура диалогового окна отправляет сообщение в элемент управления редактирования, направляя его на выделение текста в элементе управления, чтобы пользователь смог легко заменить его. Если Метод GetDlgItemInt не возвращает ошибку, процедура может выполнить запрошенную задачу или отправить сообщение в окно владельца, направив его для выполнения операции.
Инициализация диалогового окна
Диалоговое окно и его содержимое инициализируются при обработке сообщения WM_INITDIALOG . Наиболее распространенной задачей является инициализация элементов управления для отражения текущих параметров диалогового окна. Еще одной распространенной задачей является центр диалогового окна на экране или в окне владельца. Полезной задачей для некоторых диалоговых окон является установка фокуса ввода на указанный элемент управления, а не принятие фокуса ввода по умолчанию.
В следующем примере процедура диалогового окна центрируется с диалоговым окном и задает фокус ввода при обработке сообщения WM_INITDIALOG . Чтобы вывести диалоговое окно по центру, процедура извлекает прямоугольники окна для диалогового окна и окна владельца и вычисляет новую позицию для диалогового окна. Чтобы задать фокус ввода, процедура проверяет параметр wParam , чтобы определить идентификатор фокуса ввода по умолчанию.
HWND hwndOwner; RECT rc, rcDlg, rcOwner; . case WM_INITDIALOG: // Get the owner window and dialog box rectangles. if ((hwndOwner = GetParent(hwndDlg)) == NULL) < hwndOwner = GetDesktopWindow(); >GetWindowRect(hwndOwner, GetWindowRect(hwndDlg, CopyRect(rcOwner); // Offset the owner and dialog box rectangles so that right and bottom // values represent the width and height, and then offset the owner again // to discard space taken up by the dialog box. OffsetRect( OffsetRect( OffsetRect( // The new position is the sum of half the remaining space and the owner’s // original position.
SetWindowPos(hwndDlg, HWND_TOP, rcOwner.left + (rc.right / 2), rcOwner.top + (rc.bottom / 2), 0, 0, // Ignores size arguments. SWP_NOSIZE); if (GetDlgCtrlID((HWND) wParam) != ID_ITEMNAME) < SetFocus(GetDlgItem(hwndDlg, ID_ITEMNAME)); return FALSE; >return TRUE;
В приведенных выше инструкциях процедура использует функцию GetParent для получения дескриптора окна владельца в диалоговом окне.
Функция возвращает дескриптор окна владельца в диалоговые окна, а родительский дескриптор окна — дочерним окнам. Так как приложение может создать диалоговое окно без владельца, процедура проверяет возвращенный дескриптор и при необходимости использует функцию GetDesktopWindow для получения дескриптора окна рабочего стола. После вычисления новой позиции процедура использует функцию SetWindowPos для перемещения диалогового окна, указав значение HWND_TOP, чтобы убедиться, что диалоговое окно остается в верхней части окна владельца.
Перед установкой фокуса ввода процедура проверяет идентификатор элемента управления для фокуса ввода по умолчанию. Система передает дескриптор окна для фокуса ввода по умолчанию в параметре wParam . Функция GetDlgCtrlID возвращает идентификатор элемента управления, определяемого дескриптором окна. Если идентификатор не соответствует правильному идентификатору, процедура использует функцию SetFocus для задания фокуса ввода. Функция GetDlgItem требуется для получения дескриптора окна нужного элемента управления.
Создание шаблона в памяти
Приложения иногда адаптируют или изменяют содержимое диалоговых окон в зависимости от текущего состояния обрабатываемых данных. В таких случаях нецелесообразно предоставлять все возможные шаблоны диалоговых окон как ресурсы в исполняемом файле приложения. Но создание шаблонов в памяти дает приложению большую гибкость в адаптации к любым обстоятельствам.
В следующем примере приложение создает шаблон в памяти для модального диалогового окна, содержащего сообщение и кнопки «ОК » и «Справка «.
В шаблоне диалогового окна все символьные строки, такие как диалоговое окно и заголовки кнопок, должны быть строками Юникода. В этом примере функция MultiByteToWideChar используется для создания этих строк Юникода.
Структуры DLGITEMTEMPLATE в шаблоне диалога должны быть выровнены по границам DWORD . Для выравнивания этих структур в этом примере используется вспомогающая подпрограмма, которая принимает указатель ввода и возвращает ближайший указатель, выровненный по границе DWORD .
#define ID_HELP 150 #define ID_TEXT 200 LPWORD lpwAlign(LPWORD lpIn) < ULONG ul; ul = (ULONG)lpIn; ul ++; ul >>=1; ul LRESULT DisplayMyMessage(HINSTANCE hinst, HWND hwndOwner, LPSTR lpszMessage) < HGLOBAL hgbl; LPDLGTEMPLATE lpdt; LPDLGITEMTEMPLATE lpdit; LPWORD lpw; LPWSTR lpwsz; LRESULT ret; int nchar; hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024); if (!hgbl) return -1; lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl); // Define a dialog box. lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION; lpdt->cdit = 3; // Number of controls lpdt->x = 10; lpdt->y = 10; lpdt->cx = 100; lpdt->cy = 100; lpw = (LPWORD)(lpdt + 1); *lpw++ = 0; // No menu *lpw++ = 0; // Predefined dialog box class (by default) lpwsz = (LPWSTR)lpw; nchar = 1 + MultiByteToWideChar(CP_ACP, 0, «My Dialog», -1, lpwsz, 50); lpw += nchar; //———————— // Define an OK button. //———————— lpw = lpwAlign(lpw); // Align DLGITEMTEMPLATE on DWORD boundary lpdit = (LPDLGITEMTEMPLATE)lpw; lpdit->x = 10; lpdit->y = 70; lpdit->cx = 80; lpdit->cy = 20; lpdit->id = IDOK; // OK button identifier lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; lpw = (LPWORD)(lpdit + 1); *lpw++ = 0xFFFF; *lpw++ = 0x0080; // Button class lpwsz = (LPWSTR)lpw; nchar = 1 + MultiByteToWideChar(CP_ACP, 0, «OK», -1, lpwsz, 50); lpw += nchar; *lpw++ = 0; // No creation data //———————— // Define a Help button. //———————— lpw = lpwAlign(lpw); // Align DLGITEMTEMPLATE on DWORD boundary lpdit = (LPDLGITEMTEMPLATE)lpw; lpdit->x = 55; lpdit->y = 10; lpdit->cx = 40; lpdit->cy = 20; lpdit->id = ID_HELP; // Help button identifier lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON; lpw = (LPWORD)(lpdit + 1); *lpw++ = 0xFFFF; *lpw++ = 0x0080; // Button class atom lpwsz = (LPWSTR)lpw; nchar = 1 + MultiByteToWideChar(CP_ACP, 0, «Help», -1, lpwsz, 50); lpw += nchar; *lpw++ = 0; // No creation data //———————— // Define a static text control. //———————— lpw = lpwAlign(lpw); // Align DLGITEMTEMPLATE on DWORD boundary lpdit = (LPDLGITEMTEMPLATE)lpw; lpdit->x = 10; lpdit->y = 10; lpdit->cx = 40; lpdit->cy = 20; lpdit->id = ID_TEXT; // Text identifier lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT; lpw = (LPWORD)(lpdit + 1); *lpw++ = 0xFFFF; *lpw++ = 0x0082; // Static class for (lpwsz = (LPWSTR)lpw; *lpwsz++ = (WCHAR)*lpszMessage++;); lpw = (LPWORD)lpwsz; *lpw++ = 0; // No creation data GlobalUnlock(hgbl); ret = DialogBoxIndirect(hinst, (LPDLGTEMPLATE)hgbl, hwndOwner, (DLGPROC)DialogProc); GlobalFree(hgbl); return ret; >
Источник: learn.microsoft.com