1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 # include "stringtool.h"
10 # include "multithread.h"
13 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18 <p>Before writing to omsgstream, you must acquire lock by calling
19 <code>acquire()</code>. Then after completion of writing, you
20 must call <code>release()</code>.</p>
22 <p>Omsgbuf calls <code>PostMessage(hwnd, messageid, 0,
23 (LPARAM)omsgbuf)</code> to notify that string is ready to get.
24 When the window (<code>hwnd</code>) get the message, you can get
25 the string containd in the omsgbuf by calling
26 <code>acquireString()</code>. After calling
27 <code>acquireString()</code>, you must / call releaseString().</p>
31 template<class T, size_t SIZE = 1024,
32 class TR = std::char_traits<T>, class A = std::allocator<T> >
33 class basic_msgbuf : public std::basic_streambuf<T, TR>, public SyncObject
36 typedef std::basic_string<T, TR, A> String; ///
37 typedef std::basic_streambuf<T, TR> Super; ///
40 HWND m_hwnd; /** window handle for
42 UINT m_messageId; /// messageid for notification
43 T *m_buf; /// for streambuf
44 String m_str; /// for notification
45 CriticalSection m_cs; /// lock
46 A m_allocator; /// allocator
49 if ( m_msgDebugLevel <= m_debugLevel ), message is displayed
52 int m_msgDebugLevel; ///
55 basic_msgbuf(const basic_msgbuf &); /// disable copy constructor
59 basic_msgbuf(UINT i_messageId, HWND i_hwnd = 0)
61 m_messageId(i_messageId),
62 m_buf(m_allocator.allocate(SIZE, 0)),
67 setp(m_buf, m_buf + SIZE);
74 m_allocator.deallocate(m_buf, SIZE);
77 /// attach/detach a window
78 basic_msgbuf* attach(HWND i_hwnd)
81 ASSERT( !m_hwnd && i_hwnd );
84 PostMessage(m_hwnd, m_messageId, 0, (LPARAM)this);
89 basic_msgbuf* detach()
98 HWND getHwnd() const { return m_hwnd; }
100 /// is a window attached ?
101 int is_open() const { return !!m_hwnd; }
103 /// acquire string and release the string
104 const String &acquireString()
118 void setDebugLevel(int i_debugLevel)
120 m_debugLevel = i_debugLevel;
124 int getDebugLevel() const { return m_debugLevel; }
127 typename Super::int_type overflow(typename Super::int_type i_c = TR::eof())
129 if (sync() == TR::eof()) // sync before new buffer created below
132 if (i_c != TR::eof())
134 *pptr() = TR::to_char_type(i_c);
138 return TR::not_eof(i_c); // return something other than EOF if successful
147 for (i = begin; i < end; ++ i)
152 if (m_msgDebugLevel <= m_debugLevel)
153 m_str += String(begin, end - begin);
154 setp(m_buf, m_buf + SIZE);
158 if (m_msgDebugLevel <= m_debugLevel)
159 m_str += String(begin, end - begin - 1);
161 setp(m_buf, m_buf + SIZE);
164 return TR::not_eof(0);
170 virtual void acquire()
176 virtual void acquire(int i_msgDebugLevel)
179 m_msgDebugLevel = i_msgDebugLevel;
183 virtual void release()
186 PostMessage(m_hwnd, m_messageId, 0, reinterpret_cast<LPARAM>(this));
187 m_msgDebugLevel = m_debugLevel;
194 template<class T, size_t SIZE = 1024,
195 class TR = std::char_traits<T>, class A = std::allocator<T> >
196 class basic_omsgstream : public std::basic_ostream<T, TR>, public SyncObject
199 typedef std::basic_ostream<T, TR> Super; ///
200 typedef basic_msgbuf<T, SIZE, TR, A> StreamBuf; ///
201 typedef std::basic_string<T, TR, A> String; ///
204 StreamBuf m_streamBuf; ///
208 explicit basic_omsgstream(UINT i_messageId, HWND i_hwnd = 0)
209 : Super(&m_streamBuf), m_streamBuf(i_messageId, i_hwnd)
214 virtual ~basic_omsgstream()
219 StreamBuf *rdbuf() const
221 return const_cast<StreamBuf *>(&m_streamBuf);
224 /// attach a msg control
225 void attach(HWND i_hwnd)
227 m_streamBuf.attach(i_hwnd);
230 /// detach a msg control
233 m_streamBuf.detach();
236 /// get window handle of the msg control
239 return m_streamBuf.getHwnd();
242 /// is the msg control attached ?
245 return m_streamBuf.is_open();
249 void setDebugLevel(int i_debugLevel)
251 m_streamBuf.setDebugLevel(i_debugLevel);
255 int getDebugLevel() const
257 return m_streamBuf.getDebugLevel();
260 /// acquire string and release the string
261 const String &acquireString()
263 return m_streamBuf.acquireString();
269 m_streamBuf->releaseString();
275 virtual void acquire()
277 m_streamBuf.acquire();
281 virtual void acquire(int i_msgDebugLevel)
283 m_streamBuf.acquire(i_msgDebugLevel);
287 virtual void release()
289 m_streamBuf.release();
294 typedef basic_omsgstream<_TCHAR> tomsgstream;
297 #endif // !_MSGSTREAM_H