ATL의 다이얼로그 리전
프로그래밍 언어/C++2017. 4. 11. 20:51
ATL or WTL 상에서 윈도우 리전을 사용할 수 있는 템플릿 클래스 소스코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | /** * __________________________________________________________________________ * * ATL 대화상자 리전 윈도우 템플릿 ver 0.1 by Copynull * __________________________________________________________________________ * ______________ * STEP #1: 상속 템플릿 변경 * _______ * class CMainDlg : * public CDialogRegionT<CMainDlg> // this is step1 * { * ______________ * STEP #2: 메시지 맵 상속 템플릿 명 변경 * _______ * BEGIN_MSG_MAP(CMainDlg) * MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) * ... * ... * CHAIN_MSG_MAP(CDialogRegionT<CMainDlg>) // this is step2 * END_MSG_MAP() * ______________ * STEP #3: WM_INITDIALOG 메시지 함수내에 SetBKBitmap() 함수로 설정 완료 * _______ * LRESULT CMainDlg::OnInitDialog(UINT uMsg, WPARAM wParam, * LPARAM lParam, BOOL& bHandled) * { * SetBKBitmap(IDB_BITMAP); // this is step3 * * return TRUE; * } * __________________________________________________________________________ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma once template <typename T> class CATLDialogRegionT : public CAxDialogImpl<T> { public: HRGN m_hRgn; // the bitmap region BITMAP m_bmpInfo; // contains bitmap info HDC m_hdcBmp; // bitmap device context CBitmap m_Bitmap; // the bitmap BOOL m_bDlgMove; // Indicates if dialog can be moved by clicking COLORREF m_crTransparent; // the color which is to be drawn as transparent public: BEGIN_MSG_MAP(template <typename T>) MESSAGE_HANDLER(WM_PAINT, OnPaint) MESSAGE_HANDLER(WM_NCHITTEST, OnNCHitTest) END_MSG_MAP() CATLDialogRegionT() { m_hRgn = NULL; m_bDlgMove = FALSE; m_crTransparent = RGB(255, 0, 0); } ~CATLDialogRegionT() { if (m_hRgn) DeleteObject(m_hRgn); if (m_Bitmap.GetSafeHandle() != NULL) m_Bitmap.DeleteObject(); } bool SetDialogRegion() { T* pT = static_cast<T*>(this); // Set the window region int iRet = pT->SetWindowRgn(m_hRgn, FALSE); if (iRet == 0) return false; // Ups something went wrong // Size the window to the size of bitmap iRet = pT->SetWindowPos(NULL, 0, 0, m_bmpInfo.bmWidth, m_bmpInfo.bmHeight, SWP_NOZORDER | SWP_NOMOVE); CenterWindow(); return true; } bool GenerateRegion() { HDC dc = GetDC(); m_hdcBmp = CreateCompatibleDC(dc); ReleaseDC(dc); // Get info about the bitmap GetObject(m_Bitmap, sizeof(m_bmpInfo), &m_bmpInfo); HGDIOBJ hGdiObj = SelectObject(m_hdcBmp, m_Bitmap); m_hRgn = CreateRectRgn(0, 0, 0, 0); int iX = 0; int iRet = 0; for (int iY = 0; iY < m_bmpInfo.bmHeight; iY++) { do { while (iX < m_bmpInfo.bmWidth && GetPixel(m_hdcBmp, iX, iY) == m_crTransparent) iX++; int iLeftX = iX; while (iX < m_bmpInfo.bmWidth && GetPixel(m_hdcBmp, iX, iY) != m_crTransparent) ++iX; HRGN hRgnTemp = CreateRectRgn(iLeftX, iY, iX, iY + 1); iRet = CombineRgn(m_hRgn, m_hRgn, hRgnTemp, RGN_OR); if (iRet == ERROR) { return false; } //delete the temp region for next pass DeleteObject(hRgnTemp); } while (iX < m_bmpInfo.bmWidth); iX = 0; } return true; } bool SetBKBitmap(unsigned int iResourceID, COLORREF crTransparent, bool bDlgMove = true) { m_bDlgMove = bDlgMove; m_crTransparent = crTransparent; ATLASSERT(m_Bitmap.GetSafeHandle() == NULL); m_Bitmap.LoadBitmap(iResourceID); return processBitmap(); } bool processBitmap() { T* pT = static_cast<T*>(this); long oldWinStyle = pT->GetWindowLong(GWL_STYLE); if (m_Bitmap.GetSafeHandle() == NULL) return false; // Ups we dont have a bitmap image // Set the window style to WS_POPUPWINDOW and remove borders int iRetVal = pT->SetWindowLong(GWL_STYLE, oldWinStyle & WS_POPUPWINDOW & ~WS_BORDER); if (iRetVal == 0) { // Something went wrong m_Bitmap.DeleteObject(); return false; } if (!GenerateRegion()) { // Something went wrong, set the old window style pT->SetWindowLong(GWL_STYLE, oldWinStyle); return false; } // set the region for dialog SetDialogRegion(); return true; } LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) { PAINTSTRUCT ps; HDC hDC = BeginPaint(&ps); if (m_hdcBmp) BitBlt(hDC, 0, 0, m_bmpInfo.bmWidth, m_bmpInfo.bmHeight, m_hdcBmp, 0, 0, SRCCOPY); ReleaseDC(hDC); EndPaint(&ps); return 0; } LRESULT OnNCHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { POINT point = { LOWORD(lParam), HIWORD(lParam) }; ScreenToClient(&point); if (/*hit == HTCLIENT && */point.y <= 42 && m_bDlgMove) return HTCAPTION; else return DefWindowProc(); } }; |
'프로그래밍 언어 > C++' 카테고리의 다른 글
[mfc] 작업표시줄 알림창 애니메이션 c++ (0) | 2017.04.11 |
---|---|
Text-to-speech simple class c++ SAPI (0) | 2017.04.11 |
Visual Studio 2017 출시 및 ISO 파일 생성 방법 (1) | 2017.03.16 |
아스키(ASCII) 코드표 (1) | 2016.03.01 |
std::thread 클래스 활용 (2) | 2015.12.22 |