Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.73/26: Рейтинг темы: голосов - 26, средняя оценка - 4.73
 Аватар для bretba
63 / 58 / 13
Регистрация: 24.07.2011
Сообщений: 343

Функция обратного вызова в классе

29.11.2011, 16:04. Показов 5323. Ответов 29
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Такие проблемы возникли у меня.
Есть два класса.В одном классе относится к окну(создание,регистрация и тд),а второй класс это таймер(включение,отключение таймера и тд)
Так вот мне почему-то пишет ошибки
КОД:
Это класс "создания окна" файл CWindows.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <windows.h>
#include <windowsx.h>
#include<stdlib.h>
#include <wchar.h>
 
class WINDOWMAIN
{
public:
    HWND hwnd;
    void Create_Window(LPCWSTR Name_Prog);
    void Create_Button(LPCWSTR text,int x,int y,int x2,int y2);
    void Show_Window();
    bool Reg_Window(HINSTANCE hInstance,LPCWSTR lpzClassName,WNDPROC lpfnWndProc);
    HDC Get_DC(HWND hwnd);
private:
    WNDCLASS we;
};
Это описание методов класса файл CWindows.cpp
C++
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
#include "CWindows.h"
 
bool WINDOWMAIN::Reg_Window(HINSTANCE hInstance, LPCWSTR lpzClassName,WNDPROC lpfnWndProc)
   {
       ZeroMemory(&we,sizeof(we));
       we.lpfnWndProc=lpfnWndProc;
       we.hInstance=hInstance;
       we.hIcon=LoadIcon(NULL,IDI_APPLICATION);
       we.hCursor=LoadCursor(NULL,IDC_ARROW);
       we.hbrBackground=GetStockBrush(WHITE_BRUSH);
       we.lpszClassName= lpzClassName;
      if (RegisterClass(&we)!=0) 
            return true;
              else 
            return false;
   }
 
  void WINDOWMAIN::Create_Window(LPCWSTR Name_Prog)
  {
    hwnd=CreateWindow(L"MyWindowClass",Name_Prog,
WS_OVERLAPPEDWINDOW,500,200,230,250,
HWND_DESKTOP,NULL,NULL,NULL);  
  }
 
  void WINDOWMAIN::Show_Window()
  {
ShowWindow(hwnd,SW_SHOW);       
  }
 
 HDC WINDOWMAIN::Get_DC(HWND hwnd)
  {
     if (GetDC(hwnd)!=NULL)
      return GetDC(hwnd);
     else
         return NULL;
  }
Это класс таймера файл CTimer.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "CWindows.h"
 
class CTimer : WINDOWMAIN
{
public:
CTimer(UINT idTimer,UINT Interval);
void CTimer::operator=(bool fl);
private:
UINT idTimer;
UINT Interval;
static TIMERPROC OnTimer(HWND hwnd, UINT msg, UINT idTimer, DWORD dwTime);
static void CALLBACK TimerProc(HWND hwnd, UINT msg, UINT idTimer, DWORD dwTime);
};
Это описание методов класса таймера файл CTimer.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "CTimer.h"
#include "CWindows.h"
CTimer::CTimer(UINT idTimer,UINT Interval)
{
    if (Interval<0) Interval=Interval*(-1);
    if (Interval=0) Interval++;
}
 
void CTimer::operator=(bool fl)
{
    if (fl=true) SetTimer(WINDOWMAIN::hwnd,idTimer,Interval,(TIMERPROC)OnTimer); else KillTimer(WINDOWMAIN::hwnd,idTimer);
}
 
TIMERPROC CTimer::OnTimer(HWND hwnd, UINT msg, UINT idTimer, DWORD dwTime)
{
TimerProc(WINDOWMAIN::hwnd,WM_TIMER,idTimer,dwTime);
return 0;
}
И наконец главный файл,где все выполняется файл Main.cpp
C++
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
39
40
#include "CWindows.h"
#include "CTimer.h"
 
LRESULT CALLBACK  WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam);
HDC dc;
WINDOWMAIN MyObject; 
 
  int WINAPI  WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int )
 
   {
       MSG Msg;   
 
       if (MyObject.Reg_Window(hInstance,L"MyWindowClass",WndProc)) 
      {
          MyObject.Create_Window(L"Project");
          MyObject.Show_Window();
          dc=MyObject.Get_DC(MyObject.hwnd);
          
 
         while(GetMessage(&Msg,NULL,0,0))
           {    
             DispatchMessage(&Msg);
             TranslateMessage(&Msg);
           }
      }
return 0;
}
 
LRESULT CALLBACK  WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
{
    case WM_DESTROY:
PostQuitMessage(0);
    break;
 
default:
return(DefWindowProc(hWnd,uMsg,wParam,lParam)) ; 
}
}
Когда хочу выполнить код,выдает ошибку на файл CTimer.cpp на метод OnTimer,а именно на параметр WINDOWMAIN::hwnd функции TimerProc.
Ошибки такие:
1>c:\c++\mygame\cwindows.h(7): error C2011: 'WINDOWMAIN' : 'class' type redefinition
1> c:\c++\mygame\cwindows.h(7) : see declaration of 'WINDOWMAIN'
1>c:\c++\mygame\ctimer.cpp(11): error C2027: use of undefined type 'WINDOWMAIN'
1> c:\c++\mygame\cwindows.h(7) : see declaration of 'WINDOWMAIN'
1>c:\c++\mygame\ctimer.cpp(11): error C2065: 'hwnd' : undeclared identifier
1>c:\c++\mygame\ctimer.cpp(11): error C2027: use of undefined type 'WINDOWMAIN'
1> c:\c++\mygame\cwindows.h(7) : see declaration of 'WINDOWMAIN'
1>c:\c++\mygame\ctimer.cpp(11): error C2065: 'hwnd' : undeclared identifier
1>c:\c++\mygame\ctimer.cpp(16): error C2027: use of undefined type 'WINDOWMAIN'
1> c:\c++\mygame\cwindows.h(7) : see declaration of 'WINDOWMAIN'

Что делать...помогите пожалуйста
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
29.11.2011, 16:04
Ответы с готовыми решениями:

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

Процедура/функция обратного вызова в классе
Здравствуйте. Хочу сделать принадлежность процедуры/функции обратного вызова классу. Делаю это через классовые процедуры/функции: ...

Функция обратного вызова
Функция обратного вызова это та, которая передаётся в качестве аргумента другой функции и внутри неё вызывается. А вот функция,...

29
 Аватар для bretba
63 / 58 / 13
Регистрация: 24.07.2011
Сообщений: 343
20.12.2011, 01:13  [ТС]
Студворк — интернет-сервис помощи студентам
outoftime,у тебя функция TimerProc за пределами класса.Я так тоже сделал и все замечательно работает.Но как поместить ее в класс?Вот уже какую неделю сижу и не могу сделать
0
 Аватар для bretba
63 / 58 / 13
Регистрация: 24.07.2011
Сообщений: 343
27.12.2011, 01:37  [ТС]
кто нибудь поможет мне?

Добавлено через 23 часа 34 минуты
ну кто нибудь может помочь разобраться в этой проблеме?
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,361
Записей в блоге: 5
15.01.2012, 01:49
Цитата Сообщение от bretba Посмотреть сообщение
у тебя функция TimerProc за пределами класса.Я так тоже сделал и все замечательно работает.Но как поместить ее в класс?Вот уже какую неделю сижу и не могу сделать
Внимательно читаем код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once
 
#include <Windows.h>
 
namespace Helper
{
        static void CALLBACK TimerProc(HANDLE hTimer, BOOLEAN timerCalled);
        // 
        // WinAPI timer callback
        // 
        static void CALLBACK TimerProc(HANDLE hTimer, BOOLEAN timerCalled)
        {
                TimerWinApi* timer = static_cast<TimerWinApi *>(hTimer);
                timer->onTimerTick();
        };
}
0
 Аватар для bretba
63 / 58 / 13
Регистрация: 24.07.2011
Сообщений: 343
17.01.2012, 12:55  [ТС]
outoftime, все равно не могу понять..ты же создаешь пространство имен,а не класс..как так?
0
Исследователь
 Аватар для GrayWolf
318 / 317 / 24
Регистрация: 06.04.2011
Сообщений: 872
17.01.2012, 13:11
Иэх... Еще разок...

C++
1
2
3
4
5
6
7
class CMainForm
{
...
    static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    LRESULT WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
...
}
Теперь самое интересное - реализация:

C++
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
LRESULT CALLBACK CMainForm::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    CMainForm* pThis = NULL;
    
    switch(uMsg)
    {
        case WM_CREATE:
            // При создании окна сохраняем указатель на класс
            // в области дополнительных данных
            LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
            pThis = (CMainForm*)lpcs->lpCreateParams;
            SetWindowLongPtr(hWnd, GWL_USERDATA, (DWORD)pThis);
            break;
    } // switch(uMsg)
    
    // Считываем указатель на класс и вызываем не статическую функцию
    pThis = (CMainForm*)GetWindowLongPtr(hWnd, GWL_USERDATA);
    if(pThis) return pThis->WindowProc(hWnd, uMsg, wParam, lParam);
    else return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
 
LRESULT CMainForm::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        ...
    } // switch(uMsg)
    
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Код рабочий, проверял. Должен работать и при множественном количестве экземпляров класса.
0
 Аватар для bretba
63 / 58 / 13
Регистрация: 24.07.2011
Сообщений: 343
17.01.2012, 13:34  [ТС]
GrayWolf, почему вы показывается пример только с оконной функцией?Вы уже скидывали пример с ней,и по этому примеру я исправлял свои ошибки в программе с таймером.Сейчас я уже не знаю,что исправить.Код похож на ваш,но работать не хочет.Точнее программа заводится,а вот выполнять то,что я хочу,она не хочет-OnTimer НЕ ХОЧЕТ ВЫПОЛНЯТЬСЯ
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,361
Записей в блоге: 5
18.01.2012, 01:15
Цитата Сообщение от bretba Посмотреть сообщение
все равно не могу понять..ты же создаешь пространство имен,а не класс..как так?
А что, собственно, тебя смущает? Просто функция обработки таймера находится в другом пространстве имен, причем оно никак не пересекается с другими пространствами имен, именно поэтому я с чистой совестью могу использовать этот код.
0
 Аватар для bretba
63 / 58 / 13
Регистрация: 24.07.2011
Сообщений: 343
18.01.2012, 01:32  [ТС]
Я не хочу использовать пространства имен.Я хочу чтобы эта функция была в классе и все))блин..тема уже создана около месяца и никто не может помочь...

в принципе это мне нужно только для собственного развития.Я хочу сделать именно так,и никак иначе.Я даже готов заплатить за данные знания,главное помогите с моим кодом.Почему он не работает?
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,361
Записей в блоге: 5
18.01.2012, 01:56
Никак ты так не сделаешь, вин апи - это набор сишных функций, ниокаких классах тогда не думали, о черной магии си еще не знали по-этому (ИМХО) предложеное мной решение является одиним из лучших в условиях данной задачи.
0
 Аватар для bretba
63 / 58 / 13
Регистрация: 24.07.2011
Сообщений: 343
18.01.2012, 23:08  [ТС]
не поможете мне?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.01.2012, 23:08

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

Функция обратного вызова
Доброго времени суток уважаемые гуру программирования! Нужна помощь! В описании к DLL есть функция: function...

Функция обратного вызова
#undef UNICODE #include &lt;windows.h&gt; #include &quot;resource.h&quot; #include &lt;iostream&gt; #include &lt;fstream&gt; using namespace std; HWND...

Как создайтся функция обратного вызова?
Покажите мастер-класс как создавать функции обратного вызова и использовать их.

Процедура обратного вызова
Немного запутался в процедурах обратного вызова, в процедурных типах. Есть DLL и описание к ней. ... type TFullCardInfo =...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Новые блоги и статьи
Как надо было делать правильно - вообще не слушать ИИ, его дело - текст.
Hrethgir 15.07.2026
А вообще надо было делать не так, чтобы не исправлять ошибку https:/ / www. cyberforum. ru/ blogs/ 223907/ 10996. html , правильно было : удалил кнопку, а потом добавил её. Всё это стресс конечно. Почему?. . .
Знаете, от чего появляется стресс?
kumehtar 15.07.2026
Стресс появляется оттого, что вы, зная как поступить правильно, делаете наоборот. Ларри Уингет
Нас бьют, а мы крепчаем? Какая чушь!
kumehtar 15.07.2026
Вот это вот бытующее мнение, что человек меняется только под действием проблем, всегда считал вредоносным. Поверь, от проблем у людей появляются не изменения, а нервное расстройство и ПТСР. А. . .
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы ## О чём эта статья В процессе построения ОДУ-модели (система дифференциальных. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru