На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> Создание приложения Win32API с использованием диалогов
    Поле прочтения темы GUI для консольной программы на C++ (Visual Studio 2010) решил попробовать создать приложение с помощью конструктора диалогов Visual C++ 2010:
    ExpandedWrap disabled
      #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)
    Сообщение отредактировано: tumanovalex -
      Цитата tumanovalex @
      - размещался в центре экрана

      DS_CENTER

      Цитата tumanovalex @
      - разворачивался на весь экран, при этом кнопки были бы в правом нижнем углу

      Ручками, в обработчиках POSCHANGE/SIZE.
        У меня основная функция имеет вид (забыл ее указать в первом сообщении:
        ExpandedWrap disabled
          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;
          }
        Как я понял, функция DialogBox регистрирует колбек функцию и присваивает уникальный номер дескриптору окна, созданного из ресурса (шаблона диалога). А как указать, что это окно должно размещаться по центру? Когда класс окна создается в памяти, это указывается в параметрах окна, а когда окно создается с использованием ресурса?
          Цитата tumanovalex @
          А как указать, что это окно должно размещаться по центру?

          В редакторе ресурсов, в режиме конструктора диалогов -- свойство "Position -> Center"
            Спасибо, получилось. Теперь буду разбираться с POSCHANGE/SIZE.
              У меня диалоговое окно будет содержать много контролов, поэтому хотелось бы сразу развернуть его на весь экран, а потом уже подбирать расположение контролов на развернутом экране. Подскажите, пожалуйста, как диалог из ресурса сразу развернуть на весь экран.
                Цитата tumanovalex @
                У меня диалоговое окно будет содержать много контролов, поэтому хотелось бы сразу развернуть его на весь экран, а потом уже подбирать расположение контролов на развернутом экране. Подскажите, пожалуйста, как диалог из ресурса сразу развернуть на весь экран.

                извращенец :crazy:
                MFC в зубы и с песней! :D
                  Да не хочу я MFC!!! Хочу все контролировать и попытаться разобраться с Windows API без всяких надстроек. Я не профессиональный программист, сроков создания программы у меня нет, просто очень люблю программирование, Windows и Visual Studio.
                    Цитата tumanovalex @
                    Да не хочу я MFC!!! Хочу все контролировать и попытаться разобраться с Windows API без всяких надстроек. Я не профессиональный программист, сроков создания программы у меня нет, просто очень люблю программирование, Windows и Visual Studio.

                    c MFC проще, без нее тебя ждет долгий и тернистый путь с Win32 API к тому же еще и на Си :D
                    Флаг в руки, но не с песней :D
                      Так как все-таки развернуть диалог из ресурсов
                      ExpandedWrap disabled
                        int ret = DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DlgProc);
                      на весь экран? Неужели никто не знает?
                        M
                        Cfon, за дальнейший оффтоп в разделе выпишу банку и РО.


                        Цитата tumanovalex @
                        Подскажите, пожалуйста, как диалог из ресурса сразу развернуть на весь экран.

                        Уточни, что ты имеешь ввиду под сразу: 1. после создания диалога, 2. в конструкторе диалогов редактора ресурсов?
                          Хотелось бы узнать и то, и другое (после создания диалога и в конструкторе диалогов редактора ресурсов)

                          Добавлено
                          Как сделать после создания диалога - я вроде бы разобрался:
                          ExpandedWrap disabled
                                case WM_INITDIALOG:
                                {
                                  ShowWindow(hwnd, SW_MAXIMIZE);
                                  return FALSE;
                                }
                          а вот как в редакторе ресурсов - не знаю

                          Добавлено
                          А если в редакторе диалогов можно указать, что окно нужно развернуть на весь экран, то можно редакторе задать положение кнопок (и других контролов), чтобы они были на нужном месте при развернутом окне?
                            Цитата tumanovalex @
                            2. В большинстве книг по WinAPI описано создание класса окна в памяти с последующим созданием экземпляра класса, а не с помощью конструктора диалогов.
                            Вы рассматриваете идею использования окон по средствам 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, возможно там задокументировано использование конструктора студии.
                              Спасибо за ответ. А почему B.V. указал второй вариант?
                                Ему виднее, конечно.
                                Но, он попросил уточнить вопрос, а не дал два варианта ответа :)

                                Вот скрин создания формы. В свойствах "По центру" можно сразу указать, а вот "На весь экран" я не вижу..
                                В принципе, так можно все свойства смотреть.

                                Просмотреть в оригинальном разрешении.

                                user posted imageuser posted image
                                  Цитата tumanovalex @
                                  А если в редакторе диалогов можно указать, что окно нужно развернуть на весь экран, то можно редакторе задать положение кнопок (и других контролов), чтобы они были на нужном месте при развернутом окне?

                                  С точки зрения редактора ресурсов, описание диалога лишь текстовая структура в *.rc-файле. Посмотри https://msdn.microsoft.com/ru-ru/library/wi...p/aa381002.aspx, там указаны все возможные поля структуры, а конкретно то, что ты хочешь, должно делаться заданием стиля WS_MAXIMIZE в параметре STYLE. Что касается размещения элементов управления на диалоге, то тут два варианта: либо сразу создать диалог размером с предполагаемый экран и разместить стандартными средствами конструктора все элементы, либо кодом, после инициализации выполнить перемещение, а что бы было проще, можно сгруппировать элементы по дочерним диалогам-контейнерам
                                    Спасибо за ответ. Когда был такой код:
                                    ExpandedWrap disabled
                                          case WM_INITDIALOG:
                                          {
                                            //ShowWindow(hwnd, SW_MAXIMIZE);
                                            return FALSE;
                                          }
                                    диалог появлялся (причем при раскоментировании строки диалог максимизировался), а когда в файле .rc сделал так:
                                    ExpandedWrap disabled
                                      STYLE WS_MAXIMIZE | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
                                    окно мелькнуло и пропало. Поскольку разрешение экрана может быть разное, я хотел бы следовать по второму пути - разместить на диалоге нужные элементы, а после инициализации диалога (максимизации диалога) контролы диалога переместить в нужное положение в зависимости от текущего разрешения экрана. При этом хотелось бы максимально использовать возможности редактора ресурсов.
                                    Сообщение отредактировано: tumanovalex -
                                      Цитата tumanovalex @
                                      окно мелькнуло и пропало

                                      Добавь WS_VISIBLE.
                                        ExpandedWrap disabled
                                          STYLE WS_MAXIMIZE | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
                                        Все равно окно мелькнуло и пропало. Попробовал
                                        ExpandedWrap disabled
                                              case WM_INITDIALOG:
                                              {
                                                ShowWindow(hwnd, WS_VISIBLE);
                                                return FALSE;
                                              }
                                        тот же результат.
                                          Цитата tumanovalex @
                                          ExpandedWrap disabled
                                            STYLE WS_MAXIMIZE | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
                                          Все равно окно мелькнуло и пропало. Попробовал
                                          ExpandedWrap disabled
                                                case WM_INITDIALOG:
                                                {
                                                  ShowWindow(hwnd, WS_VISIBLE);
                                                  return FALSE;
                                                }
                                          тот же результат.

                                          Может это ?:
                                          ExpandedWrap disabled
                                            WS_MINIMIZEBOX | WS_MAXIMIZEBOX

                                          Процесс исследований может быть таким:
                                          Запускаем некое приложение, разворачиваем окно и WinSpy-ем смотрим его стили.
                                          Их и будем пробовать использовать.
                                          ---
                                          А вообще эти опыты у меня кончились полным провалом - мне никак не удалось, используя
                                          стили окна показать его при запуске приложения полностю развёрнутым или свёрнутым.
                                          Иногда при использовании WS_MAXIMIZE приложение начинало мерзко глючить.
                                          Поэтому я устанавливаю размеры окна исключительно после запуска.
                                          Попробуй найти, в чём дело, но по моему тема тухлая.
                                          ---
                                          Однако эта тема имеет полезное продолжение.
                                          Обычно юзер стремится выбрать некие параметры удобные для него.
                                          В том числе размеры окна и его расположение на скрине.
                                          Поэтому неплохим свойством приложения можно считать установку при запуске
                                          местоположения и размеров, выбраннх юзером предыдущим запуском.
                                          По крайней мере для окошек, непрерывно отображающих чего-то.
                                          (За исключением свёрнутого положения - запускать так, это уже перебор.)
                                          Сообщение отредактировано: ЫукпШ -
                                            нельзя! нет совместимости флажков WS_POPUP и WS_MAXIMIZE. MFC рулит! :D
                                              Убрал WS_POPUP, все равно ничего не получилось. Проект прикрепил, может быть я где-то что-то перепутал?
                                              Прикреплённый файлПрикреплённый файлWin32dialog.zip (3,73 Кбайт, скачиваний: 103)
                                                tumanovalex, похоже ответ спрятан в сообщении ЫукпШ. Рекомендую перечитать его внимательно.
                                                  пропустил break в switch WM_SIZE :D
                                                  MFC рулит! :wild:
                                                  Сообщение отредактировано: Cfon -
                                                    Спасибо, получилось. Только если в rc файле указать:
                                                    ExpandedWrap disabled
                                                      STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_VISIBLE | WS_MAXIMIZE | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZE | WS_VISIBLE
                                                    все равно не разворачивается
                                                      Чтобы ответить почему, надо знать релизацию Win32 API функции CreateWindow(Ex) :)
                                                      ИМХО как я уже писал флажок WS_MAXIMIZE игнорится при установленом стиле WS_POPUP, хотя вроде он игнориться и при WS_OVERLAPPED :D
                                                      вообще надо делать через ShowWindow(SW_MAXIMIZE)
                                                      Сообщение отредактировано: Cfon -
                                                        Цитата B.V. @
                                                        либо кодом, после инициализации выполнить перемещение, а что бы было проще, можно сгруппировать элементы по дочерним диалогам-контейнерам

                                                        Подскажите, пожалуйста,как создать дочерний диалог-контейнер для контролов, например, для кнопок ОК и Отмена.
                                                        Сообщение отредактировано: tumanovalex -
                                                          Цитата tumanovalex @
                                                          Все равно окно мелькнуло и пропало.

                                                          Открыл твой проект. У тебя неправильно составлена процедура диалога. Во-первых, в случае обработки сообщения следует возвращать TRUE, согласно спецификации обработчика. Во-вторых, каждый case должен заканчиваться break-ом или return-ом, иначе управление безусловно перейдет на нижестоящий case. Что у тебя и происходит: со всех вышестоящих case управление переходит на case WM_CLOSE с последующим закрытием диалога.

                                                          Что касается WS_MAXIMIZE. Возможно, диалоговые функции игнорируют данный стиль. Окно, созданное таким образом
                                                          ExpandedWrap disabled
                                                                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 после родительского (так же не-модального), с указанием родителя..
                                                            Я никогда не работал с диалогами, а тем более с диалогами в диалоге. Поэтому у меня возникли трудности в реализации того, что Вы, B.V. посоветовали. У меня возникли следующие вопросы:
                                                            1. Исправил оконную процедуру DlgProc. Однако если в последнем операторе return CALLBACK DlgProc вместо FALSE указать TRUE, программа зависает. Почему так происходит?
                                                            2. Как определить хендл основного диалога для указания его в CreateDialog второго диалога?
                                                            3. Попробовал размер диалога с кнопками уменьшить до размера кнопок - не получилось. Можно ли это сделать? А то размер второго диалога, гораздо больший размера кнопок, может наложиться на другие контролы основного диалога.
                                                            Проект с двумя диалогами и двумя колбек функциями прикрепил. В связи с возникшими вопросами проект не доделан, прошу не судить строго.
                                                            Прикреплённый файлПрикреплённый файлWin32dialog.zip (3,7 Кбайт, скачиваний: 103)
                                                            Сообщение отредактировано: tumanovalex -
                                                              Цитата B.V. @
                                                              Что касается WS_MAXIMIZE. Возможно, диалоговые функции игнорируют данный стиль. Окно, созданное таким образом
                                                              ExpandedWrap disabled
                                                                    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-го параметра при первом вызове этой функции.
                                                              -----
                                                              Вероятно, все эти "проблемы" - результат того, что запускающее
                                                              приложение Виндус должно иметь возможность запустить приложение
                                                              в любом виде. И это можно настроить в "свойствах" - правой кнопкой
                                                              мыши по ярлыку на рабочем столе->свойства->окно.
                                                              Сообщение отредактировано: ЫукпШ -
                                                                Цитата 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

                                                                ExpandedWrap disabled
                                                                  #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;
                                                                  }
                                                                  Цитата B.V. @
                                                                  VC++ 12 -> Win32 empty project

                                                                  Нет, не работает.
                                                                  VS2008 -> Win32 empty project
                                                                  ExpandedWrap disabled
                                                                    // --------------------------------------------------------------------------
                                                                    #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) ;
                                                                    }
                                                                    // --------------------------------------------------------------------------

                                                                  Прикреплённая картинка
                                                                  Прикреплённая картинка
                                                                  Сообщение отредактировано: ЫукпШ -
                                                                    Цитата ЫукпШ @
                                                                    Нет, не работает.
                                                                    VS2008 -> Win32 empty project

                                                                    Windows XP? Не исключаю, что проблема может быть в ней. Ибо у меня вот: https://snag.gy/1UbQJW.jpg
                                                                      Спасибо за ответ.
                                                                      1. По поводу хендла. Я использую для основного диалога:
                                                                      ExpandedWrap disabled
                                                                        INT_PTR ret = DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DlgProc);
                                                                      Как используя DialogBox получить хендл - я не понял. Мне нужно заменить DialogBox на CreateDialog?
                                                                      2. По размеру диалога. В редакторе ресурсов я тянул края диалога за квадратики. Активны были только черные квадратики, но при уменьшении размеров диалога или исчезала кнопка, или кнопки сужались. Посмотрите, пожалуйста, прикрепленный выше проект, там есть второй диалог без рамки диалога.
                                                                        Цитата B.V. @
                                                                        Windows XP? Не исключаю, что проблема может быть в ней. Ибо у меня вот: https://snag.gy/1UbQJW.jpg

                                                                        дело в среде VS :D
                                                                        попробуй запустить экзешник не из среды.

                                                                        Добавлено
                                                                        Цитата tumanovalex @
                                                                        1. По поводу хендла. Я использую для основного диалога:
                                                                        ExpandedWrap disabled
                                                                          INT_PTR ret = DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DlgProc);
                                                                        Как используя DialogBox получить хендл - я не понял. Мне нужно заменить DialogBox на CreateDialog?

                                                                        Через DialogBox нельзя получить хендл окна, а зачем этот хендл если окно модальное :D
                                                                        Сообщение отредактировано: Cfon -
                                                                          Цитата tumanovalex @
                                                                          Как используя DialogBox получить хендл - я не понял. Мне нужно заменить DialogBox на CreateDialog?

                                                                          Да. И добавить цикл обработки сообщений ниже создания диалогов. Вместе с IsDialogMessage.

                                                                          Цитата tumanovalex @
                                                                          но при уменьшении размеров диалога или исчезала кнопка, или кнопки сужались

                                                                          Ах, вот ты про что. Так это фича студийного конструктора, помогающая позиционировать элементы на клиентской области. Нажми Ctrl+G и она тебе не будет никак мешать задавать положение и размеры. Либо просто растяни пунктирный контур на весь диалог, эффект будет аналогичным

                                                                          Цитата Cfon @
                                                                          дело в среде VS

                                                                          Дело, скорее, в ShowWindow после CreateProcess у Проводника. Аналогичный запуск из под командной строки не вызывает проблем..
                                                                            Цитата B.V. @
                                                                            Дело, скорее, в ShowWindow после CreateProcess у Проводника. Аналогичный запуск из под командной строки не вызывает проблем..

                                                                            точно так :yes:
                                                                              Цитата B.V. @
                                                                              Цитата ЫукпШ @
                                                                              Нет, не работает.
                                                                              VS2008 -> Win32 empty project

                                                                              Windows XP? Не исключаю, что проблема может быть в ней.

                                                                              Увы, это не так.
                                                                              Проверял и компиляцию и выполнение на XP SP2,SP3, WIN7.
                                                                              (все x86)
                                                                              Под Вистой собрать не могу, но выполняется также.
                                                                              (x86,x64). Сборки приложения x86, x64.
                                                                              Под WIN8 я тоже проверить могу, и, вероятно, под WIN98.
                                                                              (Только придётся собрать проект VS2005-ой.)
                                                                              Нутром чую, что это незачем.

                                                                              Добавлено
                                                                              Цитата B.V. @
                                                                              Ибо у меня вот: https://snag.gy/1UbQJW.jpg

                                                                              Не вижу окна тестовой программы...
                                                                              Покажи окошко. А такой вариант я уже видел - стиль правильный,
                                                                              а окошко не развернулось.
                                                                              Это я подразумевал под словами "мерзко глючит".

                                                                              Добавлено
                                                                              Цитата B.V. @
                                                                              Аналогичный запуск из под командной строки не вызывает проблем..

                                                                              Да. Это я забыл сделать.
                                                                              Если из командной строки - развернётся. Но на это рассчитывать не хотелось бы.
                                                                              ---
                                                                              Всем спасибо, обсуждение оказалось для меня очень полезным.
                                                                              Теперь стало понятно, для надёжного восстановления размеров
                                                                              и расположения главного окна на скрине, необходимо вызвать
                                                                              "ShowWindow" не менее 2-х раз.
                                                                              Сообщение отредактировано: ЫукпШ -
                                                                                Второй диалог уменьшить удалось, хендл первого диалог получил. Код получился такой:
                                                                                ExpandedWrap disabled
                                                                                  #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)
                                                                                  Цитата tumanovalex @
                                                                                  Как дальше обрабатывать сообщения от этих диалогов и как расположить второй диалог в правом нижнем углу первого диалога - я не знаю. Может быть есть пример с диалогом, размещенным на другом диалоге?

                                                                                  коллега :D
                                                                                  может откроешь книгу по winapi? например есть хорошая книжка "win32 api разработка приложений для Windows" автор Юрий Щупак , 2008 года издание.
                                                                                  там есть отдельная глава посвящённая диалоговым окнам.
                                                                                    К сожалению, этой книги нигде в продаже нет. На торрентах тоже не нашел. А те книги по Win32API, которые я смотрел, не содержат информации об управлении диалоговыми окнами.

                                                                                    Добавлено
                                                                                    У меня есть книга Румянцева "Азбука программирования на Win32", но в ней я информации об управлении диалогом в диалоге я не нашел.
                                                                                    Сообщение отредактировано: tumanovalex -
                                                                                      Цитата tumanovalex @
                                                                                      На торрентах тоже не нашел.

                                                                                      Если ты воспользуешься яндексом и будешь просто искать
                                                                                      стороку :
                                                                                      "win32 api разработка приложений для Windows" автор Юрий Щупак
                                                                                      книга найдётся почти сразу.
                                                                                      ---
                                                                                      Что-то надо делать и самому, иначе точно ничего не получится.
                                                                                      Сообщение отредактировано: ЫукпШ -
                                                                                        Спасибо, нашел. Буду изучать.
                                                                                          Наконец-то удалось вывести на экран основной диалог и кнопки:
                                                                                          ExpandedWrap disabled
                                                                                            #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)
                                                                                          Сообщение отредактировано: tumanovalex -
                                                                                            Цитата tumanovalex @
                                                                                            Однако основной диалог и кнопки закрываются по-отдельности и после их закрытия программа зависает. Как я понимаю, это вызвано строками, которые я пометил как "Не знаю". Помогите, пожалуйста, разобраться, как правильно посылать и обрабатывать сообщения.

                                                                                            смотрел смотрел твой проект и ничего не понял :D
                                                                                            зачем создается два диалога? только для группировки двух кнопок? :wacko:

                                                                                            !
                                                                                            Нарушение п. 1.3 правил форума
                                                                                            Cfon, я предупреждал
                                                                                            Сообщение отредактировано: B.V. -
                                                                                              Цитата 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.
                                                                                              а у вас диалог создаётся просто как окошко... :(

                                                                                              Добавлено
                                                                                              Но в том конкретном вашем примере сработает и так:
                                                                                              ExpandedWrap disabled
                                                                                                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);
                                                                                                ...
                                                                                                [QUOTE=Cfon,1484463663,3702023]смотрел смотрел твой проект и них** не понял :D
                                                                                                зачем создается два диалога? только для группировки двух кнопок? :wacko:[/QUOTE]
                                                                                                На самом деле будет много контролов на основном диалоге.

                                                                                                Добавлено
                                                                                                [QUOTE=Славян,1484466124,3702028]Есть подозрение, что функцию EndDialog не надо вызывать как у вас, ибо на это намекает справка:[QUOTE]а у вас диалог создаётся просто как окошко... :([/QUOTE]
                                                                                                Спасибо большое, сработало. А как правильно вызывать EndDialog и создавать диалог (не просто как окошко)? Как правильно в моем примере это сделать?
                                                                                                  Можно так попробовать:
                                                                                                  ExpandedWrap disabled
                                                                                                    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 в данном случае даже излишне. :blush:
                                                                                                    Цитата tumanovalex @
                                                                                                    А как правильно вызывать EndDialog и создавать диалог (не просто как окошко)? Как правильно в моем примере это сделать?

                                                                                                    EndDialog разрушает модальное диалоговое окно, немодальное удаляется через DestroyWindow.
                                                                                                    Чтобы закрыть диалог из другого окна диалога надо послать пользовательское сообщение и обработать его в диал.процедуре окна владельца :D

                                                                                                    ExpandedWrap disabled
                                                                                                      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;
                                                                                                      }
                                                                                                    Сообщение отредактировано: Cfon -
                                                                                                      Спасибо за ответы. Теперь понятно.
                                                                                                        А когда нужно использовать IsDialogMessage, о которой упоминается в сообщении B.V.?
                                                                                                          Цитата tumanovalex @
                                                                                                          А когда нужно использовать IsDialogMessage, о которой упоминается в сообщении B.V.?

                                                                                                          в случае немодального окна:
                                                                                                          ExpandedWrap disabled
                                                                                                            while(GetMessage(...))
                                                                                                            {
                                                                                                                if (!IsDialogMessage(...))
                                                                                                                {
                                                                                                                     DispatchMessage(...);
                                                                                                                }
                                                                                                            }

                                                                                                          обработаное в IsDialogMessage сообщение не должно обрабатывается повторно в DispatchMessage.
                                                                                                          Сообщение отредактировано: Cfon -
                                                                                                            Спасибо за ответ.
                                                                                                            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                                                                            0 пользователей:


                                                                                                            Рейтинг@Mail.ru
                                                                                                            [ Script execution time: 0,1776 ]   [ 25 queries used ]   [ Generated: 2.05.24, 12:16 GMT ]