Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Диалоговые окна - не могу разобраться


Автор: Алексеу 3.6.2008, 20:31
Здравствуйте, господа програмисты!

Хочу обратиться к вам за помощью - разбираю программу, которую написали на учебе никак не могу въехать. С использованием MFC. Задачу модифицировать, изменять могу - знаю как куда и что добавить, если, к примеру, нужно обработать двойной шелчем мыши и т.д, но вот глобальной сути порограммы не понимаю - КАК она работает. Недавно только вылез из консоли - там все просто как веник - сначала инклуды, затем int main, функции - т.е. все четко и логически разбито, а тут я не понимаю что и в какой последовательности выполняется. В WinAPI вроде бы тоже ясно - ф.я. WinMain, обработчик сообщений, но в MFC не могу понять. Ниже программка которая создает обычное диалоговоек окно и выводит на экран информацию по щелчку мыши 

Заголовочный файл:

Код

DLGTEMPLATE dl={
                WS_DLGFRAME|WS_VISIBLE|WS_SYSMENU,
                0,
                0,
                100,100,
                400,400
                };
class MyDlg: public CDialog
{
public:
    MyDlg();
    BOOL OnInitDialog();
    DECLARE_MESSAGE_MAP();

    afx_msg void OnDestroy();
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnPaint();
};

class MyDlgApp:public CWinApp
{
public:
    BOOL InitInstance();
};


Файл срр:

Код

#include <afxwin.h>
#include "headMFC2.h"

MyDlg::MyDlg()
{
    InitModalIndirect(&dl);
}

BEGIN_MESSAGE_MAP(MyDlg,CDialog)
    //ON_WM_INITDIALOG()
    ON_WM_DESTROY()
    ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

BOOL MyDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    SetWindowText(L"Это диалоговое окно");
    return TRUE;
}

void MyDlg::OnDestroy()
{
    CDialog::OnDestroy();
}

MyDlgApp theApp;

BOOL MyDlgApp::InitInstance()
{
    MyDlg dlg;
    m_pMainWnd=&dlg;
    dlg.DoModal();
    return TRUE;
}

void MyDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
    MessageBox(L"Ура.",L"Сообщение");
}

void MyDlg::OnPaint()
{
    //This потому что для этого окна
    CPaintDC dc(this);
    CBrush br;
    br.CreateSolidBrush(RGB(0,0,255));
    CRect r(10,10,100,100);
    dc.FrameRect(&r,&br);
    br.DeleteObject();
}


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

Автор: east 3.6.2008, 21:48
Честно говоря сам в MSDN мало что понимаю. Для начала тебе нужно разобраться в обьектно ориентированном программировании. В Windows всё связано с сообщениями и событиями. Схема примерно такая, ты нажимаешь на кнопке в своём диалоговом окне. Виндус посылает сообщение о нажатии на кнопку мыши диалоговому. В диалоговом окне у тебя есть обработчик этого сообщения
Код

void MyDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
    MessageBox(L"Ура.",L"Сообщение");
}

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

Автор: Алексеу 3.6.2008, 22:23
east, да это все я понимаю. Понимаю суть ООП, да и подобную программу написать могу, но просто пишу я так - беру какую-то подобную вроде этой и начинаю оттуда выкидывать ненужное и вкидывать нужное, не понимаю толком самой структуры, а вот ясность хотелось бы иметь. То что ты сказал понятно, но вот хотелось бы глобального понимания...

Автор: yurik_l 3.6.2008, 23:33
http://www.rsdn.ru/article/mfc/maze.xml

Автор: Earnest 4.6.2008, 07:41
Алексеу, MFC - это тонкая оболочка на WinAPI, не больше. Там есть тот же WinMain и главный цикл обработки сообщения: все в классе CWinApp.
Самое лучшее, что могу предложить - залезь в исходники MFC и посмотри. Можно поставить точку прерывания в InitInstance твоего класса- приложения и посмотреть, откуда вызывается и что там вокруг.

Автор: dizzy1984 4.6.2008, 10:21
ИМХО приблизительно так :
Выполняется цепочка вызова
WinMainCRTStartup()->WinMain()->AfxWinMain()
В AfxWinMain() из интересного происходит 
Код

//...
CWinThread* pThread = AfxGetThread();
//...
pThread->InitInstance();
//...

Последняя строчка выполнется в контексте единственного объекта класса-потомка CWinApp - theApp. Похоже, что InitInstance() можно сравнить с функцией main для консоли, т.к ее начало - первое место(ну кроме разве что конструкторов глобальных переменных), которое позволено редактировать программисту и с ее концом, фактически программа завершается (только для диалоговых приложений). Если определить в нем объект класса-потомка CDialog, и вызвать метод DoModal(), то выполнение программы сосредоточится в цикле выборки сообщений CWnd::RunModalLoop(). Теперь если приложение получит какое-либо сообщения, то будет вызвана цепочка AfxWndProc()->AfxCallWndProc()->CWnd::WindowProc()->CWnd::OnWndMsg()->М
етод_Окна_Созданного_в_InitInstance(). Причем вызов последней функции осуществится при наличии соответствующей записи в таблице откликов - коде между
Код

BEGIN_MESSAGE_MAP
END_MESSAGE_MAP
.
MFC сохраняет все созданные CWnd и соответствующие им HWND, а также единственный CWinThread в определенной области памяти, поэтому у нее не возникает вопросов в плане определения с чем она работает. А вообще разбираться в принципах MFC дело неблагодарное, уж лучше запоминать факты...

Автор: Алексеу 4.6.2008, 21:31
Интересно, а можно ли узнать где-то hwnd, которое назначается автоматически в оболочке?

Сегодня попробовал использовать мастер создания диалогового окна - создало около 10 файлов на обычное окно. Вообще глаза на лоб вылазят. Как можно в этом разобраться?..

Автор: dizzy1984 5.6.2008, 05:20
Для диалога
Код

AfxGetApp()->m_pMainWnd->m_hWnd
AfxGetMainWnd()->m_hWnd

Цитата(Алексеу @  4.6.2008,  23:31 Найти цитируемый пост)
 Вообще глаза на лоб вылазят. Как можно в этом разобраться?..

Кстати, кроме всего прочего создается readme.txt, где описаны некоторые из них.

Автор: Earnest 5.6.2008, 12:40
Цитата(Алексеу @  4.6.2008,  22:31 Найти цитируемый пост)
создало около 10 файлов на обычное окно. Вообще глаза на лоб вылазят.

Ну это ты лукавишь. Создавал ты, видимо, диалоговое приложение, а там не одно окно, а несколько классов. Вот по 2 файла на 
класс тебе и сгенерили. Спасибо скажи, что руками это делать не пришлось. 
Кстати, там обычно прилагается readme.txt, где вкратце описано что где.
Вообще, установка - отдельные файл (пара h+cpp) на класс - очень полезная, даже если поначалу кажется, что удобнее все валить в один файл. Зато при поддерже сильно упорядочивает и облегчает жизнь...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)