Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.145.108.9] |
|
Сообщ.
#1
,
|
|
|
Поле прочтения темы GUI для консольной программы на C++ (Visual Studio 2010) решил попробовать создать приложение с помощью конструктора диалогов Visual C++ 2010:
#include <string> #include <iostream> #include <windows.h> #include "resource.h" #include <stdio.h> BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { return FALSE; } case WM_COMMAND: { switch (LOWORD(wParam)) { case ID_OK: EndDialog(hwnd,1); return TRUE; case ID_CANCEL: EndDialog(hwnd,0); return TRUE; } } case WM_CLOSE: { EndDialog(hwnd,0); return FALSE; } } return FALSE; } 1. Как сделать так, чтобы диалог: - размещался в центре экрана; - разворачивался на весь экран, при этом кнопки были бы в правом нижнем углу 2. В большинстве книг по WinAPI описано создание класса окна в памяти с последующим созданием экземпляра класса, а не с помощью конструктора диалогов. Посоветуйте, пожалуйста, книгу или статьи с подробным описанием возможности создания программ с использованием конструктора диалогов (вызов из одного диалога другого, настройка вида диалогов в процессе работы программы, примеры диалогов с разными контролами, создание событий для контролов и др.). Проект прикрепил. Прикреплённый файлWin32dialog.zip (3,63 Кбайт, скачиваний: 143) |
Сообщ.
#2
,
|
|
|
Цитата tumanovalex @ - размещался в центре экрана DS_CENTER Цитата tumanovalex @ - разворачивался на весь экран, при этом кнопки были бы в правом нижнем углу Ручками, в обработчиках POSCHANGE/SIZE. |
Сообщ.
#3
,
|
|
|
У меня основная функция имеет вид (забыл ее указать в первом сообщении:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int ret = DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DlgProc); if (ret == 0) { MessageBox(NULL, "Нажата кнопка \"Отмена\"","Информация о нажатой кнопке", MB_OK|MB_ICONINFORMATION); } else { MessageBox(NULL, "Нажата кнопка \"ОК\"","Информация о нажатой кнопке", MB_OK|MB_ICONINFORMATION); } return ret; } |
Сообщ.
#4
,
|
|
|
Цитата tumanovalex @ А как указать, что это окно должно размещаться по центру? В редакторе ресурсов, в режиме конструктора диалогов -- свойство "Position -> Center" |
Сообщ.
#5
,
|
|
|
Спасибо, получилось. Теперь буду разбираться с POSCHANGE/SIZE.
|
Сообщ.
#6
,
|
|
|
У меня диалоговое окно будет содержать много контролов, поэтому хотелось бы сразу развернуть его на весь экран, а потом уже подбирать расположение контролов на развернутом экране. Подскажите, пожалуйста, как диалог из ресурса сразу развернуть на весь экран.
|
Сообщ.
#7
,
|
|
|
Цитата tumanovalex @ У меня диалоговое окно будет содержать много контролов, поэтому хотелось бы сразу развернуть его на весь экран, а потом уже подбирать расположение контролов на развернутом экране. Подскажите, пожалуйста, как диалог из ресурса сразу развернуть на весь экран. извращенец MFC в зубы и с песней! |
Сообщ.
#8
,
|
|
|
Да не хочу я MFC!!! Хочу все контролировать и попытаться разобраться с Windows API без всяких надстроек. Я не профессиональный программист, сроков создания программы у меня нет, просто очень люблю программирование, Windows и Visual Studio.
|
Сообщ.
#9
,
|
|
|
Цитата tumanovalex @ Да не хочу я MFC!!! Хочу все контролировать и попытаться разобраться с Windows API без всяких надстроек. Я не профессиональный программист, сроков создания программы у меня нет, просто очень люблю программирование, Windows и Visual Studio. c MFC проще, без нее тебя ждет долгий и тернистый путь с Win32 API к тому же еще и на Си Флаг в руки, но не с песней |
Сообщ.
#10
,
|
|
|
Так как все-таки развернуть диалог из ресурсов
int ret = DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DlgProc); |
Сообщ.
#11
,
|
|
|
M Cfon, за дальнейший оффтоп в разделе выпишу банку и РО. Цитата tumanovalex @ Подскажите, пожалуйста, как диалог из ресурса сразу развернуть на весь экран. Уточни, что ты имеешь ввиду под сразу: 1. после создания диалога, 2. в конструкторе диалогов редактора ресурсов? |
Сообщ.
#12
,
|
|
|
Хотелось бы узнать и то, и другое (после создания диалога и в конструкторе диалогов редактора ресурсов)
Добавлено Как сделать после создания диалога - я вроде бы разобрался: case WM_INITDIALOG: { ShowWindow(hwnd, SW_MAXIMIZE); return FALSE; } Добавлено А если в редакторе диалогов можно указать, что окно нужно развернуть на весь экран, то можно редакторе задать положение кнопок (и других контролов), чтобы они были на нужном месте при развернутом окне? |
Сообщ.
#13
,
|
|
|
Цитата tumanovalex @ Вы рассматриваете идею использования окон по средствам WinAPI, а конструктор может лишь генерировать код окна, скажем, создавать так называемый ресурс, который затем подтягивается и используется. За вызов диалогов отвечает Код, а конструктор лишь создает шаблон. Все верно?2. В большинстве книг по WinAPI описано создание класса окна в памяти с последующим созданием экземпляра класса, а не с помощью конструктора диалогов. Тогда получается, что генератор ресурсов не может в ресурс собирать код, который будет что-то делать. Это лишь ресурс, оболочка. Вместе с этим все же, кроме создания этих ресурсов генерируется и код. Это простейший код обращения с ресурсами. Цитата tumanovalex @ Такого сделать по средствам конструктора нельзя. За вызов диалогов отвечает код, и такой код, обычно, пишет программист.возможности создания программ с использованием конструктора диалогов (вызов из одного диалога другого Цитата tumanovalex @ Это уже можно делать в Run-Time, но по средствам вызова функций, которые это делают (т.е. тех самых API Windows).настройка вида диалогов в процессе работы программы, примеры диалогов с разными контролами, создание событий для контролов и др. Поэтому, все же, стоит посмотреть в сторону книг WinAPI, чтобы понять что есть что и как этим управлять в Run-Time. Я рекомендую просмотреть (а может и почитать) книгу Программирование под Windows 95 (том 1) - Ч. Педзолд И пусть Вас не смущает Windows 95, все началось с этими окнами оттуда, появились те самые API. В книге, довольно детально, описаны методы написания программ с таким вот подходом к окнам (когда нужно работать с API голыми руками), подход тех времен. Именно поэтому Cfon написал: Цитата Cfon @ c MFC проще, без нее тебя ждет долгий и тернистый путь с Win32 API к тому же еще и на Си Как вариант, загляните еще на MSDN в документацию на Visual Studio 2010, возможно там задокументировано использование конструктора студии. |
Сообщ.
#14
,
|
|
|
Спасибо за ответ. А почему B.V. указал второй вариант?
|
Сообщ.
#15
,
|
|
|
Ему виднее, конечно.
Но, он попросил уточнить вопрос, а не дал два варианта ответа Вот скрин создания формы. В свойствах "По центру" можно сразу указать, а вот "На весь экран" я не вижу.. В принципе, так можно все свойства смотреть. Просмотреть в оригинальном разрешении. |
Сообщ.
#16
,
|
|
|
Цитата tumanovalex @ А если в редакторе диалогов можно указать, что окно нужно развернуть на весь экран, то можно редакторе задать положение кнопок (и других контролов), чтобы они были на нужном месте при развернутом окне? С точки зрения редактора ресурсов, описание диалога лишь текстовая структура в *.rc-файле. Посмотри https://msdn.microsoft.com/ru-ru/library/wi...p/aa381002.aspx, там указаны все возможные поля структуры, а конкретно то, что ты хочешь, должно делаться заданием стиля WS_MAXIMIZE в параметре STYLE. Что касается размещения элементов управления на диалоге, то тут два варианта: либо сразу создать диалог размером с предполагаемый экран и разместить стандартными средствами конструктора все элементы, либо кодом, после инициализации выполнить перемещение, а что бы было проще, можно сгруппировать элементы по дочерним диалогам-контейнерам |
Сообщ.
#17
,
|
|
|
Спасибо за ответ. Когда был такой код:
case WM_INITDIALOG: { //ShowWindow(hwnd, SW_MAXIMIZE); return FALSE; } STYLE WS_MAXIMIZE | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU |
Сообщ.
#18
,
|
|
|
Цитата tumanovalex @ окно мелькнуло и пропало Добавь WS_VISIBLE. |
Сообщ.
#19
,
|
|
|
STYLE WS_MAXIMIZE | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE case WM_INITDIALOG: { ShowWindow(hwnd, WS_VISIBLE); return FALSE; } |
Сообщ.
#20
,
|
|
|
Цитата tumanovalex @ STYLE WS_MAXIMIZE | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE case WM_INITDIALOG: { ShowWindow(hwnd, WS_VISIBLE); return FALSE; } Может это ?: WS_MINIMIZEBOX | WS_MAXIMIZEBOX Процесс исследований может быть таким: Запускаем некое приложение, разворачиваем окно и WinSpy-ем смотрим его стили. Их и будем пробовать использовать. --- А вообще эти опыты у меня кончились полным провалом - мне никак не удалось, используя стили окна показать его при запуске приложения полностю развёрнутым или свёрнутым. Иногда при использовании WS_MAXIMIZE приложение начинало мерзко глючить. Поэтому я устанавливаю размеры окна исключительно после запуска. Попробуй найти, в чём дело, но по моему тема тухлая. --- Однако эта тема имеет полезное продолжение. Обычно юзер стремится выбрать некие параметры удобные для него. В том числе размеры окна и его расположение на скрине. Поэтому неплохим свойством приложения можно считать установку при запуске местоположения и размеров, выбраннх юзером предыдущим запуском. По крайней мере для окошек, непрерывно отображающих чего-то. (За исключением свёрнутого положения - запускать так, это уже перебор.) |
Сообщ.
#21
,
|
|
|
нельзя! нет совместимости флажков WS_POPUP и WS_MAXIMIZE. MFC рулит!
|
Сообщ.
#22
,
|
|
|
Убрал WS_POPUP, все равно ничего не получилось. Проект прикрепил, может быть я где-то что-то перепутал?
Прикреплённый файлWin32dialog.zip (3,73 Кбайт, скачиваний: 103) |
Сообщ.
#23
,
|
|
|
tumanovalex, похоже ответ спрятан в сообщении ЫукпШ. Рекомендую перечитать его внимательно.
|
Сообщ.
#24
,
|
|
|
пропустил break в switch WM_SIZE
MFC рулит! |
Сообщ.
#25
,
|
|
|
Спасибо, получилось. Только если в rc файле указать:
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_VISIBLE | WS_MAXIMIZE | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZE | WS_VISIBLE |
Сообщ.
#26
,
|
|
|
Чтобы ответить почему, надо знать релизацию Win32 API функции CreateWindow(Ex)
ИМХО как я уже писал флажок WS_MAXIMIZE игнорится при установленом стиле WS_POPUP, хотя вроде он игнориться и при WS_OVERLAPPED вообще надо делать через ShowWindow(SW_MAXIMIZE) |
Сообщ.
#27
,
|
|
|
Цитата B.V. @ либо кодом, после инициализации выполнить перемещение, а что бы было проще, можно сгруппировать элементы по дочерним диалогам-контейнерам Подскажите, пожалуйста,как создать дочерний диалог-контейнер для контролов, например, для кнопок ОК и Отмена. |
Сообщ.
#28
,
|
|
|
Цитата tumanovalex @ Все равно окно мелькнуло и пропало. Открыл твой проект. У тебя неправильно составлена процедура диалога. Во-первых, в случае обработки сообщения следует возвращать TRUE, согласно спецификации обработчика. Во-вторых, каждый case должен заканчиваться break-ом или return-ом, иначе управление безусловно перейдет на нижестоящий case. Что у тебя и происходит: со всех вышестоящих case управление переходит на case WM_CLOSE с последующим закрытием диалога. Что касается WS_MAXIMIZE. Возможно, диалоговые функции игнорируют данный стиль. Окно, созданное таким образом hWnd = CreateWindowEx(0, WCEX.lpszClassName, NULL, WS_OVERLAPPEDWINDOW | WS_MAXIMIZE | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 512, 512, NULL, NULL, hInstance, NULL); успешно отображается развернутым. Цитата tumanovalex @ Подскажите, пожалуйста,как создать дочерний диалог-контейнер для контролов, например, для кнопок ОК и Отмена. Точно так же, как и родительский диалог. Добавь еще один диалог в ресурсы и помести на него кнопки, а в его обработчике выполняй обработку WM_COMMAND и его результат проверяй в WinMain. Ну и создание, соответственно, должно быть через CreateDialog после родительского (так же не-модального), с указанием родителя.. |
Сообщ.
#29
,
|
|
|
Я никогда не работал с диалогами, а тем более с диалогами в диалоге. Поэтому у меня возникли трудности в реализации того, что Вы, B.V. посоветовали. У меня возникли следующие вопросы:
1. Исправил оконную процедуру DlgProc. Однако если в последнем операторе return CALLBACK DlgProc вместо FALSE указать TRUE, программа зависает. Почему так происходит? 2. Как определить хендл основного диалога для указания его в CreateDialog второго диалога? 3. Попробовал размер диалога с кнопками уменьшить до размера кнопок - не получилось. Можно ли это сделать? А то размер второго диалога, гораздо больший размера кнопок, может наложиться на другие контролы основного диалога. Проект с двумя диалогами и двумя колбек функциями прикрепил. В связи с возникшими вопросами проект не доделан, прошу не судить строго. Прикреплённый файлWin32dialog.zip (3,7 Кбайт, скачиваний: 103) |
Сообщ.
#30
,
|
|
|
Цитата B.V. @ Что касается WS_MAXIMIZE. Возможно, диалоговые функции игнорируют данный стиль. Окно, созданное таким образом hWnd = CreateWindowEx(0, WCEX.lpszClassName, NULL, WS_OVERLAPPEDWINDOW | WS_MAXIMIZE | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 512, 512, NULL, NULL, hInstance, NULL); успешно отображается развернутым. Специально попробовал - не получается. Использовал исходник из Петзольда (то-же самое, что и в MSDN). Если это действительно устойчиво работает, значит есть что-то ещё. ----- Не так всё просто, как казалось, с функцией ShowWindow. Там вообше автомат состояний, его работа зависит от запускающего приложения. Возможно игнорирование 2-го параметра при первом вызове этой функции. ----- Вероятно, все эти "проблемы" - результат того, что запускающее приложение Виндус должно иметь возможность запустить приложение в любом виде. И это можно настроить в "свойствах" - правой кнопкой мыши по ярлыку на рабочем столе->свойства->окно. |
Сообщ.
#31
,
|
|
|
Цитата tumanovalex @ Однако если в последнем операторе return CALLBACK DlgProc вместо FALSE указать TRUE, программа зависает. Почему так происходит? Потому что возвращая TRUE ты блокируешь стандартную обработку для любых сообщений, поступающих в диалог. Цитата MSDN Typically, the dialog box procedure should return TRUE if it processed the message, and FALSE if it did not. If the dialog box procedure returns FALSE, the dialog manager performs the default dialog operation in response to the message. Цитата tumanovalex @ 2. Как определить хендл основного диалога для указания его в CreateDialog второго диалога? Его возвращает функция CreateDialog. Цитата tumanovalex @ 3. Попробовал размер диалога с кнопками уменьшить до размера кнопок - не получилось. Можно ли это сделать? А то размер второго диалога, гораздо больший размера кнопок, может наложиться на другие контролы основного диалога. Диалог может быть любого размера. Даже нулевого. Но не стоит так делать. Что и где не получилось в плане размера? Цитата ЫукпШ @ Если это действительно устойчиво работает, значит есть что-то ещё. VC++ 12 -> Win32 empty project #include "stdafx.h" static HWND hWnd; int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPWSTR lpCmdLine, int nCmdShow) { MSG Msg; WNDCLASSEX WCEX = {0}; WCEX.cbSize = sizeof(WNDCLASSEX); WCEX.lpfnWndProc = MainWndProc; WCEX.hInstance = hInstance; WCEX.hCursor = LoadCursor(NULL, IDC_ARROW); WCEX.hbrBackground = GetSysColorBrush(COLOR_BTNFACE); WCEX.lpszClassName = L"MyWndClass"; if(!RegisterClassEx(&WCEX)) return 0; hWnd = CreateWindowEx(0, WCEX.lpszClassName, NULL, WS_OVERLAPPEDWINDOW | WS_MAXIMIZE | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 512, 512, NULL, NULL, hInstance, NULL); //message-loop return 0; } |
Сообщ.
#32
,
|
|
|
Цитата B.V. @ VC++ 12 -> Win32 empty project Нет, не работает. VS2008 -> Win32 empty project // -------------------------------------------------------------------------- #include "stdafx.h" //#include <mmsystem.h> //#include <commctrl.h> // -------------------------------------------------------------------------- //#pragma comment(lib,"winmm.lib") //#pragma comment(lib,"comctl32.lib") // -------------------------------------------------------------------------- LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; static HWND hWnd; // -------------------------------------------------------------------------- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR , int iCmdShow) { MSG Msg; WNDCLASSEX WCEX = {0}; WCEX.cbSize = sizeof(WNDCLASSEX); WCEX.lpfnWndProc = WndProc; WCEX.hInstance = hInstance; WCEX.hCursor = LoadCursor(NULL, IDC_ARROW); WCEX.hbrBackground = GetSysColorBrush(COLOR_BTNFACE); WCEX.lpszClassName = L"MyWndClass"; if(!RegisterClassEx(&WCEX)) return 0; hWnd = CreateWindowEx(0, WCEX.lpszClassName, NULL, WS_OVERLAPPEDWINDOW | WS_MAXIMIZE | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 512, 512, NULL, NULL, hInstance, NULL); while(::GetMessage (&Msg, NULL, 0, 0)) { ::TranslateMessage (&Msg) ; ::DispatchMessage (&Msg) ; } return Msg.wParam ; } // -------------------------------------------------------------------------- LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc ; PAINTSTRUCT ps ; RECT rect ; switch (iMsg) { case WM_CREATE : // ::PlaySound (_T("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ; // ::EnumSystemCodePages((CODEPAGE_ENUMPROC)EnumCodePagesProc, CP_INSTALLED); // ::EnumSystemCodePages((CODEPAGE_ENUMPROC)EnumCodePagesProc, CP_SUPPORTED); return 0 ; // case WM_ERASEBKGND: return 0; case WM_PAINT : hdc = ::BeginPaint (hwnd, &ps) ; ::GetClientRect (hwnd, &rect) ; ::DrawText (hdc, _T("Hello, Windows 95!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; ::EndPaint (hwnd, &ps) ; return 0; case WM_DESTROY: ::PostQuitMessage (0); return 0; } return ::DefWindowProc (hwnd, iMsg, wParam, lParam) ; } // -------------------------------------------------------------------------- Прикреплённая картинка
|
Сообщ.
#33
,
|
|
|
Цитата ЫукпШ @ Нет, не работает. VS2008 -> Win32 empty project Windows XP? Не исключаю, что проблема может быть в ней. Ибо у меня вот: https://snag.gy/1UbQJW.jpg |
Сообщ.
#34
,
|
|
|
Спасибо за ответ.
1. По поводу хендла. Я использую для основного диалога: INT_PTR ret = DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DlgProc); 2. По размеру диалога. В редакторе ресурсов я тянул края диалога за квадратики. Активны были только черные квадратики, но при уменьшении размеров диалога или исчезала кнопка, или кнопки сужались. Посмотрите, пожалуйста, прикрепленный выше проект, там есть второй диалог без рамки диалога. |
Сообщ.
#35
,
|
|
|
Цитата B.V. @ Windows XP? Не исключаю, что проблема может быть в ней. Ибо у меня вот: https://snag.gy/1UbQJW.jpg дело в среде VS попробуй запустить экзешник не из среды. Добавлено Цитата tumanovalex @ 1. По поводу хендла. Я использую для основного диалога: INT_PTR ret = DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DlgProc); Через DialogBox нельзя получить хендл окна, а зачем этот хендл если окно модальное |
Сообщ.
#36
,
|
|
|
Цитата tumanovalex @ Как используя DialogBox получить хендл - я не понял. Мне нужно заменить DialogBox на CreateDialog? Да. И добавить цикл обработки сообщений ниже создания диалогов. Вместе с IsDialogMessage. Цитата tumanovalex @ но при уменьшении размеров диалога или исчезала кнопка, или кнопки сужались Ах, вот ты про что. Так это фича студийного конструктора, помогающая позиционировать элементы на клиентской области. Нажми Ctrl+G и она тебе не будет никак мешать задавать положение и размеры. Либо просто растяни пунктирный контур на весь диалог, эффект будет аналогичным Цитата Cfon @ дело в среде VS Дело, скорее, в ShowWindow после CreateProcess у Проводника. Аналогичный запуск из под командной строки не вызывает проблем.. |
Сообщ.
#37
,
|
|
|
Цитата B.V. @ Дело, скорее, в ShowWindow после CreateProcess у Проводника. Аналогичный запуск из под командной строки не вызывает проблем.. точно так |
Сообщ.
#38
,
|
|
|
Цитата B.V. @ Цитата ЫукпШ @ Нет, не работает. VS2008 -> Win32 empty project Windows XP? Не исключаю, что проблема может быть в ней. Увы, это не так. Проверял и компиляцию и выполнение на XP SP2,SP3, WIN7. (все x86) Под Вистой собрать не могу, но выполняется также. (x86,x64). Сборки приложения x86, x64. Под WIN8 я тоже проверить могу, и, вероятно, под WIN98. (Только придётся собрать проект VS2005-ой.) Нутром чую, что это незачем. Добавлено Не вижу окна тестовой программы... Покажи окошко. А такой вариант я уже видел - стиль правильный, а окошко не развернулось. Это я подразумевал под словами "мерзко глючит". Добавлено Цитата B.V. @ Аналогичный запуск из под командной строки не вызывает проблем.. Да. Это я забыл сделать. Если из командной строки - развернётся. Но на это рассчитывать не хотелось бы. --- Всем спасибо, обсуждение оказалось для меня очень полезным. Теперь стало понятно, для надёжного восстановления размеров и расположения главного окна на скрине, необходимо вызвать "ShowWindow" не менее 2-х раз. |
Сообщ.
#39
,
|
|
|
Второй диалог уменьшить удалось, хендл первого диалог получил. Код получился такой:
#include <windows.h> #include "resource.h" BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK DlgProc2(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hwnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DlgProc); HWND hwnd2 = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG2), hwnd, (DLGPROC)DlgProc2); return 0; } BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: ShowWindow(hwnd, SW_MAXIMIZE); break; case WM_CLOSE: EndDialog(hwnd,0); break; } return FALSE; } BOOL CALLBACK DlgProc2(HWND hwnd2, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: ShowWindow(hwnd2, SW_NORMAL); break; case WM_COMMAND: { switch (LOWORD(wParam)) { case ID_OK: EndDialog(hwnd2,1); break; case ID_CANCEL: EndDialog(hwnd2,0); break; } break; } case WM_CLOSE: EndDialog(hwnd2,0); break; } return FALSE; } Прикреплённый файлWin32dialog_02.zip (3,64 Кбайт, скачиваний: 86) |
Сообщ.
#40
,
|
|
|
Цитата tumanovalex @ Как дальше обрабатывать сообщения от этих диалогов и как расположить второй диалог в правом нижнем углу первого диалога - я не знаю. Может быть есть пример с диалогом, размещенным на другом диалоге? коллега может откроешь книгу по winapi? например есть хорошая книжка "win32 api разработка приложений для Windows" автор Юрий Щупак , 2008 года издание. там есть отдельная глава посвящённая диалоговым окнам. |
Сообщ.
#41
,
|
|
|
К сожалению, этой книги нигде в продаже нет. На торрентах тоже не нашел. А те книги по Win32API, которые я смотрел, не содержат информации об управлении диалоговыми окнами.
Добавлено У меня есть книга Румянцева "Азбука программирования на Win32", но в ней я информации об управлении диалогом в диалоге я не нашел. |
Сообщ.
#42
,
|
|
|
Цитата tumanovalex @ На торрентах тоже не нашел. Если ты воспользуешься яндексом и будешь просто искать стороку : "win32 api разработка приложений для Windows" автор Юрий Щупак книга найдётся почти сразу. --- Что-то надо делать и самому, иначе точно ничего не получится. |
Сообщ.
#43
,
|
|
|
Спасибо, нашел. Буду изучать.
|
Сообщ.
#44
,
|
|
|
Наконец-то удалось вывести на экран основной диалог и кнопки:
#include <windows.h> #include "resource.h" HWND hwnd, hwndBtn; BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK DlgProcBtn(HWND, UINT, WPARAM, LPARAM); void MoveDlg(HWND, HWND); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; hwnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DlgProc); hwndBtn = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG2), hwnd, (DLGPROC)DlgProcBtn); IsDialogMessage(hwndBtn, &msg); // // Не знаю, как правильно обработать результат проверки IsDialogMessage while (GetMessage(&msg, NULL, 0, 0)) { if (!IsDialogMessage(hwndBtn, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return msg.wParam; } BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: ShowWindow(hwnd, SW_MAXIMIZE); break; case WM_CLOSE: EndDialog(hwnd,0); break; } return FALSE; } BOOL CALLBACK DlgProcBtn(HWND hwndBtn, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: ShowWindow(hwndBtn, SW_NORMAL); MoveDlg(hwnd, hwndBtn); break; case WM_COMMAND: { switch (LOWORD(wParam)) { case ID_OK: EndDialog(hwndBtn,1); break; case ID_CANCEL: EndDialog(hwndBtn,0); break; } break; } case WM_CLOSE: EndDialog(hwndBtn,0); break; //SendMessage; // Не знаю, как правильно послать сообщение break; } return FALSE; } void MoveDlg(HWND hParent, HWND hDlg) { RECT rcParent, rcDlg; POINT p0; GetClientRect(hParent, &rcParent); GetWindowRect(hDlg, &rcDlg); int width = rcDlg.right - rcDlg.left; int height = rcDlg.bottom - rcDlg.top; p0.x = rcParent.right - width - 10; p0.y = rcParent.bottom - height; MoveWindow(hDlg, p0.x, p0.y, width, height, TRUE); } Прикреплённый файлWin32dialog_03.zip (3,87 Кбайт, скачиваний: 102) |
Сообщ.
#45
,
|
|
|
Цитата tumanovalex @ Однако основной диалог и кнопки закрываются по-отдельности и после их закрытия программа зависает. Как я понимаю, это вызвано строками, которые я пометил как "Не знаю". Помогите, пожалуйста, разобраться, как правильно посылать и обрабатывать сообщения. смотрел смотрел твой проект и ничего не понял зачем создается два диалога? только для группировки двух кнопок? ! Нарушение п. 1.3 правил форума Cfon, я предупреждал |
Сообщ.
#46
,
|
|
|
Цитата tumanovalex @ Есть подозрение, что функцию EndDialog не надо вызывать как у вас, ибо на это намекает справка:как правильно посылать и обрабатывать сообщения Цитата а у вас диалог создаётся просто как окошко... Remarks Dialog boxes created by the DialogBox, DialogBoxParam, DialogBoxIndirect, and DialogBoxIndirectParam functions must be destroyed using the EndDialog function. An application calls EndDialog from within the dialog box procedure; the function must not be used for any other purpose. Добавлено Но в том конкретном вашем примере сработает и так: BOOL CALLBACK DlgProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: ShowWindow( hwnd, SW_MAXIMIZE); break; case WM_CLOSE: EndDialog( hwnd, wParam); PostMessage( hwnd, WM_QUIT, wParam, lParam); ... BOOL CALLBACK DlgProcBtn( HWND hwndBtn, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { case WM_INITDIALOG: ShowWindow( hwndBtn, SW_NORMAL); MoveDlg( hwnd, hwndBtn); break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDOK: EndDialog(hwndBtn,1); PostMessage(GetParent(hwndBtn),WM_CLOSE,1,0); return TRUE;//break; case IDCANCEL: EndDialog(hwndBtn,0); PostMessage(GetParent(hwndBtn),WM_CLOSE,0,0); ... |
Сообщ.
#47
,
|
|
|
[QUOTE=Cfon,1484463663,3702023]смотрел смотрел твой проект и них** не понял
зачем создается два диалога? только для группировки двух кнопок? [/QUOTE] На самом деле будет много контролов на основном диалоге. Добавлено [QUOTE=Славян,1484466124,3702028]Есть подозрение, что функцию EndDialog не надо вызывать как у вас, ибо на это намекает справка:[QUOTE]а у вас диалог создаётся просто как окошко... [/QUOTE] Спасибо большое, сработало. А как правильно вызывать EndDialog и создавать диалог (не просто как окошко)? Как правильно в моем примере это сделать? |
Сообщ.
#48
,
|
|
|
Можно так попробовать:
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { //MSG msg; //hwnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DlgProc); //hwndBtn = 0;//CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG2), hwnd, (DLGPROC)DlgProcBtn); return DialogBox( hInstance, MAKEINTRESOURCE(IDD_DIALOG1),NULL,(DLGPROC)DlgProc); } BOOL CALLBACK DlgProc( HWND lhwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { case WM_INITDIALOG: ShowWindow( hwnd = lhwnd, SW_MAXIMIZE); // говорим, что глобальная - это как локальная hwndBtn = CreateDialog( NULL, MAKEINTRESOURCE(IDD_DIALOG2), lhwnd, (DLGPROC)DlgProcBtn); break; case WM_CLOSE: EndDialog( lhwnd, wParam); PostMessage(lhwnd,WM_QUIT,wParam,lParam); ... Добавлено Ай, WM_QUIT в данном случае даже излишне. |
Сообщ.
#49
,
|
|
|
Цитата tumanovalex @ А как правильно вызывать EndDialog и создавать диалог (не просто как окошко)? Как правильно в моем примере это сделать? EndDialog разрушает модальное диалоговое окно, немодальное удаляется через DestroyWindow. Чтобы закрыть диалог из другого окна диалога надо послать пользовательское сообщение и обработать его в диал.процедуре окна владельца BOOL CALLBACK DlgProc1(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case UM_CLOSEWINDOW: EndDialog(hwnd,0); return TRUE; } return FALSE; } BOOL CALLBACK DlgProc2(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: SendMessage(GetParent(hwnd), UM_CLOSEWINDOW, 0, 0); return TRUE; } } return FALSE; } |
Сообщ.
#50
,
|
|
|
Спасибо за ответы. Теперь понятно.
|
Сообщ.
#51
,
|
|
|
А когда нужно использовать IsDialogMessage, о которой упоминается в сообщении B.V.?
|
Сообщ.
#52
,
|
|
|
Цитата tumanovalex @ А когда нужно использовать IsDialogMessage, о которой упоминается в сообщении B.V.? в случае немодального окна: while(GetMessage(...)) { if (!IsDialogMessage(...)) { DispatchMessage(...); } } обработаное в IsDialogMessage сообщение не должно обрабатывается повторно в DispatchMessage. |
Сообщ.
#53
,
|
|
|
Спасибо за ответ.
|