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

Ваш аккаунт

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

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

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

делегирование вызовов процедуре класса

1.9K
17 августа 2005 года
smax13
63 / / 03.08.2004
привет.
объясните мне, пожалуйста, следующую вещь.
создаётся класс MDI-приложения. при регистрации выделяется память для указателя на объект

класса:

1.WNDCLASS wc.cbWndExtra=sizeof(CMDIFrame*);

члену же wc.lpfnWndProc присваивается указатель на глобальнуб ф-ию, выполняющую роль

процедуры "промежуточной":

2.wc.lpfnWndProc=(WNDPROC)::g_MDIFrameProc;

при создании окна последний параметр равен (LPVOID)this (собственно указатель на объект

класса):

3.m_hFrameHwnd=CreateWindow(...,(LPVOID)this);

для того, чтобы ф-ия g_MDIFrameProc перенаправляла сообщения функции члену класса (назовём

ее "процедурой класса"), я пишу внутри "промежуточной" следующее:

LRESULT CALLBACK g_MDIFrameProc(HWND hwnd, UINT msg, WPARAM wParam, LPARRAM lParam){
4.CMDIFrame* pFrame=(CMDIFrame*)GetWindowLong(hwnd,0);
5.if(pFrame==0) {
6. switch(msg) {
7. case WM_CREATE:{
8. LPCREATESTRUCT lpcs=(LPCREATESTRUCT)lParam;
9. pFrame=(CApp*)lpcs->lpCreateParams;
10. SetWindowLong(hwnd,0,(LONG)pFrame);
11. return pFrame->FrameProc(msg,wParam,lParam);
}
12. default: return DefFrameProc(hwnd,0,msg,wParam,lParam);
}
}
13.else return pFrame->FrameProc(msg,wParam,lParam);}

суть, если не совсем ясно:
стр.4-присваивание указателя на объект окна фрейма (при первых вызове процедуры равен 0).
стр.5-если этот указатель равен 0, и msg!=WM_CREATE все сообщения посылаются в процедуру по

умолчанию.
стр.7-когда приходит сообщение WM_CREATE, его lParam указывает на структуру CREATESTRUCT.
её параметр lpCreateParams равняется переданному (стр.3) указателю на объект класса.
затем происходит присваивание этого указателя локальной переменной (стр.9) и запись

его в память , связанную с созданным окном (стр.10).наконец, вызов поуказателю процедуря

класса(стр.11).
после этого по дескриптору окна фрейма можно добраться до указателя объекта "окно фрейма"
(стр.4) и перенапраить сообщение процедуе класса (стр.13).

главное
-------
почему аналогичный подход при создании дочернего окна не проходит:

если написать:

окно создаётся при помощи сообщения WM_MDICREATE:

BOOL CDocument::CreateDocument(LPTSTR windowtitle,HWND parent,DWORD

style=MDIS_ALLCHILDSTYLES){
14.MDICREATESTRUCT mcs;
15. mcs.szClass=m_lpszclassname;
16. mcs.szTitle="Document";
17. mcs.hOwner=m_hInstance;
18. mcs.x=mcs.cx=CW_USEDEFAULT;
19. mcs.y=mcs.cy=CW_USEDEFAULT;
20. mcs.style=MDIS_ALLCHILDSTYLES;
21. mcs.lParam=(LONG)this;//передаваемый указатель на создаваемый объект
22. m_hDocHwnd=SendMessage(parent,WM_MDICREATE,0,(LONG)(LPMDICREATESTRUCT)&mcs);}

LRESULT CALLBACK g_DocumentProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam){
23.CDocument* pDocument=pDocument=(CDocument*)GetWindowLong(hwnd,0);
24.if(pDocument==0){
25. switch(msg){
26. case WM_CREATE:{
27. LPCREATESTRUCT lpcs=(LPCREATESTRUCT)lParam;
28. MDICREATESTRUCT* mcs=(MDICREATESTRUCT*)lpcs->lpCreateParams;
29. pDocument=(CDocument*)mcs->lParam;
30. SetWindowLong(hwnd,0,(LONG)pDocument);
31. return pDocument->DocumentProc(msg,wParam,lParam);
}
32. default: return DefMDIChildProc(hwnd,msg,wParam,lParam);
}
}
33.else return pDocument->DocumentProc(msg,wParam,lParam);}

проиходят всякие нехорошие вещи (хорошо что система отказоустойчивая :}).
если убрать строки 27-30 включительно, всё работает отлично (может быть, на первый взгляд).
а если вместо this вставить 0, а строки 27-30 не убирать, то все тоже работает.

судя по выдаваемым собщениям, что-то не то с передаваемым указателем, но процедура класса
(CDocument::CocumentProc(...)) по этому указателю вызывается нормально(?!).
вопрос тогда: откуда этот указатель на объект берётся, если mcs.lParam=(LONG)0;(стр.21)?
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог