Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> WNDPROC, Как обмануть VC? как ? взять адрес виртуального метода 
:(
    Опции темы
LabelZero
Дата 24.1.2004, 03:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 24.1.2004
Где: СПБ

Репутация: нет
Всего: нет



У меня возник тупой вопрос при написании простейшего класса окна на VC: каким образом взять адрес метода, который будет оконной процедурой и запихать в структуру окна? Вот о чем я говорю:

WNDCLASSEX wc;
wc.lpfnWndProc = (WNDPROC)WndProcedure;

присваивается только ф-я(не член класса), и static.
Если далаем static, получается бред...
Простой ф-ей не удобно, хочу юзать ООП smile.gif

WndProcedure хотелось бы сделать членом класса... но увы.
(кстати таже проблема и с CreateThread, LPTHREAD_START_ROUTINE)

Подскажите, как этот идиотизм обходитьconfused.gif

Это сообщение отредактировал(а) LabelZero - 24.1.2004, 06:55
PM MAIL ICQ   Вверх
RAN
Дата 24.1.2004, 07:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Я на этот вопрос сотню раз отвечал. Эй, модераторы FAQ, добавть эту тему у себя.
http://forum.vingrad.ru/index.php?act=ST&f=1&t=12981
http://forum.vingrad.ru/index.php?act=ST&f=1&t=10320
PM MAIL ICQ   Вверх
LabelZero
Дата 24.1.2004, 08:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 24.1.2004
Где: СПБ

Репутация: нет
Всего: нет



ха-ха! все равно через }|{0ny!!! сорри, конечно, у меня подобные способы smile.gif
хотя есть и более извращенные методыsmile.gif
гыыыыsmile.gif
PM MAIL ICQ   Вверх
LabelZero
Дата 24.1.2004, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 24.1.2004
Где: СПБ

Репутация: нет
Всего: нет



в общем спасибо RAN
PM MAIL ICQ   Вверх
RAN
Дата 24.1.2004, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



при чём тут жопа? Ты думаешь в MFC или ещё где это по другому?
Windows API в понятиях С++ не объектно-ориентирована. В нем есть задатки ООП. Поэтому только так. Тут ничего не придумаешь.
PM MAIL ICQ   Вверх
mr.DUDA
Дата 24.1.2004, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



LabelZero, можно взять адрес виртуального метода (здесь описано, как), но смысла в этом нет, т.к. WinAPI будет пытаться вызвать обычную callback-функцию, а для корректного вызова (даже виртуального) метода требуется указатель на объект, в котором метод находится (о чём WinAPI, конечно же, понятия не имеет, "видя" обычный указатель на функцию).

Здесь подойдёт вариант с глобальной функцией-заглушкой, которая будет брать из GetWindowLong указатель на объект нашего класса и вызывать виртуальный метод WndProc, который можно переопределить в производных классах (и который будет вызывать обработчики для каждого конкретного сообщения - OnMouseMove и т.п.). Таким же способом построена оконная часть библиотеки MFC.

Вот пример, как всё это можно реализовать на чистом WinAPI:
Цитата
class CGenericWnd
{
public:
       CGenericWnd();

       HWND m_hWnd;

       bool RegisterWindowClass(HINSTANCE hInstance,
                     char *szWindowClass, UINT idMenu,
                     UINT idIcon, UINT idIconSmall);
       bool Create(HINSTANCE hInstance, char *szWindowClass,
                     DWORD dwStyle, DWORD dwExStyle, RECT rect,
                     HWND hWndParent, HMENU hMenu, char *szTitle);

protected:
       virtual LRESULT WndProc(UINT, WPARAM, LPARAM) = 0;
       friend LRESULT WINAPI WndProcCallback(HWND, UINT, WPARAM, LPARAM);
};



// функция-заглушка
LRESULT WINAPI WndProcCallback(HWND hWnd, UINT msg, WPARAM w, LPARAM l)
{
       CGenericWnd *pWnd = (CGenericWnd*) GetWindowLong(hWnd, GWL_USERDATA);
       return pWnd->WndProc(msg, w, l);
}



//////////////////////////////////////////////////////////////////////////


CGenericWnd::CGenericWnd()
{
       m_hWnd = NULL;
}


bool CGenericWnd::RegisterWindowClass(HINSTANCE hInstance,
                     char *szWindowClass,  UINT idMenu, UINT idIcon,
                     UINT idIconSmall)
{
       WNDCLASSEX wcex;

       wcex.cbSize = sizeof(WNDCLASSEX);
       wcex.style = CS_HREDRAW | CS_VREDRAW;
       wcex.lpfnWndProc = WndProcCallback;
       wcex.cbClsExtra = 0;
       wcex.cbWndExtra = 0;
       wcex.hInstance  = hInstance;
       wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)idIcon);;
       wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
       wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
       wcex.lpszMenuName = (LPCSTR)idMenu;
       wcex.lpszClassName = szWindowClass;
       wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)idIconSmall);

       return RegisterClassEx(&wcex)?true:false;
}


bool CGenericWnd::Create(HINSTANCE hInstance, char *szWindowClass,
              DWORD dwStyle, DWORD dwExStyle, RECT rect,
              HWND hWndParent, HMENU hMenu, char *szTitle)
{
       m_hWnd = CreateWindowEx(dwExStyle, szWindowClass, szTitle,
              dwStyle, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
              hWndParent, NULL, hInstance, (LPVOID)this);

       return m_hWnd?true:false;
}


//////////////////////////////////////////////////////////////////////////


// пример нашего собственного оконного класса
class CMyWnd: public CGenericWnd
{
protected:
       virtual LRESULT WndProc(UINT msg, WPARAM w, LPARAM l)
       {
              switch(msg)
              {
              case WM_MOUSEMOVE:
                     OnMouseMove(LOWORD(l), HIWORD(l), w);
                     return 1;
              default:
                     return 0;
              }
       }

public:

       void OnMouseMove(int xPos, int yPos, UINT keys)
       {
              // ...
       }
};



to RAN,

мне кажется, нужно набросать какой-то пример, который можно скомпилировать и использовать в проектах. Не добавлять же в FAQ тему типа "в CreateWindow и CreateThread нельзя передавать указатель на метод" и пару строк кода, объясняющих - почему... wink.gif


--------------------
user posted image
PM MAIL WWW   Вверх
LabelZero
Дата 24.1.2004, 23:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 24.1.2004
Где: СПБ

Репутация: нет
Всего: нет



RAN это и так понятно, Маздай он и есть Маздай, увы.
кстати, в VCL вроде еще страшнее реализовано(как мне показалось), посмотрел на пару таких вещей(VCL, MFC, ATL...) и решил поискать что-нть поинтереснее, попроще.
в общем еще раз сенкс, народ.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0734 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.