Files
core/ASCImageStudio3/AVSImageView5/Tracking/WindowsEx.h
Elen.Subbotina 70e623d70b восстановление
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62634 954022d7-b5bf-4e40-9824-e11837661b57
2016-05-21 00:05:02 +03:00

309 lines
7.0 KiB
C++

#pragma once
#include <gdiplusex.h>
#include <structures.h>
#include <AtlDefine.h>
#include <MediaFormatDefine.h>
#define IMAGE_STUDIO_TEXT_RENDER
namespace Windows
{
// êëàññ, ïîçâîëÿþùèé ïðîñòî äåëàòü îòðèñîâêó ñ èñïîëüçîâàíèåì back buffer'à
// èñïîëüçóåòñÿ gdi hbitmap äëÿ back buffer'à
class CDoubleBuffer
{
protected:
Structures::RECTI m_rect;
HDC m_hForeDC;
HDC m_hBackDC;
HBITMAP m_hBackBitmap;
HGDIOBJ m_hBackBitmapOld;
BYTE* m_pBackBitmapPixels;
#ifdef IMAGE_STUDIO_TEXT_RENDER
MediaCore::IAVSUncompressedVideoFrame* m_pMediaData;
#endif
public:
CDoubleBuffer()
{
m_hForeDC = 0;
m_hBackDC = 0;
m_hBackBitmap = 0;
m_hBackBitmapOld = 0;
m_pBackBitmapPixels = 0;
m_pMediaData = NULL;
}
~CDoubleBuffer()
{
Destroy();
}
void Destroy()
{
#ifdef IMAGE_STUDIO_TEXT_RENDER
RELEASEINTERFACE ( m_pMediaData );
m_pBackBitmapPixels = NULL;
#else if
if (m_pBackBitmapPixels)
{
delete[] m_pBackBitmapPixels;
m_pBackBitmapPixels = 0;
}
#endif
if (m_hBackDC)
{
SelectObject(m_hBackDC, m_hBackBitmapOld);
DeleteObject(m_hBackBitmap);
DeleteDC(m_hBackDC);
}
m_hForeDC = 0;
m_hBackDC = 0;
m_hBackBitmap = 0;
m_hBackBitmapOld = 0;
}
BOOL Create(HDC hDC, RECT rect, BOOL bCreateBackPixelBuffer)
{
if (!hDC || rect.right == rect.left || rect.bottom == rect.top)
{
Destroy();
return TRUE;
}
BOOL bReCreated = FALSE;
Structures::RECTI rectI(rect);
// clear resources if painting settings has changed
if (rectI != m_rect)
Destroy();
m_hForeDC = hDC;
m_rect = rectI;
// reallocate pixel buffer only if the new size is greater than the old
if (bCreateBackPixelBuffer)
{
if (!m_pBackBitmapPixels)
{
#ifdef IMAGE_STUDIO_TEXT_RENDER
if ( CreateMediaData ( ) )
{
m_pMediaData->get_Buffer ( &m_pBackBitmapPixels );
}
#else if
m_pBackBitmapPixels = new BYTE[4*m_rect.GetWidth()*m_rect.GetHeight()];
#endif
bReCreated = TRUE;
}
}
// create back buffer device context for smooth blitting
if (!m_hBackBitmap)
{
m_hBackBitmap = CreateCompatibleBitmap(m_hForeDC, m_rect.GetWidth(), m_rect.GetHeight());
m_hBackDC = CreateCompatibleDC(m_hForeDC);
m_hBackBitmapOld = SelectObject(m_hBackDC, m_hBackBitmap);
bReCreated = TRUE;
}
return bReCreated;
}
void Render()
{
if (!Valid())
return;
BitBlt(m_hForeDC, m_rect.left, m_rect.top, m_rect.GetWidth(), m_rect.GetHeight(), m_hBackDC, 0, 0, SRCCOPY);
}
void RenderBackBitmapPixels()
{
if (!Valid() || !m_pBackBitmapPixels)
return;
BITMAPINFO oBitmapInfo;
oBitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
oBitmapInfo.bmiHeader.biHeight = m_rect.GetHeight();
oBitmapInfo.bmiHeader.biWidth = m_rect.GetWidth();
oBitmapInfo.bmiHeader.biPlanes = 1;
oBitmapInfo.bmiHeader.biBitCount = 32;
oBitmapInfo.bmiHeader.biCompression = BI_RGB;
oBitmapInfo.bmiHeader.biSizeImage = 0;
oBitmapInfo.bmiHeader.biXPelsPerMeter = 1;
oBitmapInfo.bmiHeader.biYPelsPerMeter = 1;
oBitmapInfo.bmiHeader.biClrUsed = 0;
oBitmapInfo.bmiHeader.biClrImportant = 0;
SetDIBitsToDevice(m_hBackDC, 0, 0, m_rect.GetWidth(), m_rect.GetHeight(), 0, 0, 0, m_rect.GetHeight(), m_pBackBitmapPixels, &oBitmapInfo, DIB_RGB_COLORS);
}
BOOL Valid()
{
if (!m_hForeDC || !m_hBackDC || !m_hBackBitmap)
return FALSE;
return TRUE;
}
HDC GetForeDC()
{
return m_hForeDC;
}
HDC GetBackDC()
{
return m_hBackDC;
}
Structures::RECTI GetRect()
{
return m_rect;
}
HBITMAP GetBackBitmap()
{
return m_hBackBitmap;
}
BYTE* GetBackBitmapPixels()
{
return m_pBackBitmapPixels;
}
#ifdef IMAGE_STUDIO_TEXT_RENDER
bool CreateMediaData ( )
{
RELEASEINTERFACE ( m_pMediaData );
if ( SUCCEEDED ( CoCreateInstance ( MediaCore::CLSID_CAVSUncompressedVideoFrame, NULL, CLSCTX_ALL, MediaCore::IID_IAVSUncompressedVideoFrame, (void**)(&m_pMediaData) ) ) )
{
if ( NULL == m_pMediaData )
return false;
m_pMediaData->put_ColorSpace ( CSP_BGRA );
m_pMediaData->put_Width ( m_rect.GetWidth() );
m_pMediaData->put_Height ( m_rect.GetHeight() );
m_pMediaData->put_AspectRatioX ( m_rect.GetWidth() );
m_pMediaData->put_AspectRatioY ( m_rect.GetHeight() );
m_pMediaData->SetDefaultStrides ( );
m_pMediaData->AllocateBuffer ( -1 );
return true;
}
return false;
}
MediaCore::IAVSUncompressedVideoFrame* GetSurface ()
{
return m_pMediaData;
}
#endif
};
// Êëàññû, ïîçâîëÿþùèå ðåàëèçîâûâàòü ñõåìó ñ "çàìåäëåííûì îáíîâëåíèåì" (delayed updates)
// íàïðèìåð äëÿ ñîçäàíèÿ âèçóàëüíûõ êîìïîíåíò ñ çàäåðæêîé â îáíîâëåíèè back-buffer'à
// Äëÿ ðåàëèçàöèè ýòîé ñõåìû íàäî:
// 1. ïîðîäèòü îáíîâëÿåìóþ êîìïîíåíòó îò CUpdateReceiver è ðåàëèçîâàòü OnUpdate()
// 2. â îáíîâëÿåìîé êîìïîíåíòå çàâåñòè òàéìåð è âûçûâàòü Update(this) ïî òàéìåðó
// ñêîðîñòü òàéìåðà äîëæíà áûòü â 2 ðàçà áîëüøå, ÷åì ñêîðîñòü æåëàåìîãî update'à
// 3. â ôóíêöèè Update() îáíîâëÿòü ñîñòîÿíèå, îáíîâëÿòü State, ÷èñòèòü Request è
// îñóùåñòâëÿòü ïåðåðèñîâêó êîìïîíåíòû è ò.ï.
namespace Update
{
// òåêóùèå ñîñòîÿíèÿ îáúåêòà - áèòîâàÿ ìàñêà!
// ýòîò ñïèñîê íàäî ñîñòàâëÿòü ñàìîìó
const int c_nStateNonInitialized = 0;
const int c_nStateInitialized = 1;
// êîìàíäû äëÿ îáíîâëåíèÿ ÷åãî-ëèáî - áèòîâàÿ ìàñêà!
// ýòîò ñïèñîê íàäî ñîñòàâëÿòü ñàìîìó
const int c_nRequestUpdateNone = 0;
const int c_nRequestUpdateAll = 1;
const int c_nRequestRefresh = 1024;
const int c_nRequestDelayUpdate = 2048;
class CUpdateManager;
class CUpdateReceiver
{
public:
virtual void OnUpdate(CUpdateManager* pUpdateManager) = 0;
};
class CUpdateManager
{
public:
int m_nState;
int m_nRequest;
public:
CUpdateManager()
{
m_nState = c_nStateNonInitialized;
m_nRequest = c_nRequestUpdateNone;
}
int StateGet()
{
return m_nState;
}
BOOL IsState(int State)
{
return (m_nState & State);
}
void StateSet(int State)
{
m_nState = State;
}
void StateAdd(int State)
{
m_nState |= State;
}
void StateRemove(int State)
{
m_nState = (m_nState & ~State);
}
int RequestGet()
{
return m_nRequest;
}
BOOL IsRequest(int Request)
{
return (m_nRequest & Request);
}
void RequestSet(int Request)
{
m_nRequest = Request;
}
void RequestAdd(int Request)
{
m_nRequest |= Request;
}
void RequestRemove(int Request)
{
m_nRequest = (m_nRequest & ~Request);
}
void Update(CUpdateReceiver* pUpdateReceiver)
{
// check for delayed update
if (IsRequest(c_nRequestDelayUpdate))
return;
// update receiver
if (pUpdateReceiver)
pUpdateReceiver->OnUpdate(this);
}
};
}
}