powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / класс-оболочка
15 сообщений из 15, страница 1 из 1
класс-оболочка
    #34507333
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VC2005/winapi

Приветствую всех!

Сижу уже целый день в гугле, глаза вместе с головой уже квадратно-гиперболические, но так и не нашел ни одного примера класса-оболочки для оконных классов static, button, edit и др. Кто-нибудь пробовал написать нечто подобное? Может знаете ссылки? Ну тогда вы просто обязаны в меня ими кинуть, в голову, желательно, аккурат между квадратно-гиперболические глаз.
HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
Проблема собственно в том, что не могу понять как мне обрабатывать сообщения поступающие к подобного рода классу.

Допустим у меня есть класс CMyStatic

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
class CMyStatic
{
private m_hWnd;
CMyStatic()
{
m_hWnd = CreateWindow("static", bla=bla-bla);
}

~CMyStatic(){DestroyWindow(m_hWnd;)}

};


есть глобальный обработчик сообщений для всех экземпляров этого класса

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

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

Спасибо!
...
Рейтинг: 0 / 0
класс-оболочка
    #34507366
ErV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum
есть глобальный обработчик сообщений для всех экземпляров этого класса

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
lParam);

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

Спасибо!

Вариант следующий.(Уже где-то предлагал, по-моему).

Создаем некий базовый класс для всех "своих" оконных элементов, в нем делаем
метод WndProc - виртуальный/абстрактный, например. А также делаем внутри
класса ещё одну оконную процедуру - статическую. При создании окна
устанавливаем При помощи SetWindowLongPtr (или как там его) поле
GWLP_USERDATA устанавливаем его в значение this. При создании окна передаем
оконную статическую оконную процедуру, где этот самый указатель берется,
преобразуется в this, и уже вызывается виртуальная оконая процедура
конкретно этого класса. Т.е. что-то вроде:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
class MyWindowClass{
public:
  virtual LRESULT wndProc (HWND hWnd, UINT msg, WPARAM wparam, LPARAM
lparam);
protected:
  static LRESULT WINAPI commonWndProc(HWND hWnd, UINT msg, WPARAM wparam,
LPARAM lparam);
};

LRESULT WINAPI MyWindowClass::commonWndProc(HWND...){
        MyWindowClass* ptr = (MyWindowClass*)GetWindowLongPtr(HWND, GWLP_USERDATA);
        if (ptr)
                return ptr->wndProc(hwnd, msg, wparam, lparam);
        else
                return DefaultWndProc(hwnd, msg, wparam, lparam);
}
Это даст возможность делать виртуальные разработчики. Естественно, что при
инициализации окна передаем ему в качестве оконной процедуры
MyWindowClass::commonWndProc, а потом устанавливаем пол GWLP_USERDATA в
указатель равный this...

Если нужно именно для каждого экземпляра свой, то можно сделать поле
указатель на функцию, запихнуть его в класс и вызывать его...


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
класс-оболочка
    #34507512
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
спасибо , дружище, буду пробовать
...
Рейтинг: 0 / 0
класс-оболочка
    #34507832
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
маленько запутался.... :)

итак,
1. Создаем базовый класс, пусть будет как у тебя

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
class MyWindowClass{
protected:
    HWND m_hWnd;
public:
  virtual LRESULT wndProc (HWND hWnd, UINT msg, WPARAM wparam, LPARAM
lparam);
protected:
  static LRESULT WINAPI commonWndProc(HWND hWnd, UINT msg, WPARAM wparam,
LPARAM lparam);
};

LRESULT WINAPI MyWindowClass::commonWndProc(HWND...){
        MyWindowClass* ptr = (MyWindowClass*)GetWindowLongPtr(HWND, GWLP_USERDATA);
        if (ptr)
                return ptr->wndProc(hwnd, msg, wparam, lparam);
        else
                return DefaultWndProc(hwnd, msg, wparam, lparam);
}

2. Нужен класс CMyStatic производный от MyWindowClass

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
class CMyStatic : public CMyWindowClass
{
CMyStatic()
{
m_hWnd = CreateWindow("static", bla=bla-bla);
// вот здесь у меня затык: что, кто, кому передает?
// по идее я хотел бы использовать функции класса CMyStatic, внутри switch() блока обработчика
// сообщений контрола, который, опять же, по идее, должен располагаться внутри области 
// видимости CMyStatic, т.е. быть функцией-членом класса CMyStatic, т.к. основным полем битвы
// предполагает выступать именно этот класс, а не CMyWindowClass, да и передать указатель можно
// только лишь через глобальную функцию WindowProc, так как это было сказано

здесь
Код: plaintext
1.
2.
}
~CMyStatic(){DestroyWindow(m_hWnd;)}
};

В общем опять туплю не по децки, на тебя одна надежда...help
...
Рейтинг: 0 / 0
класс-оболочка
    #34507905
ErV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
class CMyStatic : public CMyWindowClass
{
CMyStatic()
{
m_hWnd = CreateWindow("static", bla=bla-bla);
// вот здесь у меня затык: что, кто, кому передает?
// по идее я хотел бы использовать функции класса CMyStatic, внутри switch()
блока обработчика
// сообщений контрола, который, опять же, по идее, должен располагаться
внутри области 
// видимости CMyStatic, т.е. быть функцией-членом класса CMyStatic, т.к.
основным полем битвы
// предполагает выступать именно этот класс, а не CMyWindowClass, да и
передать указатель можно
// только лишь через глобальную функцию WindowProc, так как это было сказано


Вообще вот так:
Код: plaintext
1.
2.
3.
4.
class CMyStatic : public CMyWindowClass{
   CMyStatic(){
      m_hWnd = CreateWindow("static", bla=bla-bla);
      SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR)this);

я такую вещь делал когда-то через SetWindowLong, но сейчас появились
64битные системы, а SetWindowLong на 64бит работать не будет по понятным
причинам.

ЗЫ. Обернуть бы это все как-нибудь по-красивей виртуальными методами :-\ А
то немного коряво получается - так как в конструктор виртуальные методы
вызывать бесполезно...

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
класс-оболочка
    #34507919
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да насчет обертки я тоже так думаю, но это потом, а пока мне надо понять логику, а то у меня складывается впечатление, что мы говорим о разных вещах.

Я правильно понял, ты предлагаешь использовать потом в глобальном обработчике сообщений для класса CMyStatic нечто подобное
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_PAINT:
{
CMyStatic* pStatic = (CMyStatic*) GetWindowLongPtr(HWND, GWLP_USERDATA);
pStatic->SomeFunction();
.....
return 0L;
}
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
...
Рейтинг: 0 / 0
класс-оболочка
    #34508218
ErV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum
да насчет обертки я тоже так думаю, но это потом, а пока мне надо понять
логику, а то у меня складывается впечатление, что мы говорим о разных
вещах.

Я правильно понял, ты предлагаешь использовать потом в глобальном
обработчике сообщений для класса CMyStatic нечто подобное

Нет, не правильно.

Я вот это имел в виду:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
class MyWindowClass{
public:
  virtual LRESULT wndProc (HWND hWnd, UINT msg, WPARAM wparam, LPARAM
lparam);
protected:
  static LRESULT WINAPI commonWndProc(HWND hWnd, UINT msg, WPARAM wparam,
LPARAM lparam);
  HWND m_hWnd;
  MyWindowClass();
};

LRESULT WINAPI MyWindowClass::commonWndProc(HWND...){
        MyWindowClass* ptr = (MyWindowClass*)GetWindowLongPtr(HWND,
GWLP_USERDATA);
        if (ptr)
                return ptr->wndProc(hwnd, msg, wparam, lparam);
        else
                return DefaultWndProc(hwnd, msg, wparam, lparam);
}

MyWindowClass::MyWindowClass(){
   ...
   m_hWnd = CreateWindow("static", bla=bla-bla);
   SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR)this);
   ...
}

LRESULT MyWindowClass::wndProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM
lparam){
    switch (msg){
        case (WM_PAINT):
            BeginPaint(..
            и т.д.
            break;
        default:
            return DefWndProc(hwnd, msg, wparam, lparam);
    }
}

MyWindowClass::commonWndProc будет одна для всех классов, никогда не будет
меняться. Её можно будет запихнуть даже в private а оверрайды/обработку
сообщений переопределять (wndProc) в каждом из потомков MyWindowClass, при
этом все будет работать. Конечно, работать будет только если поле
GWLP_USERDATA будет устновлено в this и класс будет производным от
MyWindowProc. Потом можно офигеть и вычленить каждое из нужных сообщений,
сделать обертку для них в виде виртуальных функций или присваиваемых
переменных, и получится новый VCL :) Пример потомка (для разъяснений):

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
class NewWindowClass: public MyWindowClass{
public:
    LRESULT wndProc(HWND hWnd, UING msg, WPARAM wparam, LPARAM lparam);
};

LRESULT NewWindowClass::wndProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM
lparam){
    if (msg == WMPAINT){
        ...
    }
    else
        return MyWindowClass::wndProc(hWnd, msg, wparam, lparam);
}
Т.е. commonWndProc определяется один раз и больше никогда не трогается. Она
нужна только для того, чтобы передать обработку сообщений внутрь класса,
которому принадлежит окно, больше ни для чего другого.

Вопросы?
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
класс-оболочка
    #34508500
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вопрос только один: почему я такой тупой, что сразу не допер!?
спасибо, Erv

пошел пробовать, а то что-то у меня такие чудеса начались, что даже самому старшно...
--------------------------------------------------------------
[не претендую на уникальность]
...
Рейтинг: 0 / 0
класс-оболочка
    #34508984
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
немного оффтоп, но возможно что он как-то связан с тем что я затеял

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
class CMyStatic
{
public:
 m_hWnd;
CMyStatic()
{
m_hWnd = CreateWindow("static", WS_CHILD, bla-bla-bla);
// Если здесь проверить следующее, то все нормально
assert(IsWindow(m_hWnd));// все ок
}

~CMyStatic()
{
assert(IsWindow(m_hWnd));// вылетает как и положено при assert !!! П_О_Ч_Е_М_У_?
DestroyWindow(m_hWnd;)
}

};

больше никаких функций в этом классе нет, то есть фактически я эмулирую создание и разрушение окна. Значение m_hWnd остается прежним, кто разрушает окно? Родитель?
--------------------------------------------------------------
[не претендую на уникальность]
...
Рейтинг: 0 / 0
класс-оболочка
    #34510722
ErV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum wrote:

> больше никаких функций в этом классе нет, то есть
> фактически я эмулирую создание и разрушение окна. Значение m_hWnd остается
> прежним, кто разрушает окно?

Идей нету. Винды под рукой тоже. Можно почитать справку. Или отладить с
установкой бряков.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
класс-оболочка
    #34511009
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum пишет:

> больше никаких функций в этом классе нет, то есть фактически я эмулирую
> создание и разрушение окна. Значение m_hWnd остается прежним, кто
> разрушает окно? Родитель?

Да кто угодно. Windows может разрушить.
Это не важно на самом деле. По концепции Windows окно - это объект,
как надо его разрушить, ему посылается WM_DESTROY.
Оно уничтожается.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
класс-оболочка
    #34511208
ErV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv
Да кто угодно. Windows может разрушить.
Это не важно на самом деле. По концепции Windows окно - это объект,
как надо его разрушить, ему посылается WM_DESTROY.
Оно уничтожается.

ПО моему, понял. В оконной процедуре вызывается DefWindowProc (или как там
её), она и гасит окно... Хотя и другие вариант могут быть. (Если честно,
никогда не делал IsWindow перед DestroyWindow).
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
класс-оболочка
    #34511398
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тоже решил забить, просто делаю DestroyWindow(), если hWnd != NULL;
спасибо
--------------------------------------------------------------
[не претендую на уникальность]
...
Рейтинг: 0 / 0
класс-оболочка
    #34513602
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну вот, создание оконной библиотеки с нуля: http://www.relisoft.com/win32/index.htm
...
Рейтинг: 0 / 0
класс-оболочка
    #34513808
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maXmoну вот, создание оконной библиотеки с нуля: http://www.relisoft.com/win32/index.htm
премного благодарен!
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / класс-оболочка
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]