TNB Library
TnbMfcRgnButton.h
[詳解]
1#pragma once
14#include "TnbBitmapImage.h"
15
16
17
18//TNB Library
19namespace TNB {
20namespace MFC {
21
22
23
71{
72 DEFSUPER(CAbstractButton);
73 CSize m_size;
74 COLORREF m_transColor;
75 HRGN m_hRgnClip;
76 HRGN m_hRgnCtrl;
77 bool m_boIsDoSetRgn;
78 CBitmapImage m_lastBitmap;
79 UINT m_bitmapChangeTime;
80 CPoint m_pushedOffset;
81 enum { TIMERID_DRAW = 1 };
83 void m_DeleteRgn(HRGN& _hRgn)
84 {
85 if ( _hRgn != NULL )
86 {
87 _DeleteObject(_hRgn);
88 _hRgn = NULL;
89 }
90 }
91 void m_DeleteRgns(void)
92 {
93 if ( ::IsWindow(m_hWnd) )
94 {
95 _super::SetWindowRgn(NULL, false);
96 }
97 m_DeleteRgn(m_hRgnClip);
98 m_DeleteRgn(m_hRgnCtrl);
99 }
100 void m_SetRgn(HRGN& _hRgn, HRGN h)
101 {
102 m_DeleteRgn(_hRgn);
103 _hRgn = ::CreateRectRgn(0, 0, 1, 1);
104 ::CombineRgn(_hRgn, h, NULL, RGN_COPY);
105 }
107 bool m_SetBaseBitmap(CBitmapHandle h, COLORREF color)
108 {
109 if ( h.GetSize(m_size) )
110 {
111 m_DeleteRgns();
112 CBitmapImage bi;
113 bi.Attach(h);
114 m_hRgnClip = bi.CreateRgn(color);
115 m_SetRgn(m_hRgnCtrl, m_hRgnClip);
116 m_boIsDoSetRgn = true;
117 _super::SetWindowPos(NULL, 0, 0, m_size.cx, m_size.cy, SWP_NOZORDER | SWP_NOMOVE);
118 _super::SetWindowRgn(NULL, true);
119 return true;
120 }
121 return false;
122 }
124 void m_DrawBmp(CDC* pDC, CBitmapHandle hb)
125 {
126 if ( hb == NULL ) { return; }
127 CPoint pos1(0, 0);
128 CPoint pos2((_super::GetButtonState() == ES_Pushed) ? m_pushedOffset : pos1);
129 OnDrawingButton(pos2, pDC, true);
130 MFCLIB::SelectClipRgnOrg(pDC, m_hRgnClip);
131// pDC->DrawState(pos1, m_size, hb, DST_BITMAP);
132 hb.Draw(*pDC, pos1.x, pos1.y);
133 OnDrawingButton(pos2, pDC, false);
134 if ( m_focusMaskColor != CLR_INVALID )
135 {
136 if ( _super::HasFocus() && ! m_focusBitmap.IsEmpty() )
137 {
138 const SIZE& s = m_focusBitmap.GetSize();
139 HDC hdc = m_focusBitmap.GetDC();
140 ::TransparentBlt(*pDC, pos2.x, pos2.y, s.cx, s.cy, hdc, 0, 0, s.cx, s.cy, m_focusMaskColor);
142 }
143 }
144 }
145
146protected:
147
151
159 virtual void OnDrawingButton(CPoint& _pos, CDC* pDC, bool boIsFirst)
160 {
161 }
162
167 virtual void OnDrawButton(CDC* pDC)
168 {
169 CBitmapHandle hb = m_bmpButtons[_super::GetButtonState()];
170 if ( hb.IsNull() )
171 {
173 }
174 if ( m_focusMaskColor == CLR_INVALID )
175 {
176 //フォーカスは、イメージ
177 if ( _super::GetButtonState() == ES_Normal && _super::HasFocus() && ! m_focusBitmap.IsEmpty() )
178 {
180 }
181 }
182 _super::KillTimer(TIMERID_DRAW);
183 if ( m_lastBitmap.IsEmpty() )
184 {
185 m_lastBitmap.Attach(hb);
186 m_DrawBmp(pDC, hb);
187 }
188 else if ( m_bitmapChangeTime == 0 || hb.IsNull() )
189 {
190 m_DrawBmp(pDC, hb);
191 }
192 else
193 {
194 CBitmapImage bi;
195 VERIFYLIB( bi.Set(hb) );
196// VERIFYLIB( bi.InsertOnSemitransparect(0, 0, m_lastBitmap, 50) );//50%合成
197 VERIFYLIB( bi.InsertOnAlphaBlend(0, 0, m_lastBitmap, 50) );//50%合成
198 m_DrawBmp(pDC, bi.GetBitmapHandle());
199 m_lastBitmap.Attach(hb);
200 _super::SetTimer(TIMERID_DRAW, m_bitmapChangeTime, NULL);
201 }
202 }
203
213 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
214 {
215 if ( message == WM_PAINT )
216 {
217 if ( m_boIsDoSetRgn )
218 {
219 m_boIsDoSetRgn = false;
220 _super::SetWindowRgn(m_hRgnCtrl, true);
221 m_hRgnCtrl = NULL; // 開放はWinが行う
222 _super::RedrawWindow();
223 return 0;
224 }
225 }
226 else if ( message == WM_SHOWWINDOW )
227 {
228 m_lastBitmap.Empty();
229 }
230 else if ( message == WM_DESTROY )
231 {
232 m_DeleteRgns();
233 }
234 else if ( message == WM_SETTEXT )
235 {
236 CString s = reinterpret_cast<LPCTSTR>(lParam);
237 int f = s.Find('&');
238 if ( f >= 0 && (f + 1) < s.GetLength() )
239 {
240 SetShortcutKey(s[f + 1]);
241 }
242 }
243 else if ( message == WM_TIMER && wParam == TIMERID_DRAW )
244 {
245 KillTimer(TIMERID_DRAW);
246 CClientDC dc(this);
247 m_DrawBmp(&dc, m_lastBitmap.GetBitmapHandle());
248 }
249 return _super::WindowProc(message, wParam, lParam);
250 }
251
257 virtual void PreSubclassWindow(void)
258 {
259 HBITMAP hBase = reinterpret_cast<HBITMAP>(::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_BITMAP, 0L));// GetBitmap()
260 if ( ! m_bmpButtons[ES_Normal].IsNull() )
261 {
262 if ( ! m_SetBaseBitmap(m_bmpButtons[ES_Normal], m_transColor) )
263 {
265 }
266 }
267 if ( m_bmpButtons[ES_Normal].IsNull() )
268 {
269 CRect rect;
270 _super::GetClientRect(rect);
271 if ( hBase == NULL )
272 {
273 HDC dc = ::GetDC(NULL);
274 hBase = ::CreateCompatibleBitmap(dc, rect.Width(), rect.Height());
275 ::ReleaseDC(NULL, dc);
276 m_bmpButtons[ES_Normal] = hBase;
277 }
278 else
279 {
281 }
282 VERIFYLIB( m_SetBaseBitmap(m_bmpButtons[ES_Normal], m_transColor) );
283 }
284 _super::PreSubclassWindow();
285 }
286
287public:
288
290 virtual ~CRgnButton(void)
291 {
292 m_DeleteRgns();
293 }
294
297 : m_boIsDoSetRgn(false), m_hRgnClip(NULL), m_hRgnCtrl(NULL), m_pushedOffset(0, 0)
298 , m_transColor(CLR_AUTOSELECT), m_focusMaskColor(CLR_INVALID), m_bitmapChangeTime(40)
299 {
300 }
301
310 {
311 _super::operator=(other);
312 m_size = other.m_size;
313 m_transColor = other.m_transColor;
314 m_boIsDoSetRgn = other.m_boIsDoSetRgn;
315 m_lastBitmap = other.m_lastBitmap;
316 m_bitmapChangeTime = other.m_bitmapChangeTime;
317 m_pushedOffset = other.m_pushedOffset;
320 loop ( i, 4 )
321 {
322 m_bmpButtons[i] = other.m_bmpButtons[i];
323 }
324 m_SetRgn(m_hRgnClip, other.m_hRgnClip);
325 if ( ! ::IsWindow(other) )
326 {
327 m_SetRgn(m_hRgnCtrl, other.m_hRgnCtrl);
328 }
329 else
330 {
331 other.GetWindowRgn(m_hRgnCtrl);
332 }
333 //
334 if ( ::IsWindow(m_hWnd) )
335 {
336 m_SetBaseBitmap(m_bmpButtons[ES_Normal], m_transColor);
337 }
338 return *this;
339 }
340
350 {
351 m_bitmapChangeTime = ms;
352 }
353
364 bool SetBitmap(CBitmapHandle bmp, COLORREF color = CLR_AUTOSELECT)
365 {
366 if ( bmp.IsNull() ) { return false; }
367 m_bmpButtons[ES_Normal] = bmp;
368 m_transColor = color;
369 if ( ::IsWindow(m_hWnd) )
370 {
371 if ( ! m_SetBaseBitmap(bmp, color) )
372 {
373 return false;
374 }
375 }
376 return true;
377 }
378
386 {
387 m_bmpButtons[ES_Pushed] = bmp;
388 }
389
397 {
399 }
400
408 {
409 m_bmpButtons[ES_Hover] = bmp;
410 }
411
420 {
421 m_focusBitmap.Set(bmp);
422 m_focusMaskColor = CLR_INVALID;
423 }
424
434 void SetFocusMarkBitmap(CBitmapHandle bmp, COLORREF color = CLR_AUTOSELECT)
435 {
436 m_focusBitmap.Set(bmp);
437 if ( ! IS_RGBVALUE(color) )
438 {
439 const SIZE& s = m_focusBitmap.GetSize();
440 HDC dc = m_focusBitmap.GetDC();
441 color = ::GetPixel(dc, 0, s.cy - 1);
443 }
444 m_focusMaskColor = color;
445 }
446
452 void SetPushedMarkOffset(const POINT& pos)
453 {
454 m_pushedOffset = pos;
455 }
456
468 bool SetAllBitmaps(CBitmapHandle bmp, COLORREF color = CLR_AUTOSELECT)
469 {
470 CBitmapImage baseImage;
471 if ( baseImage.Set(bmp) )
472 {
473 CSize baseSize = baseImage.GetSize();
474 bool r = true;
475 int x = 0;
476 int l = baseSize.cx / 5;
477 CBitmapImage bi;
478 for ( int i = 0; i < 5; i++ )
479 {
480 bi = baseImage.Cut(CRect(x, 0, x + l, baseSize.cy));
481 if ( i == 0 )
482 {
483 r &= SetBitmap(bi, color);
484 }
485 else if ( i == 4 )
486 {
487 SetFocusBitmap(bi);
488 }
489 else
490 {
491 m_bmpButtons[i] = bi;
492 }
493 x += l;
494 }
495 return r;
496 }
497 return false;
498 }
499
506 void SetValidRgn(HRGN h)
507 {
508 m_DeleteRgn(m_hRgnClip);
509 m_SetRgn(m_hRgnCtrl, h);
510 m_boIsDoSetRgn = true;
511 _super::RedrawWindow();
512 }
513};
514
515
516
517}; //MFC
518}; //TNB
519
520
521
ビットマップイメージ管理関係のヘッダ
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
ボタン抽象関係のヘッダ
HBITMAP型ハンドルハンドル
void SetClone(HBITMAP hBmp)
[設定] HBITMAPセット.
bool Draw(HDC hdc, int x=0, int y=0) const
[処理] イメージ描画.
ビットマップイメージ管理クラス
bool IsEmpty(void) const
[確認] Empty状態確認.
HRGN CreateRgn(COLORREF transColor=CLR_AUTOSELECT) const
[作成] リージョン作成.
HDC GetDC(void)
[取得]デバイスコンテキストハンドル取得.
bool Attach(CBitmapHandle bmp)
[設定] アタッチ.
CBitmapImage Cut(const RECT &rect, int cx=0, int cy=0) const
[取得] イメージ取り出し.
const SIZE & GetSize(void) const
[取得] イメージサイズ取得.
bool Set(int cx, int cy, COLORREF color=CLR_INVALID)
[設定] イメージ設定.
CBitmapHandle GetBitmapHandle(void)
[取得] ビットマップハンドル取得
bool ReleaseDC(void)
[設定] デバイスコンテキストハンドル返却.
void Empty(void)
[設定] 破棄.
bool InsertOnAlphaBlend(int x, int y, const CBitmapImage &bmpimg, int parsent=100, int cx=0, int cy=0)
[挿入] 半透過処理付イメージ挿入.
bool IsNull(void) const
[確認] NULLチェック
void Null(void)
[設定] 開放.
ボタンコントロール抽象クラス
void SetShortcutKey(TCHAR key)
[設定] ショートカットキー設定.
自由型ビットマップボタンコントロール
void SetDisableBitmap(CBitmapHandle bmp)
[設定] 無効状態ビットマップ指定.
virtual void OnDrawingButton(CPoint &_pos, CDC *pDC, bool boIsFirst)
[通知] 描画中.
COLORREF m_focusMaskColor
フォーカスマークの透過色(-1ならフォーカスはマークではなく直書き)
void SetPushedBitmap(CBitmapHandle bmp)
[設定] 押下状態ビットマップ指定.
void SetFocusBitmap(CBitmapHandle bmp)
[設定] フォーカス状態ビットマップ指定.
bool SetAllBitmaps(CBitmapHandle bmp, COLORREF color=CLR_AUTOSELECT)
[設定] ビットマップ指定.
void SetPushedMarkOffset(const POINT &pos)
[設定] 押下時表示ずれ設定.
CRgnButton(void)
コンストラクタ
void SetFocusMarkBitmap(CBitmapHandle bmp, COLORREF color=CLR_AUTOSELECT)
[設定] フォーカス状態マークビットマップ指定.
virtual ~CRgnButton(void)
デストラクタ
bool SetBitmap(CBitmapHandle bmp, COLORREF color=CLR_AUTOSELECT)
[設定] ベースビットマップ指定.
CBitmapHandle m_bmpButtons[4]
「通常」「ホバー」「押下」[無効」状態のBITMAP.
virtual void PreSubclassWindow(void)
[通知] subclassing/unsubclassing functions.
void SetValidRgn(HRGN h)
[設定] ボタン有効範囲指定.
void SetBitmapChangeTime(UINT ms)
[設定] ビットマップ切り替え時間設定.
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
[通知] for processing Windows messages.
CRgnButton & operator=(const CRgnButton &other)
[複製] 情報コピー.
virtual void OnDrawButton(CDC *pDC)
[通知] 描画
void SetHoverBitmap(CBitmapHandle bmp)
[設定] ホバー状態ビットマップ指定.
CBitmapImage m_focusBitmap
フォーカス(マーク)BITMAP
int SelectClipRgnOrg(CDC *pDC, HRGN rgn, int mode=RGN_COPY)
[設定] リージョン設定.
Definition: TnbMfcCommon.h:347
TNB Library
Definition: TnbDoxyTitle.txt:2