tiwal Ответов: 1

Невозможно управлять событием cbutton on_BN_CLICKED в MFC


Мне удалось создать CButton в производном классе CView, и он виден.
Проблема в том, что независимо от того, как и где я вставляю запись карты управления событиями ON_BN_CLICKED, кажется, что событие не запускается или, по крайней мере, не распространяется на правильную карту сообщений.
Это мой класс, производный от cview первоначального обработчика обновления :

void CMFC_csv2hstView::OnInitialUpdate()  // 
{
	// TODO: add draw code for native data here
	RECT R;
	R.bottom = 250;
	R.top = 100;
	R.left = 100;
	R.right = 250; 
	
	/*CButton CB;*/
	CB.Create(_T("Hello"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, R, this, 1);
	

}


и связанная с этим карта сообщений :


IMPLEMENT_DYNCREATE(CMFC_csv2hstView, CView)

BEGIN_MESSAGE_MAP(CMFC_csv2hstView, CView)
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CMFC_csv2hstView::OnFilePrintPreview)
	ON_COMMAND(WM_CREATE, &CMFC_csv2hstView::OnCreateWindow)
	//ON_COMMAND(BN_CLICKED, &CMFC_csv2hstView::OnButton) //-->
	ON_BN_CLICKED(1, &CMFC_csv2hstView::OnButton)//-
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONUP()
END_MESSAGE_MAP()


Как вы можете видеть , метод "OnButton" - это мой обработчик OnClick, где я ставлю точку останова, но она никогда не достигается.Похоже, что, как бы вы ни нажимали на кнопку, событие не управляется.

Я должен сказать, что сделал много попыток, прежде чем достичь этой точки, я пытался поместить обработчик событий во все возможные карты сообщений вокруг приложения (даже если иногда это было явно глупо).
Некоторые говорили мне , что, возможно, идентификатор, который я назначал CButton (1), уже используется, я попытался найти в приложении другие объекты с тем же идентификатором, но не смог его найти. Есть ли способ назначить идентификатор и убедиться, что он еще не используется ?

Я просмотрел множество учебников и онлайн-ресурсов, похоже, никто не принимает во внимание возможность управления кнопкой без использования диалоговых окон.
Разве это правило ? есть ли предел в структуре MFC, который не позволяет делать то, что я хочу сделать ?

Приложение является MDI и я использую VS 2013 Community

Что я уже пробовал:

Сдачи :

ON_BN_CLICKED(1, &CMFC_csv2hstView::OnButton)


в CWinApp, MainFrm

Jochen Arndt

Где определяется CB?

Это должен быть член вашего класса представлений. Если это так, то ON_BN_CLICKED() должен работать при условии, что кнопка тем временем не была отключена.

Проверьте также, была ли кнопка успешно создана (Create возвращает TRUE).

tiwal

CButton является частным членом моего производного от CView класса... Я вижу кнопку на представлении и нажимаю на нее , но обработчик событий не вызывается.

Jochen Arndt

Каков базовый класс вашего CMFC_csv2hstView (например, CEditView, CListView)?

tiwal

Это Cview .

Jochen Arndt

Так что обычный CView. Как уже было сказано, это должно сработать.

Что Вы тоже должны проверить:
- CMFC_csv2hstView::OnButton должен быть объявлен как afx_msg
- Убедитесь, что идентификатор кнопки уникален (не используется для других элементов управления в том же представлении)

Чтобы проверить, обработано ли сообщение, вы можете отправить его вручную для тестирования:

SendMessage(GetSafeHwnd(), WM_COMMAND, (BN_CLICKED << 16) | 1, CB.GetSafeHwnd());
Вышесказанное должно быть вызвано из класса view. Но он также может быть вызван из другого места при передаче указателя на представление и использовании его для первого и последнего параметра (тогда CB должен быть общедоступным).

В качестве альтернативы подумайте об использовании класса на основе CFormView, где элементы управления определены в шаблоне и поэтому не должны создаваться в вашем коде.

tiwal

Мне сказали , что есть способ добавить CButton с помощью мастера, но я не могу узнать, как ... кроме того, есть ли здесь способ убедиться, что идентификатор CButton ID
разве он уже не используется ?

Jochen Arndt

Смотрите мой ответ: это работает для меня.

Используйте представление на основе CFormView для создания шаблона, в который можно добавить кнопку с помощью мастера. В интернете есть много примеров по этой теме.

tiwal

Хорошо , воссоздал решение, получающее представление из CFormView . Теперь, как я могу добавить CButton с помощью мастера ? Должен ли я выбрать мастер проекта|класса ?

Jochen Arndt

Вы должны создать шаблон dialag, который загружается представлением формы (обычно в конструкторе вашего производного класса).
Смотрите документацию по классу CFormView и связанные ссылки или ищите учебник в интернете.

tiwal

Ну, я не создавал шаблон диалогового окна, но я понял, что, помещая CButton непосредственно в CFormView, событие BN_CLICKED правильно распространяется, и я могу справиться с ним. Довольно странно, что то же самое нельзя сделать с помощью Cview .

Jochen Arndt

Это можно сделать так, как показано в моем решении. Я создал новый проект на основе CView, добавил код, показанный в моем решении, и он работает так, как ожидалось.

1 Ответов

Рейтинг:
2

Jochen Arndt

Я только что протестировал его с новым приложением MFC, и он работает так, как ожидалось:

// ViewTestView.h
class CViewTestView : public CView
{
    // ...
protected:
    CButton m_button;
    DECLARE_MESSAGE_MAP()
    afx_msg void OnButton();
};
// ViewTestView.cpp
BEGIN_MESSAGE_MAP(CViewTestView, CView)
	// ...
	ON_BN_CLICKED(1, &CViewTestView::OnButton)
END_MESSAGE_MAP()

// ...

void CViewTestView::OnInitialUpdate()
{
    CView::OnInitialUpdate();
    
    m_button.Create(_T("Hello"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 
        CRect(100, 100, 250,250), this, 1);
}

void CViewTestView::OnButton()
{
    AfxMessageBox(_T("Button activated"));
}