Помощь - Поиск - Пользователи - Календарь
Полная версия: C++ создание класса дочернего окна
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ада и другие языки
guf
Создаю обычный win32 project. Нужно использовать RegisterClass либо RegisterClassEx. Подскажите как сделать новый класс окна.
guf
Что никто не может мне помочь???
volvo
Цитата
Подскажите как сделать новый класс окна.
Ты ж создаешь проект, в большинстве случаев для тебя генерируют стандартный исходник, вот и посмотри, как там делается:

WNDCLASSEX wcex;

// Заполняешь поля класса

// и регистрируешь:
RegisterClassEx(&wcex);
Какой у тебя компилятор?
guf
У меня стоит MVS 2005.
Только у меня не дочернее окно, а просто новое окно.Я к тому что WS_CHILD мне нужен)
Так создал класс второго окна:
Код
ATOM CSecondWindow(HINSTANCE hInstance) //регистрация класса окна
{
    WNDCLASSEX wc;
    
    wc.cbSize = sizeof(WNDCLASSEX);
    
    wc.style            = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc    = SecondWindProc;
            wc.cbClsExtra        = 0;
            wc.cbWndExtra        = 0;
            wc.hInstance     = hInstance;
            wc.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MY21212121));
            wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
            wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
            wc.lpszMenuName    = MAKEINTRESOURCE(IDC_MY21212121);
            wc.lpszClassName    = szWindowClass;
            wc.hIconSm        = LoadIcon(wc.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wc);
}


Потом делаю оконную процедуру:

Код
LRESULT CALLBACK SecondWindProc(HWND hSWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_EXIT:
            DestroyWindow(hSWnd);
            break;
        default:
            return DefWindowProc(hSWnd, message, wParam, lParam);
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hSWnd, &ps);
        // TODO: Add any drawing code here...
        EndPaint(hSWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hSWnd, message, wParam, lParam);
    }
    return 0;
}


Дальше нужно сделать, чтобы это окно открывалось после выбора пункта меню в главном окне.
volvo
Ну, так сделай что-то вроде:

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_COMMAND: // получили команду от пользователя
switch(wParam) {
case IDM_CREATECHILD: // на создание дочернего окна

// переменная hChildWnd описана глобально, как и hwnd - хендл главного окна приложения
hChildWnd = CreateWindowEx (0, szWindowClass,
"Child Window", // заголовок дочернего окна
WS_CHILD|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_VISIBLE, // его стиль
200, 200, 200, 200, // и размеры
hwnd, NULL, ::GetModuleHandle(NULL),
NULL
);

if(!hChildWnd) MessageBox(0, 0, 0, 0); // сигнализируем об ошибке
else ShowWindow(hChildWnd, SW_SHOWNORMAL);
break;

default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
break;

case WM_DESTROY:
PostQuitMessage (0);
break;

default:
return DefWindowProc (hwnd, message, wParam, lParam);
}

return 0;
}



Добавлено через 3 мин.
P.S. Ах, да... Забыл... CSecondWindow вызывается там же, где регистрируется класс основного окна... Ибо просто регистрация класса ни к чему не обязывает - создавать окно этого класса можно потом, когда в этом возникнет необходимость.
guf
Сделал почти как ты описал. Теперь окно About вылезает если вызывать окноunsure.gif
volvo
Значит, делай не "почти", а точно так, как я описал. Потому что я не придумывал ничего прямо здесь, а проверил, и скопировал кусок из отработавшего проекта. Никакое окно "About" не выскакивает, когда не положено...
guf
Переделал работает. Не получается точно также...

				case IDM_CREATECHILD: // на создание дочернего окна

// переменная hChildWnd описана глобально, как и hwnd - хендл главного окна приложения
hChildWnd = CreateWindowEx (0, szWindowClass,
"Child Window", // заголовок дочернего окна
WS_CHILD|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_VISIBLE, // его стиль
200, 200, 200, 200, // и размеры
hwnd, NULL, ::GetModuleHandle(NULL),
NULL
);


"Child Window" не получается заголовок сделать, пишет
Цитата
cannot convert parameter 3 from 'const char [3]' to 'LPCWSTR'

как это описать?
volvo
Я изначально тестировал на Code::Blocks, но для Студии надо сделать следующее (пишу по памяти, Студию запустить сейчас не могу, я не под Windows):

1. Добавить
TCHAR szTitle[MAX_LOADSTRING];		// The title bar text
TCHAR szChildTitle[MAX_LOADSTRING]; // Вот эту строку - здесь будет храниться заголовок дочерней формы


2. Добавить
	// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDS_CHILD_TITLE, szChildTitle, MAX_LOADSTRING); // <--- Чтение из ресурсов

(естественно, в resource.h надо добавить константу IDS_CHILD_TITLE, а в сам файл ресурсов .RC - добавить к уже существующему STRINGTABLE саму строку:

   IDS_APP_TITLE       "app" 
IDS_CHILD_TITLE "Child Window"
)

Убедись, что ты регистрируешь класс основного окна и дочернего с разными именами классов, потому что из того что ты запостил здесь следует как раз, что имена классов одинаковые: у тебя при регистрации класса дочернего окна записано:
wc.lpszClassName    = szWindowClass;

, а это то, что студия делает для основного тоже... Если так, то придется тебе еще и описать строку szChildWindowClass (по подобию szWindowClass, опять внести изменения в resource.h и RC-файл, и прочитать строку с именем дочернего класса по аналогии с тем, как читается szWindowClass)...

И самое главное - не забудь поставить тот break, который у меня стоит перед default, очень похоже на то, что ты его упустил, и поэтому у тебя при создании дочернего окна еще и выскакивает About...
guf
Да про break ты прав, я поспешил. С заголовкам так и не получилось ничего сделать.
Мне вот интересено как сделать оконную процедуру для дочернего окна, типа LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM) у главного окна.
volvo
Не знаю, что там у тебя не получилось, вот работающий проект (правда, собирался на VC++ 2008):
Нажмите для просмотра прикрепленного файла

Правда его еще надо "допиливать", при создании и перемещении нескольких дочерних окон проявляются артефакты. Но это уже попробуй сделать сам...
guf
Volvo, спасибо огромное!!! Я начал потихоньку понимать что к чему smile.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.