mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
Improved drawing performance. Now uses DIBSection bitmap for UpdateLayeredWindow.
This commit is contained in:
parent
a4b24d75ac
commit
0e0eb66cff
@ -57,6 +57,10 @@ extern CRainmeter* Rainmeter;
|
|||||||
*/
|
*/
|
||||||
CMeterWindow::CMeterWindow(const std::wstring& path, const std::wstring& config, const std::wstring& iniFile) : m_SkinPath(path), m_SkinName(config), m_SkinIniFile(iniFile),
|
CMeterWindow::CMeterWindow(const std::wstring& path, const std::wstring& config, const std::wstring& iniFile) : m_SkinPath(path), m_SkinName(config), m_SkinIniFile(iniFile),
|
||||||
m_DoubleBuffer(),
|
m_DoubleBuffer(),
|
||||||
|
m_DIBSectionBuffer(),
|
||||||
|
m_DIBSectionBufferPixels(),
|
||||||
|
m_DIBSectionBufferW(),
|
||||||
|
m_DIBSectionBufferH(),
|
||||||
m_Background(),
|
m_Background(),
|
||||||
m_BackgroundSize(),
|
m_BackgroundSize(),
|
||||||
m_Window(),
|
m_Window(),
|
||||||
@ -156,7 +160,8 @@ CMeterWindow::~CMeterWindow()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(m_Background) delete m_Background;
|
if(m_Background) delete m_Background;
|
||||||
if(m_DoubleBuffer) delete (m_DoubleBuffer);
|
if(m_DoubleBuffer) delete m_DoubleBuffer;
|
||||||
|
if(m_DIBSectionBuffer) DeleteObject(m_DIBSectionBuffer);
|
||||||
|
|
||||||
if(m_Window) DestroyWindow(m_Window);
|
if(m_Window) DestroyWindow(m_Window);
|
||||||
|
|
||||||
@ -238,7 +243,7 @@ int CMeterWindow::Initialize(CRainmeter& Rainmeter)
|
|||||||
IgnoreAeroPeek();
|
IgnoreAeroPeek();
|
||||||
|
|
||||||
// Gotta have some kind of buffer during initialization
|
// Gotta have some kind of buffer during initialization
|
||||||
m_DoubleBuffer = new Bitmap(1, 1, PixelFormat32bppPARGB);
|
CreateDoubleBuffer(1, 1);
|
||||||
|
|
||||||
Refresh(true, true);
|
Refresh(true, true);
|
||||||
if (!m_WindowStartHidden)
|
if (!m_WindowStartHidden)
|
||||||
@ -2281,6 +2286,35 @@ Bitmap* CMeterWindow::GrabDesktop(int x, int y, int w, int h)
|
|||||||
return background;
|
return background;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** CreateDoubleBuffer
|
||||||
|
**
|
||||||
|
** Creates the back buffer bitmap.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void CMeterWindow::CreateDoubleBuffer(int cx, int cy)
|
||||||
|
{
|
||||||
|
// Create DIBSection bitmap
|
||||||
|
BITMAPV4HEADER bmiHeader = {sizeof(BITMAPV4HEADER)};
|
||||||
|
bmiHeader.bV4Width = cx;
|
||||||
|
bmiHeader.bV4Height = -cy; // top-down DIB
|
||||||
|
bmiHeader.bV4Planes = 1;
|
||||||
|
bmiHeader.bV4BitCount = 32;
|
||||||
|
bmiHeader.bV4V4Compression = BI_BITFIELDS;
|
||||||
|
bmiHeader.bV4RedMask = 0x00FF0000;
|
||||||
|
bmiHeader.bV4GreenMask = 0x0000FF00;
|
||||||
|
bmiHeader.bV4BlueMask = 0x000000FF;
|
||||||
|
bmiHeader.bV4AlphaMask = 0xFF000000;
|
||||||
|
|
||||||
|
m_DIBSectionBuffer = CreateDIBSection(NULL, (BITMAPINFO*)&bmiHeader, DIB_RGB_COLORS, (void**)&m_DIBSectionBufferPixels, NULL, 0);
|
||||||
|
|
||||||
|
// Create GDI+ bitmap from DIBSection's pixels
|
||||||
|
m_DoubleBuffer = new Bitmap(cx, cy, cx * 4, PixelFormat32bppPARGB, (BYTE*)m_DIBSectionBufferPixels);
|
||||||
|
|
||||||
|
m_DIBSectionBufferW = cx;
|
||||||
|
m_DIBSectionBufferH = cy;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CreateRegion
|
** CreateRegion
|
||||||
**
|
**
|
||||||
@ -2298,13 +2332,16 @@ void CMeterWindow::CreateRegion(bool clear)
|
|||||||
// Set window region if needed
|
// Set window region if needed
|
||||||
if(!m_BackgroundName.empty())
|
if(!m_BackgroundName.empty())
|
||||||
{
|
{
|
||||||
HBITMAP background = NULL;
|
if (m_WindowW != 0 && m_WindowH != 0)
|
||||||
m_DoubleBuffer->GetHBITMAP(Color(255,0,255), &background);
|
|
||||||
if (background)
|
|
||||||
{
|
{
|
||||||
HRGN region = BitmapToRegion(background, RGB(255,0,255), 0x101010, 0, 0);
|
HBITMAP background = NULL;
|
||||||
SetWindowRgn(m_Window, region, TRUE);
|
m_DoubleBuffer->GetHBITMAP(Color(255,0,255), &background);
|
||||||
DeleteObject(background);
|
if (background)
|
||||||
|
{
|
||||||
|
HRGN region = BitmapToRegion(background, RGB(255,0,255), 0x101010, 0, 0);
|
||||||
|
SetWindowRgn(m_Window, region, TRUE);
|
||||||
|
DeleteObject(background);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2336,17 +2373,17 @@ void CMeterWindow::Redraw()
|
|||||||
cy = 1;
|
cy = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitmapData buf;
|
if (cx != m_DIBSectionBufferW || cy != m_DIBSectionBufferH || m_DIBSectionBufferPixels == NULL)
|
||||||
if (cx != m_DoubleBuffer->GetWidth() || cy != m_DoubleBuffer->GetHeight() ||
|
|
||||||
Ok != m_DoubleBuffer->LockBits(&Rect(0, 0, cx, cy), ImageLockModeWrite, PixelFormat32bppPARGB, &buf))
|
|
||||||
{
|
{
|
||||||
if (m_DoubleBuffer) delete m_DoubleBuffer;
|
if (m_DoubleBuffer) delete m_DoubleBuffer;
|
||||||
m_DoubleBuffer = new Bitmap(cx, cy, PixelFormat32bppPARGB);
|
if (m_DIBSectionBuffer) DeleteObject(m_DIBSectionBuffer);
|
||||||
|
m_DIBSectionBufferPixels = NULL;
|
||||||
|
|
||||||
|
CreateDoubleBuffer(cx, cy);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memset(buf.Scan0, 0, buf.Stride * cy); // assume that the bitmap is top-down
|
memset(m_DIBSectionBufferPixels, 0, cx * cy * 4);
|
||||||
m_DoubleBuffer->UnlockBits(&buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2652,15 +2689,12 @@ void CMeterWindow::UpdateTransparency(int alpha, bool reset)
|
|||||||
|
|
||||||
HDC dcScreen = GetDC(0);
|
HDC dcScreen = GetDC(0);
|
||||||
HDC dcMemory = CreateCompatibleDC(dcScreen);
|
HDC dcMemory = CreateCompatibleDC(dcScreen);
|
||||||
|
SelectObject(dcMemory, m_DIBSectionBuffer);
|
||||||
|
|
||||||
HBITMAP dbBitmap;
|
|
||||||
m_DoubleBuffer->GetHBITMAP(Color(0, 0, 0, 0), &dbBitmap);
|
|
||||||
HBITMAP oldBitmap = (HBITMAP)SelectObject(dcMemory, dbBitmap);
|
|
||||||
UpdateLayeredWindow(m_Window, dcScreen, &ptWindowScreenPosition, &szWindow, dcMemory, &ptSrc, 0, &blendPixelFunction, ULW_ALPHA);
|
UpdateLayeredWindow(m_Window, dcScreen, &ptWindowScreenPosition, &szWindow, dcMemory, &ptSrc, 0, &blendPixelFunction, ULW_ALPHA);
|
||||||
|
|
||||||
ReleaseDC(0, dcScreen);
|
ReleaseDC(0, dcScreen);
|
||||||
SelectObject(dcMemory, oldBitmap);
|
|
||||||
DeleteDC(dcMemory);
|
DeleteDC(dcMemory);
|
||||||
DeleteObject(dbBitmap);
|
|
||||||
|
|
||||||
m_TransparencyValue = alpha;
|
m_TransparencyValue = alpha;
|
||||||
}
|
}
|
||||||
@ -2679,6 +2713,7 @@ void CMeterWindow::UpdateTransparency(int alpha, bool reset)
|
|||||||
** OnPaint
|
** OnPaint
|
||||||
**
|
**
|
||||||
** Repaints the window. This does not cause update of the measures.
|
** Repaints the window. This does not cause update of the measures.
|
||||||
|
** This handler is called if NativeTransparency is false.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
LRESULT CMeterWindow::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
LRESULT CMeterWindow::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
@ -3001,14 +3036,10 @@ bool CMeterWindow::HitTest(int x, int y)
|
|||||||
if (x >= 0 && y >= 0 && x < m_WindowW && y < m_WindowH)
|
if (x >= 0 && y >= 0 && x < m_WindowW && y < m_WindowH)
|
||||||
{
|
{
|
||||||
// Check transparent pixels
|
// Check transparent pixels
|
||||||
if (m_DoubleBuffer)
|
if (m_DIBSectionBufferPixels)
|
||||||
{
|
{
|
||||||
Color color;
|
DWORD pixel = m_DIBSectionBufferPixels[y * m_WindowW + x]; // top-down DIB
|
||||||
Status status = m_DoubleBuffer->GetPixel(x, y, &color);
|
return ((pixel & 0xFF000000) != 0);
|
||||||
if (status != Ok || color.GetA() != 0)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -292,9 +292,16 @@ private:
|
|||||||
void SetWindowPositionVariables(int x, int y);
|
void SetWindowPositionVariables(int x, int y);
|
||||||
void SetWindowSizeVariables(int w, int h);
|
void SetWindowSizeVariables(int w, int h);
|
||||||
|
|
||||||
|
void CreateDoubleBuffer(int cx, int cy);
|
||||||
|
|
||||||
CConfigParser m_Parser;
|
CConfigParser m_Parser;
|
||||||
|
|
||||||
Gdiplus::Bitmap* m_DoubleBuffer;
|
Gdiplus::Bitmap* m_DoubleBuffer;
|
||||||
|
HBITMAP m_DIBSectionBuffer;
|
||||||
|
LPDWORD m_DIBSectionBufferPixels;
|
||||||
|
int m_DIBSectionBufferW;
|
||||||
|
int m_DIBSectionBufferH;
|
||||||
|
|
||||||
Gdiplus::Bitmap* m_Background; // The background bitmap
|
Gdiplus::Bitmap* m_Background; // The background bitmap
|
||||||
SIZE m_BackgroundSize;
|
SIZE m_BackgroundSize;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user