TNB Library
TnbMfcDrag.h
[詳解]
1#pragma once
13#include "TnbMfcCommon.h"
14#include "TnbBitmapImage.h"
15#include "TnbDrawable.h"
16
17
18
19//TNB Library
20namespace TNB {
21namespace MFC {
22
23
24
123template<typename TYP = CStatic>
124class CDragAddinT : public TYP
125{
126 DEFSUPER(TYP);
127public:
128
135 {
136 START = 0,
143 };
144
151 {
152 CANDROP = 100,
157 };
158
161 {
162 int dragID;
163 POINT point;
164 HRGN hRgn;
165 WORD ctrlID;
166 };
167
172 static UINT GetDragNotifyMessage(void)
173 {
174 return ::RegisterWindowMessage(_T("TnbMfcDragAddin"));
175 }
176
179 : m_targetMarkColor(::GetSysColor(COLOR_HIGHLIGHT)), m_targetMarkThick(2)
180 , m_arrowIcon(NULL), m_noIcon(NULL)
181 , m_wGroupID(0), m_boCanDragging(true), m_boCanDropping(true)
182 , m_boIsDragging(false), m_nowDropItem(-1), m_nowDropItemRgn(NULL)
183 {
184 m_nMessageCode = GetDragNotifyMessage();
185 m_nowDropItemRgn = ::CreateRectRgn(0, 0, 0, 0);
186 }
187
190 {
191 _DeleteObject(m_nowDropItemRgn);
192 }
193
200 void SetDragGroupID(WORD w)
201 {
202 m_wGroupID = w;
203 }
204
209 WORD GetDragGroupID(void) const
210 {
211 return m_wGroupID;
212 }
213
220 {
221 m_bmpDragging = bmp;
222 }
223
230 template<typename T>
232 {
233 const IDrawable* draw = NULL;
234 COLORREF color;
235 int thick;
236 other.GetDropTargetMark(draw, color, thick);
237 if ( draw != NULL )
238 {
239 m_targetMarkDrawer = draw->Clone();
240 }
241 m_targetMarkColor = color;
242 m_targetMarkThick = thick;
243 }
244
251 void SetDropTargetMark(const IDrawable& draw)
252 {
253 m_targetMarkDrawer = draw.Clone();
254 }
255
263 void SetDropTargetMark(COLORREF color, int thick = 0)
264 {
265 m_targetMarkDrawer.Null();
266 m_targetMarkColor = color;
267 if ( thick > 0 )
268 {
269 m_targetMarkThick = thick;
270 }
271 }
272
279 void GetDropTargetMark(const IDrawable*& _draw, COLORREF& _color, int& _thick) const
280 {
281 _draw = m_targetMarkDrawer;
282 _color = m_targetMarkColor;
283 _thick = m_targetMarkThick;
284 }
285
290 void SetDragMode(bool can)
291 {
292 m_boCanDragging = can;
293 }
294
300 bool CanDragging(void) const
301 {
302 return m_boCanDragging;
303 }
304
309 void SetDropMode(bool can)
310 {
311 m_boCanDropping = can;
312 }
313
319 bool CanDropping(void) const
320 {
321 return m_boCanDropping;
322 }
323
324protected:
325
333 bool SendNofityMessage(CWnd* pWnd, WPARAM wParam, LPARAM lParam) const
334 {
335 return !! ::SendMessage(*pWnd, m_nMessageCode, wParam, lParam);
336 }
337
344 bool IsNofityMessage(UINT message) const
345 {
346 return m_nMessageCode == message;
347 }
348
358 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
359 {
360 if ( message == m_nMessageCode )
361 {
362 if ( wParam == static_cast<WPARAM>(MAKELONG(CANDROP, m_wGroupID)) )
363 {
364 return m_boCanDropping;
365 }
366 }
367 else if ( message == WM_LBUTTONDOWN )
368 {
369 if ( m_BeginDrag() )
370 {
371 m_SendCommand(START, 0);
372 return 0;
373 }
374 }
375 else if ( message == WM_LBUTTONUP )
376 {
377 if ( m_EndDrag() )
378 {
379 if ( m_nowDropItem >= 0 )
380 {
381 m_SendCommand(DROP, m_nowDropItem);
382 }
383 else
384 {
385 m_SendCommand(INVALID, 0);
386 }
387 return 0;
388 }
389 }
390 else if ( message == WM_CAPTURECHANGED || message == WM_RBUTTONDOWN )
391 {
392 if ( m_EndDrag() )
393 {
394 m_SendCommand(CANCEL, 0);
395 }
396 }
397 else if ( message == WM_MOUSEMOVE )
398 {
399 if ( m_boIsDragging )
400 {
401 m_OnMouseMove();
402 }
403 }
404 else if ( message == WM_DESTROY )
405 {
406 m_EndDrag();
407 }
408 return _super::WindowProc(message, wParam, lParam);
409 }
410
418 virtual int OnBeginDrag(RECT& _rc, const POINT& po)
419 {
420 if ( ! ::DragDetect(m_hWnd, po) ) //これ以外で対応したい
421 {
422 return 0;
423 }
424 return _super::GetDlgCtrlID();
425 }
426
434 virtual void OnDragNofity(UINT cmd, int draggingItem, int dropedItem)
435 {
436 }
437
438private:
439 //-設定
440 IDrawable::Ptr m_targetMarkDrawer;
441 COLORREF m_targetMarkColor;
442 int m_targetMarkThick;
443 CBitmapHandle m_bmpDragging;
444 WORD m_wGroupID;
445 bool m_boCanDragging;
446 bool m_boCanDropping;
447 //-動作 Work
448 UINT m_nMessageCode;
449 int m_draggingItemID;
450 HICON m_arrowIcon;
451 HICON m_noIcon;
452 CImageList m_imglist;
453 bool m_boIsDragging;
454 CPoint m_dragOffset;
455 //-MOVE中
456 int m_nowDropItem;
457 HRGN m_nowDropItemRgn;
458 CWnd* m_nowDropWnd;
460 void m_DrawTargetMark(CDC* pDC, HRGN hRgn)
461 {
462 if ( m_targetMarkDrawer.IsNull() )
463 {
464 CBrush br;
465 br.CreateSolidBrush(m_targetMarkColor);
466 ::FrameRgn(*pDC, m_nowDropItemRgn, br, m_targetMarkThick, m_targetMarkThick);
467 }
468 else
469 {
470 CRect rc;
471 ::GetRgnBox(hRgn, &rc);
472 ::SelectClipRgn(*pDC, hRgn);
473 m_targetMarkDrawer->Resize(rc.Size());
474 m_targetMarkDrawer->Draw(*pDC, rc.left, rc.top);
475 ::SelectClipRgn(*pDC, NULL);
476 }
477 }
479 void m_OnMouseMove(void)
480 {
481 if ( m_arrowIcon == NULL ) { m_arrowIcon = ::GetCursor(); }
482 CPoint pos;
483 ::GetCursorPos(&pos);
484 m_imglist.DragMove(pos - m_dragOffset);
485 //
486 CWnd* pParent = _super::GetParent();
487 if ( pParent == NULL )
488 {
489 return;
490 }
491 int backupDropItem = m_nowDropItem;
492 CWnd* pBackupDropWnd = m_nowDropWnd;
493 RECT backupDropRect;
494 ::GetRgnBox(m_nowDropItemRgn, &backupDropRect);
495 m_nowDropItem = -1;
496 HCURSOR hCursor = NULL;
497 //
498 CWnd* P = pParent->GetParentOwner();
499 if ( P == NULL )
500 {
501 return;
502 }
503 CRect rc;
504 P->GetClientRect(&rc);
505 P->ClientToScreen(&rc);
506 if ( rc.PtInRect(pos) )
507 {
508 pParent->ScreenToClient(&pos);
509 CWnd* P = pParent->ChildWindowFromPoint(pos, CWP_SKIPINVISIBLE);
510 if ( P != NULL )
511 {
512 TDropParam param;
513 param.dragID = m_draggingItemID;
514 param.ctrlID = static_cast<WORD>(P->GetDlgCtrlID());
515 if ( param.ctrlID != 0 )
516 {
517 pParent->ClientToScreen(&pos);
518 P->ScreenToClient(&pos);
519 param.point = pos;
520 RECT rect;
521 P->GetClientRect(&rect);
522 param.hRgn = ::CreateRectRgn(0, 0, rect.right, rect.bottom);
523 P->GetWindowRgn(param.hRgn);
524 if ( m_CanDropping(P, param) )
525 {
526 if ( param.ctrlID != m_draggingItemID )
527 {
528 _DeleteObject(m_nowDropItemRgn);
529 m_nowDropItemRgn = param.hRgn;
530 m_nowDropItem = param.ctrlID;
531 m_nowDropWnd = P;
532 hCursor = m_arrowIcon;
533 }
534 else
535 {
536 _DeleteObject(param.hRgn);
537 }
538 }
539 else
540 {
541 _DeleteObject(param.hRgn);
542 }
543 }
544 }
545 }
546 if ( hCursor == NULL )
547 {
548 if ( m_noIcon == NULL ) { m_noIcon = ::LoadCursor(NULL, IDC_NO); }
549 hCursor = m_noIcon;
550 }
551 ::SetCursor(hCursor);
552 if ( backupDropItem != m_nowDropItem )
553 {
554 if ( backupDropItem >= 0 )
555 {
556 m_SendCommand(LEAVE, backupDropItem);
557 m_imglist.DragShowNolock(false);
558 CWnd* P = pBackupDropWnd->GetParent();
559 if ( P != NULL )
560 {
561 pBackupDropWnd->ClientToScreen(&backupDropRect);
562 P->ScreenToClient(&backupDropRect);
563 P->RedrawWindow(&backupDropRect);
564 }
565 else
566 {
567 pBackupDropWnd->RedrawWindow(&backupDropRect);
568 }
569 m_imglist.DragShowNolock(true);
570 }
571 if ( m_nowDropItem >= 0 )
572 {
573 m_SendCommand(HOVER, m_nowDropItem);
574 if ( IS_RGBVALUE(m_targetMarkColor) )
575 {
576 CDC* pDC = m_nowDropWnd->GetDC();
577 m_imglist.DragShowNolock(false);
578 m_DrawTargetMark(pDC, m_nowDropItemRgn);
579 m_imglist.DragShowNolock(true);
580 m_nowDropWnd->ReleaseDC(pDC);
581 }
582 }
583 }
584 }
586 bool m_CanDropping(CWnd* P, TDropParam& _param)
587 {
588 ASSERTLIB( P != NULL );
589 ASSERTLIB( _param.ctrlID != 0 );
590 WPARAM wParam = MAKELONG(CANDROP, m_wGroupID);
591 LPARAM lParam = reinterpret_cast<LPARAM>(&_param);
592 if ( P->SendMessage(m_nMessageCode, wParam, lParam) )
593 {
594 return true;
595 }
596 if ( m_SendCommand(ISDROP, _param.ctrlID) )
597 {
598 return true;
599 }
600 return false;
601 }
602 // アイテムのドラッグ開始
603 bool m_BeginDrag(void)
604 {
605 if ( m_boIsDragging )
606 {
607 m_EndDrag();
608 }
609 if ( ! m_boCanDragging ) { return false; }
610 CPoint pos;
611 ::GetCursorPos(&pos);
612 CRect rect;
613 _super::GetWindowRect(rect);
614 CRect winRect = rect;
615 m_draggingItemID = OnBeginDrag(rect, pos);
616 if ( m_draggingItemID <= 0 )
617 {
618 return false;
619 }
620 CPoint controlPoint = rect.TopLeft();
621 m_dragOffset = pos - controlPoint;
622 CBitmapHandle hh = m_bmpDragging;
623 CSize size;
624 if ( hh.IsNull() )
625 {
626 CBitmapImage bi;
627 bi.SetFromWindow(m_hWnd, RGB(0, 0, 1));
628 rect.OffsetRect(-winRect.TopLeft());
629 hh = bi.Cut(rect).GetBitmapHandle();
630 hh.GetSize(size);
631 }
632 else
633 {
634 VERIFY( hh.GetSize(size) );
635 }
636 m_imglist.Create(size.cx, size.cy, ILC_MASK, 0, 1);
637 m_imglist.Add(CBitmap::FromHandle(hh), RGB(0, 0, 1));
638 m_imglist.BeginDrag(0, CPoint(0, 0));
639 m_imglist.DragEnter(NULL, controlPoint);
640 m_imglist.DragMove(controlPoint);
641 SetCapture();
642 m_boIsDragging = true;
643 return true;
644 }
645 // ドラッグの終了
646 bool m_EndDrag(void)
647 {
648 if ( ! m_boIsDragging ) { return false; }
649 m_boIsDragging = false;
650 m_imglist.EndDrag();
651 m_imglist.DeleteImageList();
652 if ( m_nowDropItem >= 0 && ::IsWindow(*m_nowDropWnd) )
653 {
654 m_nowDropWnd->Invalidate();
655 }
656 ReleaseCapture();
657 return true;
658 }
660 bool m_SendCommand(UINT uCmd, int item)
661 {
662 WPARAM wParam = MAKELONG(uCmd, m_wGroupID);
663 LPARAM lParam = MAKELONG(m_draggingItemID, item);
664 LRESULT r = 0;
665 CWnd* pWnd = _super::GetParent();
666 if ( pWnd != NULL )
667 {
668 r = pWnd->SendMessage(m_nMessageCode, wParam, lParam);
669 }
670 OnDragNofity(uCmd, m_draggingItemID, item);
671 return !! r;
672 }
673};
674
675
676
677}; //MFC
678}; //TNB
679
680
681
ビットマップイメージ管理関係のヘッダ
描画情報関係のヘッダ
MFCコントロール共通のヘッダ
ウィンドウ管理.
HBITMAP型ハンドルハンドル
bool GetSize(SIZE &_size) const
[取得] ビットマップサイズ取得.
ビットマップイメージ管理クラス
CBitmapImage Cut(const RECT &rect, int cx=0, int cy=0) const
[取得] イメージ取り出し.
bool SetFromWindow(HWND hWnd, COLORREF backColor=CLR_INVALID, LPARAM mode=PRF_CLIENT|PRF_ERASEBKGND|PRF_NONCLIENT|PRF_OWNED)
[設定] ウィンドウからイメージ設定.
CBitmapHandle GetBitmapHandle(void)
[取得] ビットマップハンドル取得
bool IsNull(void) const
[確認] NULLチェック
void Null(void)
[設定] 開放.
ドラッグコントロールアドインクラス
Definition: TnbMfcDrag.h:125
void GetDropTargetMark(const IDrawable *&_draw, COLORREF &_color, int &_thick) const
[取得] ドロップ先のマーク設定取得.
Definition: TnbMfcDrag.h:279
static UINT GetDragNotifyMessage(void)
[取得] 通知用メッセージコード取得.
Definition: TnbMfcDrag.h:172
void SetDraggingBitmap(CBitmapHandle bmp)
[設定] ドラック中ビットマップ設定.
Definition: TnbMfcDrag.h:219
void SetDragGroupID(WORD w)
[設定] ドロップグループID設定
Definition: TnbMfcDrag.h:200
void SetDropMode(bool can)
[設定] ドロップモード設定.
Definition: TnbMfcDrag.h:309
bool IsNofityMessage(UINT message) const
[確認] 通知メッセージ確認.
Definition: TnbMfcDrag.h:344
void SetDropTargetMark(const CDragAddinT< T > &other)
[設定] ドロップ先のマーク設定.
Definition: TnbMfcDrag.h:231
bool CanDropping(void) const
[取得] ドロップモード取得.
Definition: TnbMfcDrag.h:319
void SetDragMode(bool can)
[設定] ドラッグモード設定.
Definition: TnbMfcDrag.h:290
CDragAddinT(void)
コンストラクタ
Definition: TnbMfcDrag.h:178
bool CanDragging(void) const
[取得] ドラッグモード取得.
Definition: TnbMfcDrag.h:300
bool SendNofityMessage(CWnd *pWnd, WPARAM wParam, LPARAM lParam) const
[通知] メッセージ通知.
Definition: TnbMfcDrag.h:333
void SetDropTargetMark(const IDrawable &draw)
[設定] ドロップ先のマーク設定.
Definition: TnbMfcDrag.h:251
void SetDropTargetMark(COLORREF color, int thick=0)
[設定] ドロップ先のマーク設定.
Definition: TnbMfcDrag.h:263
virtual void OnDragNofity(UINT cmd, int draggingItem, int dropedItem)
[通知] ドラッグ通知.
Definition: TnbMfcDrag.h:434
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
[通知] for processing Windows messages.
Definition: TnbMfcDrag.h:358
~CDragAddinT(void)
デストラクタ
Definition: TnbMfcDrag.h:189
EDragNotifyCode
ドラッグ通知種別コード.
Definition: TnbMfcDrag.h:135
@ START
ドラック開始.
Definition: TnbMfcDrag.h:136
@ ISDROP
ドロップ確認.
Definition: TnbMfcDrag.h:142
@ DROP
有効ドロップ(ドラック終了).
Definition: TnbMfcDrag.h:141
@ HOVER
ホバー(ドラック中).
Definition: TnbMfcDrag.h:137
@ LEAVE
ホバー終了(ドラック中).
Definition: TnbMfcDrag.h:138
@ CANCEL
キャンセル(ドラック終了).
Definition: TnbMfcDrag.h:139
@ INVALID
無効ドロップ(ドラック終了).
Definition: TnbMfcDrag.h:140
WORD GetDragGroupID(void) const
[取得] ドロップグループID取得
Definition: TnbMfcDrag.h:209
EDropCtrlCode
ドロップコントロールコード.
Definition: TnbMfcDrag.h:151
@ CANDROP
ドロップ可能かチェック時に通知します。 通知を受けたコントロールは LRESULT で true(ドロップ可能),false(不可能) を返します。 LPARAM は TDropParam のポインタが...
Definition: TnbMfcDrag.h:152
virtual int OnBeginDrag(RECT &_rc, const POINT &po)
[通知] ドラッグ開始.
Definition: TnbMfcDrag.h:418
TNB Library
Definition: TnbDoxyTitle.txt:2
描画情報インターフェース
Definition: TnbDrawable.h:37
virtual bool Resize(const SIZE &size)=0
[設定] サイズ設定.
virtual IDrawable * Clone(void) const =0
[作成] クローン作成.
virtual void Draw(HDC dc, int x=0, int y=0) const =0
[描画] 描画.
ドロップコントロールパラメータ
Definition: TnbMfcDrag.h:161
POINT point
マウスカーソル位置(クライアント座標)。変更不可。
Definition: TnbMfcDrag.h:163
HRGN hRgn
クライアントの領域(クライアント座標)。変更可能。
Definition: TnbMfcDrag.h:164
int dragID
ドラッグ中のコントロールID。変更不可。
Definition: TnbMfcDrag.h:162
WORD ctrlID
コントロールID。変更可能。
Definition: TnbMfcDrag.h:165