Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Элемент управления потомок CWnd

501
05 июля 2006 года
hell_admin
110 / / 02.10.2004
Здравствуйте,

Есть следующай проблема которую, надо решить, буду признателен за помощь

надо сделать класс потомок от CWnd в SDI приложении,
я создаю MFC SDI App, далее создаю класс потомк CWnd

Код:
// control.h
#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);
};

Код:
//control.cpp
#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
Код:
class CMainFrame : public CFrameWnd
{

// ...всякая вода ...
    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 Создаю это окно
 
Код:
CRect rect;
    this->GetClientRect(&rect);
    if (!m_wndControl.Create(rect,this))
    {
        return -1;
    }

Так вот окно создается, тока не реагирует ни накакие события, и ваще активным не становится, хотя я в карте сообщений все прописал, ну точнее не я а ClassWizard

Возникает вопрос как правильно регистрировать этот новый класс чтоб он реагировал на события, у меня закралось подозрение что тут дело в окнной процедуре т.к. при регистрации класса указывается
 
Код:
...
    windowclass.lpfnWndProc = ::DefWindowProc;
...


Но с другой стороны класс то я наследую от Cwnd там должна быть своя прцедура или я че та не понял?
Вообщем пожалуйста обьясните вкратце механизм, а то я уже весь нет излазил и на firststeps был и на codeproject.com но нашел тока как делать оригинальные элементы управления привязанные к диалоговым окнам.
15K
06 июля 2006 года
Bora
13 / / 22.03.2006
[QUOTE=hell_admin]
 
Код:
...
    windowclass.lpfnWndProc = ::DefWindowProc;
...

[/QUOTE]
Попробуй вместо DefWindowProc написать свою ф-цию, которая будет чё-нить обрабатывать, так как DefWindowProc обрабатывает примитивы типа свернуть/развернуть.
284
06 июля 2006 года
michael_is_98
587 / / 25.02.2005
Также с этим долго разбирался. суть в том, что после создания твоего окна, нужно вызвать
RunModalLoop, который и и запустит свой цикл обработки сообщений.
Только делается это не совсем так, как обычно создаются приложения на MFC.

Т.е. в твоем окне MyControl не должно быть методов Create, RegisterClass, потому что твое окно не создано на основе класса диалога (CDialog), для которого инициализируется свой цикл обработки сообщений при вызове Create. Здесь тебе явно придется все это делать.

Если хочешь, могу пример показать.
11K
06 июля 2006 года
Ireul
90 / / 15.06.2006
[QUOTE=michael_is_98]Также с этим долго разбирался. суть в том, что после создания твоего окна, нужно вызвать
RunModalLoop, который и и запустит свой цикл обработки сообщений.
Только делается это не совсем так, как обычно создаются приложения на MFC.

Т.е. в твоем окне MyControl не должно быть методов Create, RegisterClass, потому что твое окно не создано на основе класса диалога (CDialog), для которого инициализируется свой цикл обработки сообщений при вызове Create. Здесь тебе явно придется все это делать.

Если хочешь, могу пример показать.[/QUOTE]

Чушь, товарищ... Сто раз создавал свои окна от CWnd - всё было прекрасно и всё обрабатывалось ПРОСТО СТИЛЬ WS_CHILD УКАЗЫВАТЬ НАДО КРОМЕ УКАЗАНИЯ ПАРЕНТА В Create()!!!! И всё будет!

А RegisterClass выкинь нах - он тебе не нужен, MFC само занимается обработкой сообщений - твоё дело на них реагировать.
284
07 июля 2006 года
michael_is_98
587 / / 25.02.2005
Чем WS_CHILD от WS_OVERLAPPED отличается?

Посмотрел, похоже WS_CHILD может не пройти... Он для простых окон, типа кнопки, стат. текст и т.д.
Для окна, укоторого может быть свое меню нужен WS_OVERLAPPED.

Или я что-то недопонимаю?
11K
08 июля 2006 года
Ireul
90 / / 15.06.2006
[QUOTE=michael_is_98]Чем WS_CHILD от WS_OVERLAPPED отличается?

Посмотрел, похоже WS_CHILD может не пройти... Он для простых окон, типа кнопки, стат. текст и т.д.
Для окна, укоторого может быть свое меню нужен WS_OVERLAPPED.

Или я что-то недопонимаю?[/QUOTE]

WS_CHILD от WS_OVERLAPPED отличается тем, что у последнего есть заголовок и нет передачи уведомлений родительскому окну. ПОТОМУ ЧТО У OVERLAPPED-ОКОН ОБЫЧНО НЕТ РОДИТКЛЬСКИХ ОКОН. Стиль WS_CHILD указывает именно на то, что есть родительское окно ВНУТРИ которого мы создаём наше окно, и ему с ним работать, с ним вместе двигаться и уведомления ЕМУ посылать. А ЕЩЁ У WS_CHILD ОКОН ТОЖЕ МОЖЕТ БЫТЬ РАМКА, МЕНЮ И ВСЁ ЧТО ТВОЕЙ ДУШЕ УГОДНО, ПРОСТО РАБОТАТЬ ОНИ БУДУТ В ОДНОЙ ОЧЕРЕДИ СООБЩЕНИЙ С РОДИТЕЛЬСКИМ! Уууу...
michael_is_98 убери "Специалист" из статуса. Ты им не являшься.
284
10 июля 2006 года
michael_is_98
587 / / 25.02.2005
[QUOTE=Ireul]WS_CHILD от WS_OVERLAPPED отличается тем, что у последнего есть заголовок и нет передачи уведомлений родительскому окну. ПОТОМУ ЧТО У OVERLAPPED-ОКОН ОБЫЧНО НЕТ РОДИТКЛЬСКИХ ОКОН. Стиль WS_CHILD указывает именно на то, что есть родительское окно ВНУТРИ которого мы создаём наше окно, и ему с ним работать, с ним вместе двигаться и уведомления ЕМУ посылать.
[/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.

3
10 июля 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=Ireul]ПРОСТО РАБОТАТЬ ОНИ БУДУТ В ОДНОЙ ОЧЕРЕДИ СООБЩЕНИЙ С РОДИТЕЛЬСКИМ! Уууу...
michael_is_98 убери "Специалист" из статуса. Ты им не являшься.[/QUOTE]
Вообще-то, очередь сообщений одна для одного потока (thread) и родство окон на неё никак не отражается.
284
10 июля 2006 года
michael_is_98
587 / / 25.02.2005
Конечно, но можно ведь сделать так, чтобы конкретное окно обрабатывало сообщения, которые посылаются именно ему с помощью своего цикла обюработки сообщений, а не цикла обработки сообщений владельца.
3
10 июля 2006 года
Green
4.8K / / 20.01.2000
Цикл сообщений существует в один в конкретном потоке (т.е. для однопоточных приложений он вообще один единственный) и никак не связан с каким-либо окном (окон может не быть вообще, а цикл будет жить). Т.е. не понятны выражения "свой цикл обработки сообщений" и "цикл обработки сообщений пользователя".
284
11 июля 2006 года
michael_is_98
587 / / 25.02.2005
Неправильно выразился... Процедура обработки сообщений у каждого окна может быть своя. Для конкретного окна можно создать свою процедуру, которая будет обрабатывать сообщения, поступающие из очереди.
11K
11 июля 2006 года
Ireul
90 / / 15.06.2006
[QUOTE=michael_is_98]Неправильно выразился... Процедура обработки сообщений у каждого окна может быть своя. Для конкретного окна можно создать свою процедуру, которая будет обрабатывать сообщения, поступающие из очереди.[/QUOTE]

Тебе вообще что надо-то? У тебя тема стоит "Элемент управления потомок CWnd". Это контрол. А тебе получается диалог нужен? Или может тулбарчик летучий? Что именно-то?!?

Если ты просто хочешь обрабатывать сообщения - пиши хандлеры и вставляй их в Message Map класса. И всё будет.
284
11 июля 2006 года
michael_is_98
587 / / 25.02.2005
Я вообще-то человеку хотел помочь... С его вопросом. Только он не уточнил, что именно ему нужно. Контрол на основе окна со стилем WS_CHILD, WS_POPUP, или WS_OVERLAPPED. Вот и получается, что мы говорим с разных сторон об одном и том же.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог