Оффтоп по С++ (callback и ООП)

Тема в разделе "WASM.ZEN", создана пользователем Foamplast, 11 дек 2004.

  1. Foamplast

    Foamplast New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2003
    Сообщения:
    80
    Адрес:
    Russia
    При программировании GUI некоторым функциям бывает необходимо указывать адрес callback-функции. А у меня программа на С++ состоит из классов. Хотелось бы эту callback включить, например, в класс интерфейса. Как это можно сделать?



    Если ещё не понятно, вот пример:



    Есть класс интерфейса. При создании окна необходимо члену структуры WNDCLASS присвоить адрес оконной процедуры, она вызывается через STDCALL, а методы класса вызываются по-другому. Поэтому нельзя передать в WNDCLASS адрес метода. Как тогда структурировать программу? (Хочу все callback собрать в кучу, желательно в классе интерфейса)
     
  2. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Не совсем уверен, что правильно понял. оконую процедуру делаешь static, this ложишь в lpParam при создании окна, потом вытаскиваешь его и можно вызывать виртуальные и thiscall функции:


    Код (Text):
    1.  
    2. #ifndef IMAGE_BASE
    3. #define IMAGE_BASE  0x400000
    4. #endif
    5.  
    6.  
    7. class   window
    8. {
    9. public:
    10.  
    11. window(const char * name, const int width, const int height,
    12.             const int x = CW_USEDEFAULT, const int y = CW_USEDEFAULT)
    13.         :   name(name), width(width),height(height), x(x), y( y)
    14. {}
    15.  
    16. void create(int extended_style, int style, HWND parent);
    17.  
    18. static int  message_loop()
    19. {
    20.     MSG msg;
    21.  
    22.     while(!0)
    23.         if( PeekMessageA(&msg, 0, 0, 0, PM_REMOVE) )
    24.         {
    25.             if( msg.message == WM_QUIT )
    26.                 return(msg.wParam);
    27.             TranslateMessage(&msg);
    28.             DispatchMessageA(&msg);
    29.         }
    30.         else
    31.         {
    32.             Sleep(2);
    33.         }
    34. }
    35.  
    36. protected:
    37.  
    38.     HWND                handle;
    39.     int                 x, y, width, height;   
    40.     const char        * name;
    41.  
    42. virtual void
    43. window_procedure(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    44. {
    45.     // code goes here
    46.     if( msg == WM_DESTROY )
    47.         PostQuitMessage(0);
    48. }
    49.  
    50. static LRESULT __stdcall
    51. dispatcher(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    52. {
    53.     if( msg == WM_NCCREATE )
    54.     {
    55.         ((window*)((CREATESTRUCTA*)lParam)->lpCreateParams)->handle = hWnd;
    56.  
    57.         SetWindowLongA(hWnd, GWL_USERDATA,
    58.             (long)((CREATESTRUCTA*)lParam)->lpCreateParams);
    59.     }
    60.     else if(window * This = (window*)GetWindowLongA(hWnd,GWL_USERDATA))
    61.         This->window_procedure(hWnd, msg, wParam, lParam);
    62.    
    63.     return DefWindowProcA(hWnd,msg,wParam,lParam);
    64. }
    65.  
    66. static const char   class_name[];
    67.  
    68. };
    69.  
    70. //==================================================================== =====//
    71.  
    72. const char window::class_name[] = "foo";
    73.  
    74. void        window::
    75. create(int extended_style, int style, HWND parent)
    76. {
    77.     WNDCLASSEX  wnd_class;
    78.  
    79.     wnd_class.cbSize        = sizeof(wnd_class);
    80.     wnd_class.style         = 0;
    81.     wnd_class.lpfnWndProc   = window::dispatcher;
    82.     wnd_class.cbClsExtra    = 0;
    83.     wnd_class.cbWndExtra    = 0;
    84.     wnd_class.hInstance     = (HINSTANCE)IMAGE_BASE;
    85.     wnd_class.hIconSm       =
    86.     wnd_class.hIcon         = LoadIconA(NULL, IDI_WINLOGO);
    87.     wnd_class.hCursor       = LoadCursorA(NULL, IDC_ARROW);
    88.     wnd_class.hbrBackground = NULL;
    89.     wnd_class.lpszMenuName  = NULL;
    90.     wnd_class.lpszClassName = class_name;
    91.  
    92.     RegisterClassExA(&wnd_class);
    93.     CreateWindowExA(extended_style, class_name, name, style,
    94.                     x, y, width, height, parent, NULL,
    95.                     (HINSTANCE)IMAGE_BASE, this);
    96. }
    97.  
    98.  
     
  3. Foamplast

    Foamplast New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2003
    Сообщения:
    80
    Адрес:
    Russia
    Спасибо, попробую так сделать.