Есть некий диалог, к нему привязан класс. Если создаю модальное окно, то оно все работает. Но хочется чтобы этот диалог был помещен в клиентскую область как дочернее окно.
Первый параметр в CreateWindow это зарегистрированное имя класса.
С предопределенными классами а-ля "button" все понятно, с динамической регистрацией своего тоже.
Но как определить имя класса, диалог для которого нарисован в Visual C++ и там же к нему этот класс пристегнут?
И как получить пойнтер на WNDPROC этого класса, которую тоже надо указать в CreateWindow? Ведь Visual С++ делает ее приватным параметром и у родительского класса окна нет туда доступа.
Заранее огромное спасибо.
Как определить имя класса для создания дочернего окна?
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Воплотить в жизнь то, что ты задумал не так просто. В COM есть понятия композитного контрола (это как раз и есть диалог, вмонтированный в другой диалог), так вот ATL содержит кучу дополнительного кода для того, чтобы правильно обрабатывать клавиши, двигать фокусы и резайзить этот внутренний диаложик. Если бы были простые способы это реализовать, скорее всего они были бы использованы в ATL.
Вижу 3 варианта:
1. Сделать FormView (это подходит только в том случае, если удовлетворит условиям задачи).
2. Если действительно нужен диалог-в-диалоге, то проще создать свой ActiveX composite control и встроить его.
3. Третий вариант только если два первых не подошли - делать всё ручками на уровне Win32 API.
Вижу 3 варианта:
1. Сделать FormView (это подходит только в том случае, если удовлетворит условиям задачи).
2. Если действительно нужен диалог-в-диалоге, то проще создать свой ActiveX composite control и встроить его.
3. Третий вариант только если два первых не подошли - делать всё ручками на уровне Win32 API.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Прошу прощения что изложил проблему не очень внятно. Диалог в диалоге не нужен. Нужен диалог в обычной клиентской области главного окна, который бы двигался вместе с главным окном, поэтому немодальный диалог и не подходит.
Хотя, возможно, я пошел по неправильному пути и есть другие способы размещения в главном окне жестко фиксированного окна? Кроме рисования диалога?
Слышал что такое удобно делать с помощью ActiveX, но сначала хочу нормально изучить базовую работу с окнами, а потом уже браться за надстройки.
Хотя, возможно, я пошел по неправильному пути и есть другие способы размещения в главном окне жестко фиксированного окна? Кроме рисования диалога?
Слышал что такое удобно делать с помощью ActiveX, но сначала хочу нормально изучить базовую работу с окнами, а потом уже браться за надстройки.
Это делается с помощью функции CreateDialog, которая позволяет создавать окно диалога в немодальном режиме. Этому диалогу можно указать стиль WS_CHILD вместо WS_POPUP, тогда диалог становится как бы дочерним элементом для родительского окна.
Да. Я же написал.
Вопрос: Как этого же добится для уже созданного в Visual C++ диалога?
Вот такой код работает на ура, создает окно.
d:\Work\C Projects\Port thread\Port thread\GrafikView.cpp(33): error C2724: 'CGrafikView::CWindowProc' : 'static' should not be used on member functions defined at file scope
Не понимаю откуда она появляется, что означает и как исправить?
Если я правильно понимаю, то этот класс диалога регистрируется автоматически при запуске программы и у него должно быть свое имя.
Если я пытаюсь регистрировать этот класс в конструкторе, вот так:
То есть весь предыдущий код (который выдает ошибку при компиляции) и не должен работать корректно, а должен иметь вид:
Это у меня получается и создать и получать сообщения в родительском классе."Первый параметр в CreateWindow это зарегистрированное имя класса.
С предопределенными классами а-ля "button" все понятно, с динамической регистрацией своего тоже. "
Вопрос: Как этого же добится для уже созданного в Visual C++ диалога?
Вот такой код работает на ура, создает окно.
А вот этот код выдает ошибку при компиляцииstatic WNDCLASS G;
G.hInstance = GetModuleHandle(NULL);
G.hbrBackground = (HBRUSH) (COLOR_BTNFACE);
G.lpfnWndProc = (WNDPROC) CChildWindowProc;
G.lpszClassName = "grafik";
ATOM A=RegisterClass(&G);
HWND hWndG=CreateWindow("grafik","grafik",WS_CHILD | WS_VISIBLE | WS_DLGFRAME, 0, 0, 1000, 400, this->m_hWnd, HMENU(10001), GetModuleHandle(NULL), NULL);
Ошибка звучит так:// Объявляем класс окна для графика
class CGrafikView : public CDialog
{
....
static LRESULT CWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
....
}
// Статическая функция для вызова оконной функции конкретного объекта
static LRESULT CGrafikView::CWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
return :efWindowProc(hWnd, msg, wParam, lParam);
}
// Этот код в функции Create родительского окна
static WNDCLASS G;
G.hInstance = GetModuleHandle(NULL);
G.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
G.lpfnWndProc = (WNDPROC) CGrafikView::CWindowProc;
G.lpszClassName = "grafik";
ATOM A=RegisterClass(&G);
HWND hWndD=CreateWindow("grafik","grafik",WS_CHILD | WS_VISIBLE | WS_DLGFRAME, 0, 0, 1000, 400, this->m_hWnd, HMENU(10001), GetModuleHandle(NULL), NULL);
d:\Work\C Projects\Port thread\Port thread\GrafikView.cpp(33): error C2724: 'CGrafikView::CWindowProc' : 'static' should not be used on member functions defined at file scope
Не понимаю откуда она появляется, что означает и как исправить?
Если я правильно понимаю, то этот класс диалога регистрируется автоматически при запуске программы и у него должно быть свое имя.
Если я пытаюсь регистрировать этот класс в конструкторе, вот так:
То при исполнении выдается ошибка и класс не регистрируется.ClassName = AfxRegisterWndClass(CS_VREDRAW | CS_HREDRAW, ::LoadCursor(NULL, IDC_ARROW),
(HBRUSH) ::GetStockObject(GRAY_BRUSH),
::LoadIcon(NULL, IDI_APPLICATION));
То есть весь предыдущий код (который выдает ошибку при компиляции) и не должен работать корректно, а должен иметь вид:
Вот собственно и вопрос. Откуда взять имя этого диалога?HWND hWndD=CreateWindow(<сюда подставляем имя класса диалога>,"grafik",WS_CHILD | WS_VISIBLE | WS_DLGFRAME, 0, 0, 1000, 400, this->m_hWnd, HMENU(10001), GetModuleHandle(NULL), NULL);
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Нет никакого смысла объявлять свою WindowProc для своего Dialog класса. Если ты наследуешься от CDialog, то там уже есть такая функция. Если её хочешь переопределить, то использую макросы а-ля MESSAGE_MAP, который внутри, собственно говоря и создают свою MessageProc.
По поводу ошибки компиляции. Ключевое слово static должно использоваться при объявлении метода, но не может быть использовано при определении метода. Убери его оттуда - функция всё равно останется статической. Это особенности синтаксиса С++.
По поводу ошибки компиляции. Ключевое слово static должно использоваться при объявлении метода, но не может быть использовано при определении метода. Убери его оттуда - функция всё равно останется статической. Это особенности синтаксиса С++.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Я думал, что ее надо вписывать в структуру WNDCLASS для регистрации из класса родительского окна, и, поскольку, родная WindowProc является приватной, то определил публичную функцию для доступа к ней из класса родительского окна.
Но теперь понимаю, что этот класс диалога уже обязан быть где-то зарегистрирован иначе просто не выведется даже как модальный.
И все, что требуется, это узнать имя класса для вызова CreateDialog. При этом и все другие функции работы с окнами хотят это зарегистрированное имя или ATOM. Как же его узнать?
Вот и вызов GetClassInfo,
BOOL GetClassInfoEx(
HINSTANCE hinst,
LPCTSTR lpszClass,
LPWNDCLASSEX lpwcx
);
который заполняет WNDCLASS, тоже хочет пойнтер на это имя или атом (lpszClass).
О, да. Огромное спасибо за замечание про static, виновата моя невнимательность при прочтении Страуструпа и привычка к простому Си
В будущем на эти грабли уже не наступлю.
Но теперь понимаю, что этот класс диалога уже обязан быть где-то зарегистрирован иначе просто не выведется даже как модальный.
И все, что требуется, это узнать имя класса для вызова CreateDialog. При этом и все другие функции работы с окнами хотят это зарегистрированное имя или ATOM. Как же его узнать?
Вот и вызов GetClassInfo,
BOOL GetClassInfoEx(
HINSTANCE hinst,
LPCTSTR lpszClass,
LPWNDCLASSEX lpwcx
);
который заполняет WNDCLASS, тоже хочет пойнтер на это имя или атом (lpszClass).
О, да. Огромное спасибо за замечание про static, виновата моя невнимательность при прочтении Страуструпа и привычка к простому Си

В будущем на эти грабли уже не наступлю.