GME
13
|
00001 // GMEViewOverlay.cpp : implementation file 00002 // 00003 00004 #include "stdafx.h" 00005 #include "GMEViewOverlay.h" 00006 00007 00008 const UINT_PTR ID_TIMER = 1; 00009 00010 // GMEViewOverlay 00011 00012 IMPLEMENT_DYNAMIC(GMEViewOverlay, CWnd) 00013 00014 GMEViewOverlay::GMEViewOverlay() 00015 : m_timerID(0) 00016 { 00017 } 00018 00019 GMEViewOverlay::~GMEViewOverlay() 00020 { 00021 if (this->m_hWnd) 00022 { 00023 DestroyWindow(); 00024 } 00025 } 00026 00027 void GMEViewOverlay::OnDraw(CDC* pDC) 00028 { 00029 Gdiplus::Graphics gdip(pDC->m_hDC); 00030 gdip.SetPageUnit(Gdiplus::UnitPixel); 00031 00032 Gdiplus::Pen pen(Gdiplus::Color::Blue); 00033 CRect rect; 00034 GetWindowRect(&rect); 00035 Gdiplus::Rect grect(rect.left, rect.top, rect.Width(), rect.Height()); 00036 VERIFY(gdip.DrawRectangle(&pen, grect) == Gdiplus::Ok); 00037 } 00038 00039 int GMEViewOverlay::OnCreate(LPCREATESTRUCT lpCreateStruct) 00040 { 00041 lpCreateStruct->dwExStyle |= GMEViewOverlay::exstyle; 00042 lpCreateStruct->style |= GMEViewOverlay::style; 00043 //lpCreateStruct->style |= WS_DISABLED; 00044 // SystemParametersInfo(SPI_GETSELECTIONFADE, 0, &fFade, 0); 00045 //CreateWindowEx(exstyle, 00046 if (__super::OnCreate(lpCreateStruct) == -1) 00047 return -1; 00048 00049 return 0; 00050 } 00051 00052 template<typename int_> 00053 int_ RoundUpTo4(int_ val) 00054 { 00055 int_ mask = 0; 00056 mask = (~mask) ^ 3; 00057 return (val + 3) & mask; 00058 } 00059 00060 void GMEViewOverlay::Init1() 00061 { 00062 DWORD exstyle = GMEViewOverlay::exstyle; 00063 DWORD style = GMEViewOverlay::style; 00064 00065 VERIFY(ModifyStyleEx(0, exstyle)); 00066 VERIFY(ModifyStyle(0, style)); 00067 //DWORD style = GetStyle(); 00068 //DWORD exstyle = GetExStyle(); 00069 00070 GdiFlush(); 00071 00072 CRect rcWindow; 00073 GetWindowRect(&rcWindow); 00074 SIZE size = {rcWindow.Width(), rcWindow.Height()}; 00075 00076 CDC screen; 00077 screen.Attach(::GetDC(NULL)); 00078 m_memcdc = new CDC(); 00079 m_memcdc->CreateCompatibleDC(&screen); 00080 // LPVOID bitmapdata = VirtualAlloc(0, RoundUpTo4(size.cx) * RoundUpTo4(size.cy) * 4, MEM_COMMIT, PAGE_READWRITE); 00081 // m_bitmap = CreateBitmap(RoundUpTo4(size.cx), RoundUpTo4(size.cy), 1, 32, bitmapdata); 00082 m_bitmap = CreateCompatibleBitmap(screen, size.cx, size.cy); 00083 ASSERT(m_bitmap); 00084 00085 BITMAPINFO bmpInfo = {0}; 00086 bmpInfo.bmiHeader.biSize = sizeof(bmpInfo.bmiHeader); 00087 GetDIBits(*m_memcdc, m_bitmap, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS); 00088 // TODO check bmpInfo.bmiHeader.biBitCount==32 00089 00090 HGDIOBJ old = ::SelectObject(*m_memcdc, m_bitmap); 00091 /*/ debugging: draw outline around window 00092 { 00093 Gdiplus::Graphics gdip(*m_memcdc); 00094 gdip.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality); 00095 gdip.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); 00096 { 00097 CRect rect; 00098 GetWindowRect(&rect); 00099 Gdiplus::Rect grect(0, 0, rect.Width()-1, rect.Height()-1); 00100 Gdiplus::Pen trans(Gdiplus::Color(254, 255, 0, 0), 1); 00101 VERIFY(gdip.DrawRectangle(&trans, grect) == Gdiplus::Ok); 00102 } 00103 } 00104 // */ 00105 } 00106 00107 void GMEViewOverlay::Init2() 00108 { 00109 CRect rcWindow; 00110 GetWindowRect(&rcWindow); 00111 SIZE size = {rcWindow.Width(), rcWindow.Height()}; 00112 /* debugging: FillRectangle with alpha==255 results in alpha==0 00113 { 00114 Gdiplus::Graphics gdip(*m_memcdc); 00115 gdip.Clear(Gdiplus::Color(0)); 00116 gdip.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality); 00117 gdip.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); 00118 // doesnt matter gdip.SetCompositingMode( Gdiplus::CompositingModeSourceCopy ); 00119 { 00120 CRect rect; 00121 GetWindowRect(&rect); 00122 Gdiplus::Rect grect(0, 0, 32, rect.Height()/2); 00123 Gdiplus::SolidBrush trans(Gdiplus::Color(180, 255, 0, 0)); 00124 VERIFY(gdip.FillRectangle(&trans, grect) == Gdiplus::Ok); 00125 } 00126 { 00127 CRect rect; 00128 GetWindowRect(&rect); 00129 Gdiplus::Rect grect(32, 0, 50, rect.Height()/2); 00130 Gdiplus::SolidBrush trans(Gdiplus::Color(255, 250, 0, 0)); 00131 VERIFY(gdip.FillRectangle(&trans, grect) == Gdiplus::Ok); 00132 } 00133 } */ 00134 00135 BITMAPINFO bmi = {0}; 00136 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); 00137 bmi.bmiHeader.biBitCount = 32; 00138 bmi.bmiHeader.biCompression = BI_RGB; 00139 bmi.bmiHeader.biHeight = size.cy; 00140 bmi.bmiHeader.biWidth = size.cx; 00141 bmi.bmiHeader.biPlanes=1; 00142 LPVOID bits = VirtualAlloc(0, RoundUpTo4(size.cx) * RoundUpTo4(size.cy) * 4, MEM_COMMIT, PAGE_READWRITE); 00143 //auto dibits2 = GetDIBits(*m_memcdc, m_bitmap, size.cy/2+9, size.cy/2-10, bits, &bmi, DIB_RGB_COLORS); 00144 00145 int dibits = GetDIBits(*m_memcdc, m_bitmap, 0, size.cy, bits, &bmi, DIB_RGB_COLORS); 00146 ASSERT(dibits); 00147 // GDI+ sets the alpha value to 0 if the source is 255. fix it 00148 // (GDI always sets alpha to 0. Fix that too) 00149 for (int i = 0; i < size.cy; i++) 00150 { 00151 for (int j = 0; j < size.cx; j++) 00152 { 00153 int *argb = ((int*)bits) + size.cx * i + j; 00154 if ((*argb & 0x00FFFFFF) && (*argb & 0xFF000000) == 0) 00155 { 00156 *argb = *argb | 0xFF000000; 00157 } 00158 // assert premultiplied 00159 ASSERT(((*argb & 0xFF000000) >> 24) >= ((*argb & 0x00FF0000) >> 16)); 00160 ASSERT(((*argb & 0xFF000000) >> 24) >= ((*argb & 0x0000FF00) >> 8)); 00161 ASSERT(((*argb & 0xFF000000) >> 24) >= ((*argb & 0x000000FF))); 00162 } 00163 } 00164 dibits = SetDIBits(*m_memcdc, m_bitmap, 0, size.cy, bits, &bmi, DIB_RGB_COLORS); 00165 VERIFY(dibits); 00166 VirtualFree(bits, 0, MEM_RELEASE); 00167 00168 //VERIFY(::SelectObject(*m_memcdc, m_bitmap)); 00169 00170 ASSERT(GetSafeHwnd()); 00171 ::SetWindowPos(GetSafeHwnd(), HWND_TOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE); 00172 POINT ptZero = {0, 0}; 00173 POINT ptDest = {rcWindow.left+1, rcWindow.top+1}; 00174 m_opacity = 0; 00175 BLENDFUNCTION blend = { AC_SRC_OVER, 0, 254, AC_SRC_ALPHA}; 00176 CDC screen; 00177 screen.Attach(::GetDC(NULL)); 00178 // m_memcdc RGB is premultiplied with alpha 00179 VERIFY(UpdateLayeredWindow(&screen, &ptDest, &size, m_memcdc, &ptZero, 0, &blend, ULW_ALPHA)); 00180 00181 m_timerID = SetTimer(2, 75, NULL); 00182 } 00183 00184 00185 BEGIN_MESSAGE_MAP(GMEViewOverlay, CWnd) 00186 ON_WM_CLOSE() 00187 ON_WM_CREATE() 00188 ON_WM_TIMER() 00189 END_MESSAGE_MAP() 00190 00191 00192 00193 // GMEViewOverlay message handlers 00194 00195 void GMEViewOverlay::OnClose() 00196 { 00197 CWnd::OnClose(); 00198 } 00199 00200 // Fade out, in, then out 00201 //[254 - i * 22 for i in range(6)] + [254 - i * 22 for i in range(6, 0, -1)] + [254 - i * 19 for i in range(13)] + [0] 00202 static BYTE opacities[] = { 254, 232, 210, 188, 166, 144, 122, 144, 166, 188, 210, 232, 254, 235, 216, 197, 178, 159, 140, 121, 102, 83, 64, 45, 26, 0 }; 00203 00204 void GMEViewOverlay::OnTimer(UINT_PTR nIDEvent) 00205 { 00206 m_opacity++; 00207 if (opacities[m_opacity] == 0) 00208 { 00209 DestroyWindow(); 00210 return; 00211 } 00212 BLENDFUNCTION blend; 00213 blend.BlendOp = AC_SRC_OVER; 00214 blend.BlendFlags = 0; 00215 blend.SourceConstantAlpha = opacities[m_opacity]; 00216 blend.AlphaFormat = 0; 00217 blend.AlphaFormat = AC_SRC_ALPHA; 00218 00219 VERIFY(UpdateLayeredWindow(NULL, NULL, NULL, NULL, NULL, 0, &blend, ULW_ALPHA)); 00220 00221 CWnd::OnTimer(nIDEvent); 00222 } 00223 00224 BOOL GMEViewOverlay::DestroyWindow() 00225 { 00226 if (m_timerID) 00227 { 00228 int ret = KillTimer(m_timerID); 00229 if (ret != 0) 00230 { 00231 auto err = GetLastError(); 00232 ASSERT(false); 00233 } 00234 } 00235 VERIFY(DeleteObject(m_bitmap)); 00236 VERIFY(m_memcdc->DeleteDC()); 00237 00238 return CWnd::DestroyWindow(); 00239 }