Элемент управления потомок CWnd
Есть следующай проблема которую, надо решить, буду признателен за помощь
надо сделать класс потомок от CWnd в SDI приложении,
я создаю MFC SDI App, далее создаю класс потомк CWnd
#define MYCONTROL "MyControlName"
class CMyControl : public CWnd
{
DECLARE_DYNAMIC(CMyControl)
public:
CMyControl();
virtual ~CMyControl();
bool Create(const RECT & rect,CWnd * parent);
protected:
DECLARE_MESSAGE_MAP()
public:
bool RegisterClass(void);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
};
#include "stdafx.h"
#include "cust_ctrl2.h"
#include "MyControl.h"
// CMyControl
IMPLEMENT_DYNAMIC(CMyControl, CWnd)
CMyControl::CMyControl()
{
RegisterClass();
}
CMyControl::~CMyControl()
{
}
bool CMyControl::Create(const RECT & rect, CWnd * parent)
{
return CWnd::Create(MYCONTROL,"Testing new Component", WS_CHILD| WS_VISIBLE| WS_BORDER |WS_HSCROLL |WS_CAPTION, rect, parent, IID_MYCONTROL);
}
BEGIN_MESSAGE_MAP(CMyControl, CWnd)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
//class registering
bool CMyControl::RegisterClass(void)
{
WNDCLASS windowclass;
HINSTANCE hInst = AfxGetInstanceHandle();
if (!(::GetClassInfo(hInst, MYCONTROL, &windowclass)))
{
//If not then we have to register the new class
windowclass.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
windowclass.lpfnWndProc = ::DefWindowProc;
windowclass.cbClsExtra = windowclass.cbWndExtra = 0;
windowclass.hInstance = hInst;
windowclass.hIcon = NULL;
windowclass.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
windowclass.hbrBackground = ::GetSysColorBrush(COLOR_WINDOW);
windowclass.lpszMenuName = NULL;
windowclass.lpszClassName = MYCONTROL;
if (!AfxRegisterClass(&windowclass))
{
AfxThrowResourceException();
return false;
}
}
return true;
}
// on WM_LBUTTONDOWN handler
void CMyControl::OnLButtonDown(UINT nFlags, CPoint point)
{
MessageBox("Hello click");
CWnd::OnLButtonDown(nFlags, point);
}
дальше я добавляю член перменную в класс CMainFrame
{
// ...всякая вода ...
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
CChildView m_wndView;
CMyControl m_wndControl;
// Generated message map functions
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSetFocus(CWnd *pOldWnd);
DECLARE_MESSAGE_MAP()
};
И в вызове функции OnCreate Создаю это окно
this->GetClientRect(&rect);
if (!m_wndControl.Create(rect,this))
{
return -1;
}
Так вот окно создается, тока не реагирует ни накакие события, и ваще активным не становится, хотя я в карте сообщений все прописал, ну точнее не я а ClassWizard
Возникает вопрос как правильно регистрировать этот новый класс чтоб он реагировал на события, у меня закралось подозрение что тут дело в окнной процедуре т.к. при регистрации класса указывается
windowclass.lpfnWndProc = ::DefWindowProc;
...
Но с другой стороны класс то я наследую от Cwnd там должна быть своя прцедура или я че та не понял?
Вообщем пожалуйста обьясните вкратце механизм, а то я уже весь нет излазил и на firststeps был и на codeproject.com но нашел тока как делать оригинальные элементы управления привязанные к диалоговым окнам.
windowclass.lpfnWndProc = ::DefWindowProc;
...
[/QUOTE]
Попробуй вместо DefWindowProc написать свою ф-цию, которая будет чё-нить обрабатывать, так как DefWindowProc обрабатывает примитивы типа свернуть/развернуть.
RunModalLoop, который и и запустит свой цикл обработки сообщений.
Только делается это не совсем так, как обычно создаются приложения на MFC.
Т.е. в твоем окне MyControl не должно быть методов Create, RegisterClass, потому что твое окно не создано на основе класса диалога (CDialog), для которого инициализируется свой цикл обработки сообщений при вызове Create. Здесь тебе явно придется все это делать.
Если хочешь, могу пример показать.
RunModalLoop, который и и запустит свой цикл обработки сообщений.
Только делается это не совсем так, как обычно создаются приложения на MFC.
Т.е. в твоем окне MyControl не должно быть методов Create, RegisterClass, потому что твое окно не создано на основе класса диалога (CDialog), для которого инициализируется свой цикл обработки сообщений при вызове Create. Здесь тебе явно придется все это делать.
Если хочешь, могу пример показать.[/QUOTE]
Чушь, товарищ... Сто раз создавал свои окна от CWnd - всё было прекрасно и всё обрабатывалось ПРОСТО СТИЛЬ WS_CHILD УКАЗЫВАТЬ НАДО КРОМЕ УКАЗАНИЯ ПАРЕНТА В Create()!!!! И всё будет!
А RegisterClass выкинь нах - он тебе не нужен, MFC само занимается обработкой сообщений - твоё дело на них реагировать.
Посмотрел, похоже WS_CHILD может не пройти... Он для простых окон, типа кнопки, стат. текст и т.д.
Для окна, укоторого может быть свое меню нужен WS_OVERLAPPED.
Или я что-то недопонимаю?
Посмотрел, похоже WS_CHILD может не пройти... Он для простых окон, типа кнопки, стат. текст и т.д.
Для окна, укоторого может быть свое меню нужен WS_OVERLAPPED.
Или я что-то недопонимаю?[/QUOTE]
WS_CHILD от WS_OVERLAPPED отличается тем, что у последнего есть заголовок и нет передачи уведомлений родительскому окну. ПОТОМУ ЧТО У OVERLAPPED-ОКОН ОБЫЧНО НЕТ РОДИТКЛЬСКИХ ОКОН. Стиль WS_CHILD указывает именно на то, что есть родительское окно ВНУТРИ которого мы создаём наше окно, и ему с ним работать, с ним вместе двигаться и уведомления ЕМУ посылать. А ЕЩЁ У WS_CHILD ОКОН ТОЖЕ МОЖЕТ БЫТЬ РАМКА, МЕНЮ И ВСЁ ЧТО ТВОЕЙ ДУШЕ УГОДНО, ПРОСТО РАБОТАТЬ ОНИ БУДУТ В ОДНОЙ ОЧЕРЕДИ СООБЩЕНИЙ С РОДИТЕЛЬСКИМ! Уууу...
michael_is_98 убери "Специалист" из статуса. Ты им не являшься.
[/quote]
Если уж и говорить на эту тему, то прежде нужно исследовать ее полностью... Специально уделил внимание этому вопросу. Вот какой вывод можно сделать:
Принадлежность бывает двух типов: родительское/дочернее и
владелец/собственное окно. Первый тип определяет, где окно может быть нарисовано на экране. Второй тип определяет возможность удалять окна (владелец удаляет все окна, которыми он владеет). Как известно, окна бывают WS_OVERLAPPED (перекрываемое), WS_CHILD (дочернее), WS_POPUP (всплывающее)
Есть следующие различия
WS_OVERLAPPED - не имеет родителя и владельца или таковыми можно рассматривать десктоп (пример: окна приложений)
WS_POPUP - не обязано иметь родителя (может иметь, может не иметь, устанавливается ф. SetParent), но обязано имеет владельца (пример: окна диалога)
WS_CHILD - имеет родителя, но не имеет владельца (пример: окна кнопок, надписей). Т.е. Windows не хранит информацию об отношении владелец/собств. окно.
А ЕЩЁ У WS_CHILD ОКОН ТОЖЕ МОЖЕТ БЫТЬ РАМКА, МЕНЮ И ВСЁ ЧТО ТВОЕЙ ДУШЕ УГОДНО, ПРОСТО РАБОТАТЬ ОНИ БУДУТ В ОДНОЙ ОЧЕРЕДИ СООБЩЕНИЙ С РОДИТЕЛЬСКИМ! Уууу...
Не знаю, не проверял. Есть ли смысл делать кнопку или надпись с меню ?. Позволит ли Windows это сделать ?
michael_is_98 убери "Специалист" из статуса. Ты им не являшься.
Могу я отвечать на те вопросы, в которых компетентен и иметь тот статус в форуме, который хочу?
Если я неправильно понял суть вопроса - подскажите, в чем моя ошибка. Если нужен компонент, который перемещается вместе с родительским окном , в пределах родительского окна - тогда WS_CHILD актуален. Я имел в виду совсем другой компонент - отдельное окно, которое отображается поверх остальных в модальном режиме (т.е. не позволяет переключаться на окно-владелец), имеет меню и собственный цикл обработки сообщений, который никак не связан с циклом обработки сообщений окна-владельца. Т.е. такое окно, которое может выступать как отдельный компонент. Для этого нужен WS_OVERLAPPED, WS_POPUP или что-то совсем другое, но не WS_CHILD.
michael_is_98 убери "Специалист" из статуса. Ты им не являшься.[/QUOTE]
Вообще-то, очередь сообщений одна для одного потока (thread) и родство окон на неё никак не отражается.
Тебе вообще что надо-то? У тебя тема стоит "Элемент управления потомок CWnd". Это контрол. А тебе получается диалог нужен? Или может тулбарчик летучий? Что именно-то?!?
Если ты просто хочешь обрабатывать сообщения - пиши хандлеры и вставляй их в Message Map класса. И всё будет.