Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Ада и другие языки _ C++ создание класса дочернего окна

Автор: guf 30.07.2008 0:46

Создаю обычный win32 project. Нужно использовать RegisterClass либо RegisterClassEx. Подскажите как сделать новый класс окна.

Автор: guf 30.07.2008 2:11

Что никто не может мне помочь???

Автор: volvo 30.07.2008 2:32

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

WNDCLASSEX wcex;

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

// и регистрируешь:
RegisterClassEx(&wcex);
Какой у тебя компилятор?

Автор: guf 30.07.2008 3:14

У меня стоит 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 30.07.2008 4:30

Ну, так сделай что-то вроде:

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 31.07.2008 3:04

Сделал почти как ты описал. Теперь окно About вылезает если вызывать окноunsure.gif

Автор: volvo 31.07.2008 3:23

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

Автор: guf 31.07.2008 3:36

Переделал работает. Не получается точно также...

				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 31.07.2008 4:13

Я изначально тестировал на 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 31.07.2008 5:09

Да про break ты прав, я поспешил. С заголовкам так и не получилось ничего сделать.
Мне вот интересено как сделать оконную процедуру для дочернего окна, типа LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM) у главного окна.

Автор: volvo 31.07.2008 13:16

Не знаю, что там у тебя не получилось, вот работающий проект (правда, собирался на VC++ 2008):
Прикрепленный файл  just.rar ( 16.57 килобайт ) Кол-во скачиваний: 428


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

Автор: guf 1.08.2008 6:36

Volvo, спасибо огромное!!! Я начал потихоньку понимать что к чему smile.gif