Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Диалоговое окно зависает  (Прочитано 7930 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
andrystepa
Помогающий

ru
Offline Offline

« : 01-04-2012 13:54 » 

Пишу свою первую программу только на Win32. Имеет вид окна с меню, в меню 3 пункта: Файл -> выход, О программе, Вид -> Здравствуй Мир
и 2 диалога: О программе и Здравствуй мир, вызываются соответствующими кнопками меню.
Содержимое файла Resorce.h:
Код: (C++)
#define IDC_MYICON                      2
#define IDD_HELLOWORLD_DIALOG           102
#define IDS_APP_TITLE                   103
#define IDD_ABOUTBOX                    103
#define IDM_ABOUT                       104
#define IDM_EXIT                        105
#define IDI_HELLOWORLD                  107
#define IDI_SMALL                       108
#define IDC_HELLOWORLD                  109
#define IDR_MAINFRAME                   128
#define IDD_HELLOWORLD                  129
#define IDC_EDIT1                       1000
#define IDC_RADIO1                      1001
#define IDC_LIST1                       1002
#define IDC_COMBO1                      1003
#define IDCANCEL1                       1005
#define ID_32771                        32771
#define ID_ViewHelloWorld               32772
#define ID_VIEWHELLOWOLD                32773
#define ID_VIEW_HELLOWOLD               32774
#define IDC_STATIC                      -1

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC                     1
#define _APS_NEXT_RESOURCE_VALUE        130
#define _APS_NEXT_COMMAND_VALUE         32775
#define _APS_NEXT_CONTROL_VALUE         1006
#define _APS_NEXT_SYMED_VALUE           110
#endif
#endif

Содержимое файла HelloWorld.cpp:
Код: (C++)
#include "stdafx.h"
#include "HelloWorld.h"

#define MAX_LOADSTRING 100

// Глобальные переменные:
HINSTANCE hInst;                                                                // текущий экземпляр
TCHAR szTitle[MAX_LOADSTRING];                                  // Текст строки заголовка
TCHAR szWindowClass[MAX_LOADSTRING];                    // имя класса главного окна

LPCTSTR szMsg=_T("Здравствуй Мир");
HBRUSH hBrush;
HBRUSH oldBrush;

// Отправить объявления функций, включенных в этот модуль кода:
ATOM                            MyRegisterClass(HINSTANCE hInstance);
BOOL                            InitInstance(HINSTANCE, int);
LRESULT CALLBACK        WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK        About(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK        Helloworld(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);

        // TODO: разместите код здесь.
        MSG msg;
        HACCEL hAccelTable;

        // Инициализация глобальных строк
        LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
        LoadString(hInstance, IDC_HELLOWORLD, szWindowClass, MAX_LOADSTRING);
        MyRegisterClass(hInstance);

        // Выполнить инициализацию приложения:
        if (!InitInstance (hInstance, nCmdShow))
        {
                return FALSE;
        }

        hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_HELLOWORLD));

        // Цикл основного сообщения:
        while (GetMessage(&msg, NULL, 0, 0))
        {
                if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
                {
                        TranslateMessage(&msg);
                        DispatchMessage(&msg);
                }
        }

        return (int) msg.wParam;
}



//
//  ФУНКЦИЯ: MyRegisterClass()
//
//  НАЗНАЧЕНИЕ: регистрирует класс окна.
//
//  КОММЕНТАРИИ:
//
//    Эта функция и ее использование необходимы только в случае, если нужно, чтобы данный код
//    был совместим с системами Win32, не имеющими функции RegisterClassEx'
//    которая была добавлена в Windows 95. Вызов этой функции важен для того,
//    чтобы приложение получило "качественные" мелкие значки и установило связь
//    с ними.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
        WNDCLASSEX wcex;

        wcex.cbSize = sizeof(WNDCLASSEX);

        wcex.style                      = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc        = WndProc;
        wcex.cbClsExtra         = 0;
        wcex.cbWndExtra         = 0;
        wcex.hInstance          = hInstance;
        wcex.hIcon                      = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_HELLOWORLD));
        wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName       = MAKEINTRESOURCE(IDC_HELLOWORLD);
        wcex.lpszClassName      = szWindowClass;
        wcex.hIconSm            = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

        return RegisterClassEx(&wcex);
}

//
//   ФУНКЦИЯ: InitInstance(HINSTANCE, int)
//
//   НАЗНАЧЕНИЕ: сохраняет обработку экземпляра и создает главное окно.
//
//   КОММЕНТАРИИ:
//
//        В данной функции дескриптор экземпляра сохраняется в глобальной переменной, а также
//        создается и выводится на экран главное окно программы.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Сохранить дескриптор экземпляра в глобальной переменной

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  ФУНКЦИЯ: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  НАЗНАЧЕНИЕ:  обрабатывает сообщения в главном окне.
//
//  WM_COMMAND  - обработка меню приложения
//  WM_PAINT    -Закрасить главное окно
//  WM_DESTROY   - ввести сообщение о выходе и вернуться.
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        int wmId, wmEvent;
        PAINTSTRUCT ps;
        HDC hdc;
        RECT rc;
        SIZE sz;
        switch (message)
        {
        case WM_COMMAND:
                wmId    = LOWORD(wParam);
                wmEvent = HIWORD(wParam);
                // Разобрать выбор в меню:
                switch (wmId)
                {
                case IDM_ABOUT:
                        DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                        break;
                case ID_VIEW_HELLOWOLD:
                        DialogBox(hInst, MAKEINTRESOURCE(IDD_HELLOWORLD), hWnd, Helloworld);

                        break;
                case IDM_EXIT:
                        DestroyWindow(hWnd);
                        break;
                default:
                        return DefWindowProc(hWnd, message, wParam, lParam);
                }
                break;
        case WM_PAINT:
                hdc = BeginPaint(hWnd, &ps);

               
                GetClientRect(hWnd, &rc);
               
                hBrush = CreateSolidBrush(RGB(111,123,93));

                oldBrush=(HBRUSH)SelectObject(hdc,hBrush);

                FillRect(hdc, &rc, hBrush);

                GetTextExtentPoint32(hdc,szMsg,_tcslen(szMsg),&sz);
               
                TextOut(hdc,(rc.right-rc.left-sz.cx)/2,(rc.bottom-rc.top-sz.cy)/2,szMsg,_tcslen(szMsg));
                // TODO: добавьте любой код отрисовки...
                EndPaint(hWnd, &ps);
                break;
        case WM_DESTROY:
                PostQuitMessage(0);
                break;
        default:
                return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
}

// Обработчик сообщений для окна "О программе".
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
        UNREFERENCED_PARAMETER(lParam);
        switch (message)
        {
        case WM_INITDIALOG:
                return (INT_PTR)TRUE;

        case WM_COMMAND:
                if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
                {
                        EndDialog(hDlg, LOWORD(wParam));
                        return (INT_PTR)TRUE;
                }
                break;
        }
        return (INT_PTR)FALSE;
}

//Обработчик сообщений диалога "Здравствуй Мир"
INT_PTR CALLBACK Helloworld(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
        UNREFERENCED_PARAMETER(lParam);
        switch (message)
        {
        case WM_INITDIALOG:
                return (INT_PTR)TRUE;

        case WM_COMMAND:
                if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
                {
                        EndDialog(hDlg, LOWORD(wParam));
                        return (INT_PTR)TRUE;
                }
               
                break;
        }
        return (INT_PTR)FALSE;
        }
Программа собирается без проблем и запускается тоже. Вот только диалог About (О программе) отрабатывает без проблем - т.е. открывается, закрывается при нажатии на кнопку Ок, или на крестик. А диалог Helloworld (Здравствуй Мир) открывается и виснет после этого, не реагируя на нажатия любой из кнопок или на крестик. Вышибать приходится через диспетчер задач.
Когда я создавал этот диалог, я просто скопировал диалог About, почти ничего не меняя, за исключением названия!
В чем же проблема?
« Последнее редактирование: 02-04-2012 07:53 от Джон » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 01-04-2012 15:08 » 

Вот с этого места: "...я просто скопировал..." - поподробнее. В коде у тебя сравнения идут с IDOK и IDCANCEL, а в ресурсах IDOK1 и IDCANCEL1. Два экземпляра диалога имеют собственные экземпляры кнопок. При копировании обычно автоматически добавляются единички.

Ты бы для начала не копировал диалоги, а создавал бы их самостоятельно, подглядывая в существующие, чтобы знать, что в них к чему. Потом уже можно и копировать, зная, как "причесать" копию после автоматических "услуг" по переименованию ресурсов.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
andrystepa
Помогающий

ru
Offline Offline

« Ответ #2 : 01-04-2012 17:41 » new

Вот с этого места: "...я просто скопировал..." - поподробнее. В коде у тебя сравнения идут с IDOK и IDCANCEL, а в ресурсах IDOK1 и IDCANCEL1. Два экземпляра диалога имеют собственные экземпляры кнопок. При копировании обычно автоматически добавляются единички.

Ты бы для начала не копировал диалоги, а создавал бы их самостоятельно, подглядывая в существующие, чтобы знать, что в них к чему. Потом уже можно и копировать, зная, как "причесать" копию после автоматических "услуг" по переименованию ресурсов.
Я не очень понял, в ресурсах есть IDCANCEL1, а IDOK1 нету. Я пытался решить проблему, присвоив кнопкам ОК и Canсel другие ID - не такие как в диалоге About. Я поставил в диалоге Helloworld для кнопок ОК и Cancel идентификаторы IDOK1 и IDCANCEL1, и вписал их в определении диалога в инструкции if. Но ничего не изменилось. Позже я случайно навел мышку на IDOK и выяснил что эти идентификаторы объявляются в файле WinUser.h. Поэтому вернул все как было, но еще не все успел переименовать когда создавал вопрос. Так что единички у меня не добавлялись автоматически - я сам их добавил.
Теперь все как было в самом начале, т.е. в обоих диалогах строка с if выглядит так:
Код:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
Однако все равно не работает.
« Последнее редактирование: 01-04-2012 17:46 от andrystepa » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines