📄 winctrl.cpp
字号:
return NOERROR;
}
// This allows a client to set the complete window size and position in one
// atomic operation. The same affect can be had by changing each dimension
// in turn through their individual properties although some flashing will
// occur as each of them gets updated (they are better set at design time)
STDMETHODIMP
CBaseControlWindow::SetWindowPosition(long Left,long Top,long Width,long Height)
{
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
BOOL bSuccess;
// Set the new size and position
UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE;
ASSERT(IsWindow(m_hwnd));
bSuccess = SetWindowPos(m_hwnd, // Window handle
HWND_TOP, // Put it at the top
Left, // Left position
Top, // Top position
Width, // Window width
Height, // Window height
WindowFlags); // Show window flags
ASSERT(bSuccess);
#ifdef DEBUG
DbgLog((LOG_TRACE, 1, TEXT("SWP failed error %d"), GetLastError()));
#endif
if (bSuccess == FALSE) {
return E_INVALIDARG;
}
return NOERROR;
}
// This complements the SetWindowPosition to return the current window place
// in device coordinates. As before the same information can be retrived by
// calling the property get functions individually but this is atomic and is
// therefore more suitable to a live environment rather than design time
STDMETHODIMP
CBaseControlWindow::GetWindowPosition(long *pLeft,long *pTop,long *pWidth,long *pHeight)
{
// Should check the pointers are not NULL
CheckPointer(pLeft,E_POINTER);
CheckPointer(pTop,E_POINTER);
CheckPointer(pWidth,E_POINTER);
CheckPointer(pHeight,E_POINTER);
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
RECT WindowRect;
// Get the current window coordinates
EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect));
// Convert the RECT into left,top,width and height values
*pLeft = WindowRect.left;
*pTop = WindowRect.top;
*pWidth = WindowRect.right - WindowRect.left;
*pHeight = WindowRect.bottom - WindowRect.top;
return NOERROR;
}
// When a window is maximised or iconic calling GetWindowPosition will return
// the current window position (likewise for the properties). However if the
// restored size (ie the size we'll return to when normally shown) is needed
// then this should be used. When in a normal position (neither iconic nor
// maximised) then this returns the same coordinates as GetWindowPosition
STDMETHODIMP
CBaseControlWindow::GetRestorePosition(long *pLeft,long *pTop,long *pWidth,long *pHeight)
{
// Should check the pointers are not NULL
CheckPointer(pLeft,E_POINTER);
CheckPointer(pTop,E_POINTER);
CheckPointer(pWidth,E_POINTER);
CheckPointer(pHeight,E_POINTER);
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
// Use GetWindowPlacement to find the restore position
WINDOWPLACEMENT Place;
Place.length = sizeof(WINDOWPLACEMENT);
EXECUTE_ASSERT(GetWindowPlacement(m_hwnd,&Place));
RECT WorkArea;
// We must take into account any task bar present
if (SystemParametersInfo(SPI_GETWORKAREA,0,&WorkArea,FALSE) == TRUE) {
if (GetParent(m_hwnd) == NULL) {
Place.rcNormalPosition.top += WorkArea.top;
Place.rcNormalPosition.bottom += WorkArea.top;
Place.rcNormalPosition.left += WorkArea.left;
Place.rcNormalPosition.right += WorkArea.left;
}
}
// Convert the RECT into left,top,width and height values
*pLeft = Place.rcNormalPosition.left;
*pTop = Place.rcNormalPosition.top;
*pWidth = Place.rcNormalPosition.right - Place.rcNormalPosition.left;
*pHeight = Place.rcNormalPosition.bottom - Place.rcNormalPosition.top;
return NOERROR;
}
// Return the current border colour, if we are playing something to a subset
// of the base window display there is an outside area exposed. The default
// action is to paint this colour in the Windows background colour (defined
// as value COLOR_WINDOW) We reset to this default when we're disconnected
STDMETHODIMP CBaseControlWindow::get_BorderColor(long *Color)
{
CheckPointer(Color,E_POINTER);
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
*Color = (long) m_BorderColour;
return NOERROR;
}
// This can be called to set the current border colour
STDMETHODIMP CBaseControlWindow::put_BorderColor(long Color)
{
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
// Have the window repainted with the new border colour
m_BorderColour = (COLORREF) Color;
PaintWindow(TRUE);
return NOERROR;
}
// Delegate fullscreen handling to plug in distributor
STDMETHODIMP CBaseControlWindow::get_FullScreenMode(long *FullScreenMode)
{
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
CheckPointer(FullScreenMode,E_POINTER);
return E_NOTIMPL;
}
// Delegate fullscreen handling to plug in distributor
STDMETHODIMP CBaseControlWindow::put_FullScreenMode(long FullScreenMode)
{
return E_NOTIMPL;
}
// This sets the auto show property, this property causes the base window to
// be displayed whenever we change state. This allows an application to have
// to do nothing to have the window appear but still allow them to change the
// default behaviour if for example they want to keep it hidden for longer
STDMETHODIMP CBaseControlWindow::put_AutoShow(long AutoShow)
{
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
// Check this is a valid automation boolean type
if (AutoShow != OATRUE) {
if (AutoShow != OAFALSE) {
return E_INVALIDARG;
}
}
m_bAutoShow = (AutoShow == OATRUE ? TRUE : FALSE);
return NOERROR;
}
// This can be called to get the current auto show flag. The flag is updated
// when we connect and disconnect and through this interface all of which are
// controlled and serialised by means of the main renderer critical section
STDMETHODIMP CBaseControlWindow::get_AutoShow(long *AutoShow)
{
CheckPointer(AutoShow,E_POINTER);
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
*AutoShow = (m_bAutoShow == TRUE ? OATRUE : OAFALSE);
return NOERROR;
}
// Return the minimum ideal image size for the current video. This may differ
// to the actual video dimensions because we may be using DirectDraw hardware
// that has specific stretching requirements. For example the Cirrus Logic
// cards have a minimum stretch factor depending on the overlay surface size
STDMETHODIMP
CBaseControlWindow::GetMinIdealImageSize(long *pWidth,long *pHeight)
{
CheckPointer(pWidth,E_POINTER);
CheckPointer(pHeight,E_POINTER);
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
FILTER_STATE State;
// Must not be stopped for this to work correctly
m_pFilter->GetState(0,&State);
if (State == State_Stopped) {
return VFW_E_WRONG_STATE;
}
RECT DefaultRect = GetDefaultRect();
*pWidth = WIDTH(&DefaultRect);
*pHeight = HEIGHT(&DefaultRect);
return NOERROR;
}
// Return the maximum ideal image size for the current video. This may differ
// to the actual video dimensions because we may be using DirectDraw hardware
// that has specific stretching requirements. For example the Cirrus Logic
// cards have a maximum stretch factor depending on the overlay surface size
STDMETHODIMP
CBaseControlWindow::GetMaxIdealImageSize(long *pWidth,long *pHeight)
{
CheckPointer(pWidth,E_POINTER);
CheckPointer(pHeight,E_POINTER);
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
FILTER_STATE State;
// Must not be stopped for this to work correctly
m_pFilter->GetState(0,&State);
if (State == State_Stopped) {
return VFW_E_WRONG_STATE;
}
RECT DefaultRect = GetDefaultRect();
*pWidth = WIDTH(&DefaultRect);
*pHeight = HEIGHT(&DefaultRect);
return NOERROR;
}
// Allow an application to hide the cursor on our window
STDMETHODIMP
CBaseControlWindow::HideCursor(long HideCursor)
{
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
// Check this is a valid automation boolean type
if (HideCursor != OATRUE) {
if (HideCursor != OAFALSE) {
return E_INVALIDARG;
}
}
m_bCursorHidden = (HideCursor == OATRUE ? TRUE : FALSE);
return NOERROR;
}
// Returns whether we have the cursor hidden or not
STDMETHODIMP CBaseControlWindow::IsCursorHidden(long *CursorHidden)
{
CheckPointer(CursorHidden,E_POINTER);
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
*CursorHidden = (m_bCursorHidden == TRUE ? OATRUE : OAFALSE);
return NOERROR;
}
// This class implements the IBasicVideo control functions (dual interface)
// we support a large number of properties and methods designed to allow the
// client (whether it be an automation controller or a C/C++ application) to
// set and get a number of video related properties such as the native video
// size. We support some methods that duplicate the properties but provide a
// more direct and efficient mechanism as many values may be changed in one
CBaseControlVideo::CBaseControlVideo(
CBaseFilter *pFilter, // Owning filter
CCritSec *pInterfaceLock, // Locking object
TCHAR *pName, // Object description
LPUNKNOWN pUnk, // Normal COM ownership
HRESULT *phr) : // OLE return code
CBaseBasicVideo(pName,pUnk),
m_pFilter(pFilter),
m_pInterfaceLock(pInterfaceLock),
m_pPin(NULL)
{
ASSERT(m_pFilter);
ASSERT(m_pInterfaceLock);
ASSERT(phr);
}
// Return an approximate average time per frame
STDMETHODIMP CBaseControlVideo::get_AvgTimePerFrame(REFTIME *pAvgTimePerFrame)
{
CheckPointer(pAvgTimePerFrame,E_POINTER);
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
CAutoLock cInterfaceLock(m_pInterfaceLock);
VIDEOINFOHEADER *pVideoInfo = GetVideoFormat();
if (pVideoInfo == NULL)
return E_OUTOFMEMORY;
COARefTime AvgTime(pVideoInfo->AvgTimePerFrame);
*pAvgTimePerFrame = (REFTIME) AvgTime;
return NOERROR;
}
// Return an approximate bit rate for the video
STDMETHODIMP CBaseControlVideo::get_BitRate(long *pBitRate)
{
CheckPointer(pBitRate,E_POINTER);
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
CAutoLock cInterfaceLock(m_pInterfaceLock);
VIDEOINFOHEADER *pVideoInfo = GetVideoFormat();
if (pVideoInfo == NULL)
return E_OUTOFMEMORY;
*pBitRate = pVideoInfo->dwBitRate;
return NOERROR;
}
// Return an approximate bit error rate
STDMETHODIMP CBaseControlVideo::get_BitErrorRate(long *pBitErrorRate)
{
CheckPointer(pBitErrorRate,E_POINTER);
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
CAutoLock cInterfaceLock(m_pInterfaceLock);
VIDEOINFOHEADER *pVideoInfo = GetVideoFormat();
if (pVideoInfo == NULL)
return E_OUTOFMEMORY;
*pBitErrorRate = pVideoInfo->dwBitErrorRate;
return NOERROR;
}
// This returns the current video width
STDMETHODIMP CBaseControlVideo::get_VideoWidth(long *pVideoWidth)
{
CheckPointer(pVideoWidth,E_POINTER);
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
CAutoLock cInterfaceLock(m_pInterfaceLock);
VIDEOINFOHEADER *pVideoInfo = GetVideoFormat();
if (pVideoInfo == NULL)
return E_OUTOFMEMORY;
*pVideoWidth = pVideoInfo->bmiHeader.biWidth;
return NOERROR;
}
// This returns the current video height
STDMETHODIMP CBaseControlVideo::get_VideoHeight(long *pVideoHeight)
{
CheckPointer(pVideoHeight,E_POINTER);
CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
CAutoLock cInterfaceLock(m_pInterfaceLock);
VIDEOINFOHEADER *pVideoInfo = GetVideoFormat();
if (pVideoInfo == NULL)
return E_OUTOFMEMORY;
*pVideoHeight = pVideoInfo->bmiHeader.biHeight;
return NOERROR;
}
// This returns the current palette the video is using as an array allocated
// by the user. To remain consistent we use PALETTEENTRY fields to return the
// colours in rather than RGBQUADs that multimedia decided to use. The memory
// is allocated by the user so we simple copy each in turn. We check that the
// number of entries requested and the start position offset are both valid
// If the number of entries evaluates to zero then we return an S_FALSE code
STDMETHODIMP CBaseControlVideo::GetVideoPaletteEntries(long StartIndex,
long Entries,
long *pRetrieved,
long *pPalette)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -