borisbn

gui_mover

Jun 18th, 2013
341
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.49 KB | None | 0 0
  1. #if !defined( _GUI_MOVER_H_INCLUDED_ )
  2. #define _GUI_MOVER_H_INCLUDED_
  3.  
  4. #if ! defined( _WIN32 )
  5. typedef unsigned int UINT;
  6. typedef void* WPARAM;
  7. typedef void* LPARAM;
  8. #endif
  9.  
  10. #if defined( _WIN32 )
  11.     #include <windows.h>
  12. #endif
  13. #include <map>
  14.  
  15. /** \brief Используется для "перекладывания" сообщений в GUI-поток
  16.  
  17.     Использование:
  18.     \code
  19.     class GuiClass {
  20.         enum MessageIds {
  21.             Message1,
  22.             Message2
  23.         };
  24.         struct StructForMessage2
  25.         {
  26.             std::string ip;
  27.             int port;
  28.             void * data;
  29.             int count;
  30.         };
  31.         void onMessage( MessageIds id, WPARAM wParam, LPARAM lParam ) {
  32.             switch ( id ) {
  33.                 case Message1: {
  34.                     int some1 = (int)wParam;
  35.                     int some2 = (char *)lParam;
  36.                     // do some deal with some1 and some2
  37.                 }
  38.                 break;
  39.                 case Message2: {
  40.                     StructForMessage2 * some = (StructForMessage2*)wParam;
  41.                     // do some deal with some->ip, some->port etc.
  42.                 }
  43.                 break;
  44.             }
  45.         }
  46.         GuiMover< GuiClass, MessageIds > m_guiMover;
  47.         GuiClass() : m_guiMover( & GuiClass::onMessage, this ) {}
  48.         // ----------------------------------------
  49.         void onWorkingThreadMessage1( int some1, char * some2 ) {
  50.             m_guiMover.move( Message1, some1, some2 );
  51.         }
  52.         void onWorkingThreadMessage2( const char * ip, int port, void * data, int count ) {
  53.             StructForMessage2 some( ip, port, data, count ); // да. нет у StructForMessage2 такого ctor-а. И ЧО ?
  54.             m_guiMover.move( Message2, &some );
  55.         }
  56.     };
  57.     \endcode
  58.  
  59.     Внимание! В функцию GuiMover::move 2-м и 3-м параметром можно передавать только простые типы или указатели.
  60.     Другими словами только то, что приводится к void*
  61.  
  62.     Внимание 2! В функции GuiMover::move делается SendMessage, поэтому,
  63.     -# этот класс нельзя использовать в приложении, в котором не запущен поток обработки сообщений (например, в консольном)
  64.     -# в функции-обработчике (которая передаётся в конструкторе) желательно проводить как можно меньше времени
  65. */
  66.  
  67. template< class Master, class MsgId >
  68. class GuiMover
  69. {
  70.     typedef void (Master::*wait_func)( MsgId id, WPARAM wParam, LPARAM lParam );
  71. public:
  72.     GuiMover( wait_func waitFunc, Master * master );
  73.     void move( MsgId message, WPARAM wParam = 0, LPARAM lParam = 0 );
  74.     ~GuiMover();
  75.  
  76. #if defined( _WIN32 )
  77. private:
  78.     static LRESULT CALLBACK s_netWndProc( HWND hWnd, UINT wm_message, WPARAM wParam, LPARAM lParam )
  79.     {
  80.         GuiMover< Master, MsgId > * self = ( GuiMover< Master, MsgId > * )GetWindowLongPtr( hWnd, GWL_USERDATA );
  81.         if ( self && self->m_master && self->m_waitFunc )
  82.         {
  83.             typename Msg2IdsMap::const_iterator found = self->m_msg2ids.find( wm_message );
  84.             if ( found != self->m_msg2ids.end() )
  85.             {
  86.                 MsgId id = (*found).second;
  87.                 (self->m_master->*self->m_waitFunc)( id, wParam, lParam );
  88.             }
  89.         }
  90.         return 0;
  91.     }
  92.    
  93.     HWND m_wnd;
  94.     UINT m_maxWmMessage;
  95.     typedef std::map< MsgId, UINT > Ids2MsgMap;
  96.     typedef std::map< UINT, MsgId > Msg2IdsMap;
  97.     Ids2MsgMap m_ids2msg;
  98.     Msg2IdsMap m_msg2ids;
  99. #endif
  100.     wait_func m_waitFunc;
  101.     Master * m_master;
  102. };
  103.  
  104. #if defined( _WIN32 )
  105. template < class Master, class MsgId >
  106. GuiMover< Master, MsgId >::GuiMover( wait_func waitFunc, Master * master )
  107.     : m_maxWmMessage( 1 )
  108.     , m_waitFunc( waitFunc )
  109.     , m_master( master )
  110. {
  111.     m_wnd = CreateWindowA( "STATIC", "", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_MESSAGE, NULL, NULL, NULL);
  112.     SetWindowLongPtr( m_wnd, GWL_USERDATA, (LONG_PTR)this );
  113.     SetWindowLongPtr( m_wnd, GWL_WNDPROC, (LONG_PTR)s_netWndProc );
  114. }
  115.  
  116. template < class Master, class MsgId >
  117. void GuiMover< Master, MsgId >::move( MsgId id, WPARAM wParam, LPARAM lParam )
  118. {
  119.     UINT wm_message;
  120.     typename Ids2MsgMap::const_iterator found = m_ids2msg.find( id );
  121.     if ( found == m_ids2msg.end() )
  122.     {
  123.         wm_message = WM_USER + m_maxWmMessage;
  124.         m_maxWmMessage++;
  125.         m_ids2msg[ id ] = wm_message;
  126.         m_msg2ids[ wm_message ] = id;
  127.     }
  128.     else
  129.     {
  130.         wm_message = (*found).second;
  131.     }
  132.  
  133.     ::SendMessage( m_wnd, wm_message, wParam, lParam );
  134. }
  135.  
  136. template < class Master, class MsgId >
  137. GuiMover< Master, MsgId >::~GuiMover()
  138. {
  139.     DestroyWindow( m_wnd );
  140. }
  141.  
  142. #else // #if defined( _WIN32 )
  143. template < class Master, class MsgId >
  144. GuiMover< Master, MsgId >::GuiMover( wait_func waitFunc, Master * master )
  145.     : m_waitFunc( waitFunc )
  146.     , m_master( master )
  147. {
  148. }
  149.  
  150. template < class Master, class MsgId >
  151. void GuiMover< Master, MsgId >::move( MsgId id, WPARAM wParam, LPARAM lParam )
  152. {
  153.     (m_master->*m_waitFunc)( id, wParam, lParam );
  154. }
  155. template < class Master, class MsgId >
  156. GuiMover< Master, MsgId >::~GuiMover()
  157. {
  158. }
  159. #endif // #if defined( _WIN32 )
  160.  
  161. #endif //!defined( _GUI_MOVER_H_INCLUDED_ )
Advertisement
Add Comment
Please, Sign In to add comment