First commit of the project
Just a first try.
This commit is contained in:
665
PTZControl/ExtensionUnit.cpp
Normal file
665
PTZControl/ExtensionUnit.cpp
Normal file
@@ -0,0 +1,665 @@
|
||||
#include "pch.h"
|
||||
// #include <sstream>
|
||||
// #include <iomanip>
|
||||
// #include <iostream> // Including this before DShow.h avoids a bunch of C4995 warnings for unsafe
|
||||
// // string functions if (and only if) strsafe.h is not included above.
|
||||
|
||||
#include <initguid.h>
|
||||
#include <comdef.h>
|
||||
#define NO_DSHOW_STRSAFE // Avoid more C4995 warnings in intrin.h
|
||||
#include <DShow.h>
|
||||
#include <Ks.h>
|
||||
#include <KsMedia.h>
|
||||
|
||||
#pragma comment(lib, "strmiids.lib")
|
||||
|
||||
#include "ExtensionUnit.h"
|
||||
|
||||
#define NONODE 0xFFFFFFFF
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void MySleep(int mSec)
|
||||
{
|
||||
// TIcks per second
|
||||
LARGE_INTEGER li;
|
||||
QueryPerformanceFrequency(&li);
|
||||
|
||||
LARGE_INTEGER liStart;
|
||||
QueryPerformanceCounter(&liStart);
|
||||
|
||||
LARGE_INTEGER liEnd;
|
||||
liEnd.QuadPart = liStart.QuadPart + (li.QuadPart*mSec)/1000;
|
||||
|
||||
LARGE_INTEGER liNow;
|
||||
do
|
||||
{
|
||||
QueryPerformanceCounter(&liNow);
|
||||
}
|
||||
while (liNow.QuadPart<liEnd.QuadPart);
|
||||
TRACE(__FUNCTION__ " %d\n", DWORD((liNow.QuadPart-liStart.QuadPart)*1000/li.QuadPart));
|
||||
}
|
||||
|
||||
|
||||
CWebcamController::CWebcamController()
|
||||
{
|
||||
CloseDevice();
|
||||
}
|
||||
|
||||
|
||||
CWebcamController::~CWebcamController()
|
||||
{
|
||||
CloseDevice();
|
||||
}
|
||||
|
||||
HRESULT CWebcamController::OpenDevice(BSTR bstrDevicePath, DWORD wVID, DWORD wPID)
|
||||
{
|
||||
// Create the System Device Enumerator
|
||||
CComPtr<ICreateDevEnum> pSysDevEnum;
|
||||
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, __uuidof(ICreateDevEnum), (void **)&pSysDevEnum);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
// Obtain a class enumerator for the video input device category
|
||||
CComPtr<IEnumMoniker> pEnumCat;
|
||||
hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);
|
||||
if(hr == S_OK)
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
|
||||
|
||||
// Enumerate the monikers and check if we can find a matching device
|
||||
CComPtr<IMoniker> pMoniker;
|
||||
ULONG cFetched;
|
||||
while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
|
||||
{
|
||||
if(DeviceMatches(pMoniker, bstrDevicePath, wVID, wPID))
|
||||
{
|
||||
hr = OpenDevice(pMoniker);
|
||||
break; // We're done searching (even if the OpenDevice() call above failed)
|
||||
}
|
||||
pMoniker = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
void CWebcamController::CloseDevice()
|
||||
{
|
||||
m_spKsControl = nullptr;
|
||||
m_spAMCameraControl = nullptr;
|
||||
m_spsPropertySet = nullptr;
|
||||
m_spCameraControl = nullptr;
|
||||
|
||||
m_dwXUDeviceInformationNodeId =
|
||||
m_dwXUVideoPipeControlNodeId =
|
||||
m_dwXUTestDebugNodeId =
|
||||
m_dwXUPeripheralControlNodeId = NONODE;
|
||||
|
||||
// Use IAMCameraControl motion control
|
||||
m_bUseLogitechMotionControl = false;
|
||||
m_iMotorIntervalTimer = DEFAULT_MOTOR_INTERVAL_TIMER;
|
||||
|
||||
// The PTZ Pro 2 has a mechanical pan tilt
|
||||
m_bMechanicalPanTilt = false;
|
||||
m_lDigitalTiltMin = m_lDigitalTiltMax = m_lDigitalPanMin = m_lDigitalPanMax = -1;
|
||||
}
|
||||
|
||||
HRESULT CWebcamController::IsPeripheralPropertySetSupported()
|
||||
{
|
||||
if (!m_spKsControl)
|
||||
return -1;
|
||||
|
||||
KSP_NODE extProp{};
|
||||
extProp.Property.Set = LOGITECH_XU_PERIPHERAL_CONTROL;
|
||||
extProp.Property.Id = 0;
|
||||
extProp.Property.Flags = KSPROPERTY_TYPE_SETSUPPORT | KSPROPERTY_TYPE_TOPOLOGY;
|
||||
extProp.NodeId = m_dwXUPeripheralControlNodeId;
|
||||
extProp.Reserved = 0;
|
||||
ULONG ulBytesReturned = 0;
|
||||
return m_spKsControl->KsProperty((PKSPROPERTY)&extProp, sizeof(extProp), NULL, 0, &ulBytesReturned);
|
||||
}
|
||||
|
||||
HRESULT CWebcamController::GetProperty(LOGITECH_XU_PROPERTYSET lPropertySet,ULONG ulPropertyId, ULONG ulSize, VOID *pValue)
|
||||
{
|
||||
if (!m_spKsControl)
|
||||
return -1;
|
||||
|
||||
ASSERT(pValue!=0 && ulSize!=0);
|
||||
|
||||
KSP_NODE extprop{};
|
||||
extprop.Property.Id = ulPropertyId;
|
||||
extprop.Property.Flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY;
|
||||
|
||||
switch(lPropertySet)
|
||||
{
|
||||
case XU_DEVICE_INFORMATION:
|
||||
extprop.NodeId = m_dwXUDeviceInformationNodeId;
|
||||
extprop.Property.Set = LOGITECH_XU_DEVICE_INFORMATION;
|
||||
break;
|
||||
case XU_VIDEOPIPE_CONTROL:
|
||||
extprop.NodeId = m_dwXUVideoPipeControlNodeId;
|
||||
extprop.Property.Set = LOGITECH_XU_VIDEOPIPE_CONTROL;
|
||||
break;
|
||||
case XU_TEST_DEBUG:
|
||||
extprop.NodeId = m_dwXUTestDebugNodeId;
|
||||
extprop.Property.Set = LOGITECH_XU_TEST_DEBUG;
|
||||
break;
|
||||
case XU_PERIPHERAL_CONTROL:
|
||||
extprop.NodeId = m_dwXUPeripheralControlNodeId;
|
||||
extprop.Property.Set = LOGITECH_XU_PERIPHERAL_CONTROL;
|
||||
break;
|
||||
}
|
||||
|
||||
HRESULT hr = m_spKsControl->KsProperty(
|
||||
(PKSPROPERTY)&extprop,
|
||||
sizeof(extprop),
|
||||
pValue,
|
||||
ulSize,
|
||||
&ulSize
|
||||
);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CWebcamController::SetProperty(LOGITECH_XU_PROPERTYSET lPropertySet,ULONG ulPropertyId, ULONG ulSize, VOID *pValue)
|
||||
{
|
||||
if (!m_spKsControl)
|
||||
return -1;
|
||||
|
||||
ASSERT(pValue != 0 && ulSize != 0);
|
||||
|
||||
KSP_NODE extprop{};
|
||||
extprop.Property.Id = ulPropertyId;
|
||||
extprop.Property.Flags = KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY;
|
||||
|
||||
switch(lPropertySet)
|
||||
{
|
||||
case XU_DEVICE_INFORMATION:
|
||||
extprop.NodeId = m_dwXUDeviceInformationNodeId;
|
||||
extprop.Property.Set = LOGITECH_XU_DEVICE_INFORMATION;
|
||||
break;
|
||||
case XU_VIDEOPIPE_CONTROL:
|
||||
extprop.NodeId = m_dwXUVideoPipeControlNodeId;
|
||||
extprop.Property.Set = LOGITECH_XU_VIDEOPIPE_CONTROL;
|
||||
break;
|
||||
case XU_TEST_DEBUG:
|
||||
extprop.NodeId = m_dwXUTestDebugNodeId;
|
||||
extprop.Property.Set = LOGITECH_XU_TEST_DEBUG;
|
||||
break;
|
||||
case XU_PERIPHERAL_CONTROL:
|
||||
extprop.NodeId = m_dwXUPeripheralControlNodeId;
|
||||
extprop.Property.Set = LOGITECH_XU_PERIPHERAL_CONTROL;
|
||||
break;
|
||||
}
|
||||
|
||||
ULONG ulBytesReturned;
|
||||
HRESULT hr = m_spKsControl->KsProperty(
|
||||
(PKSPROPERTY)&extprop,
|
||||
sizeof(extprop),
|
||||
pValue,
|
||||
ulSize,
|
||||
&ulBytesReturned
|
||||
);
|
||||
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether the device represented by the given IMoniker matches the given device path
|
||||
* or the given VID/PID.
|
||||
*
|
||||
* If the device path is NULL no device path matching is performed.
|
||||
* A VID or PID of 0 is considered to always match. If the VID and PID are both 0 no VID/PID
|
||||
* matching is performed.
|
||||
*/
|
||||
bool CWebcamController::DeviceMatches(CComPtr<IMoniker> pMoniker, BSTR devicePath, DWORD wVID, DWORD wPID)
|
||||
{
|
||||
|
||||
bool match = false;
|
||||
CComPtr<IPropertyBag> pPropBag;
|
||||
CComVariant varPath;
|
||||
|
||||
// Open the device properties
|
||||
HRESULT hr = pMoniker->BindToStorage(NULL, NULL, __uuidof(IPropertyBag), (void **)&pPropBag);
|
||||
if(FAILED(hr))
|
||||
goto done;
|
||||
|
||||
// Retrieve the device path
|
||||
hr = pPropBag->Read(L"DevicePath", &varPath, 0);
|
||||
if(FAILED(hr) || varPath.bstrVal == NULL)
|
||||
goto done;
|
||||
|
||||
// Return true if the device path matches
|
||||
if(devicePath!=NULL)
|
||||
{
|
||||
// Parse the device path for vid pid
|
||||
m_dwVid = m_dwPid = 0;
|
||||
if (FAILED(varPath.ChangeType(VT_BSTR)))
|
||||
return false;
|
||||
|
||||
if (_wcsicmp(varPath.bstrVal, devicePath) == 0)
|
||||
{
|
||||
// Lowercase
|
||||
_wcslwr_s(varPath.bstrVal, SysStringLen(varPath.bstrVal) + 1);
|
||||
ParseDevicePath(varPath.bstrVal, m_dwVid, m_dwPid);
|
||||
|
||||
match = true;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if the USB information matches
|
||||
if(wVID || wPID)
|
||||
{
|
||||
// Parse the device path (Convert it to lower-case first for safer parsing)
|
||||
_wcslwr_s(varPath.bstrVal, SysStringLen(varPath.bstrVal) + 1);
|
||||
DWORD vid = 0, pid = 0;
|
||||
if(ParseDevicePath(varPath.bstrVal, vid, pid))
|
||||
{
|
||||
match =
|
||||
(wVID == 0 || vid == wVID) &&
|
||||
(wPID == 0 || pid == wPID);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
VariantClear(&varPath);
|
||||
return match;
|
||||
}
|
||||
|
||||
HRESULT CWebcamController::OpenDevice(CComPtr<IMoniker> pMoniker)
|
||||
{
|
||||
CComPtr<IKsControl> pKsControl;
|
||||
|
||||
// Get a pointer to the IKsControl interface
|
||||
HRESULT hr = pMoniker->BindToObject(NULL, NULL, __uuidof(IKsControl), (void **)&pKsControl);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
// Find the H.264 XU node
|
||||
hr = InitializeXUNodesArray(pKsControl);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
// save the pointer, we succeeded
|
||||
m_spKsControl = pKsControl;
|
||||
|
||||
m_spAMCameraControl = pKsControl;
|
||||
m_spsPropertySet = pKsControl;
|
||||
m_spCameraControl = pKsControl; // not supported
|
||||
}
|
||||
|
||||
if (m_spAMCameraControl!=nullptr)
|
||||
{
|
||||
long lValue = 0, lMin = 0, lMax = 0, lSteppingSize = 0, lDefaults = 0, lFlags = 0;
|
||||
HRESULT hResult = m_spAMCameraControl->Get(KSPROPERTY_CAMERACONTROL_PAN_RELATIVE, &lValue, &lFlags);
|
||||
m_bMechanicalPanTilt = SUCCEEDED(hr);
|
||||
|
||||
{
|
||||
for (int i=0; i<=19; ++i)
|
||||
{
|
||||
hResult = m_spAMCameraControl->Get(i, &lValue, &lFlags);
|
||||
if (SUCCEEDED(hr))
|
||||
TRACE(__FUNCTION__ " m_spAMCameraControl-%d val=%d, flag=%d\n",i, lValue, lFlags);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// The PTZ Pro 2 has a mechanical pan tilt
|
||||
ASSERT(m_bMechanicalPanTilt);
|
||||
|
||||
// {
|
||||
// HRESULT hResult = GetProperty( KSPROPERTY_CAMERACONTROL_PANTILT_RELATIVE, &lValue, &lFlags);
|
||||
// }
|
||||
|
||||
hResult = m_spAMCameraControl->GetRange(CameraControl_Pan, &lMin, &lMax, &lSteppingSize, &lDefaults, &lFlags);
|
||||
if (S_OK == hResult)
|
||||
{
|
||||
m_lDigitalPanMin = lMin;
|
||||
m_lDigitalPanMax = lMax;
|
||||
}
|
||||
lMin = lMax = lSteppingSize = lDefaults = lFlags = 0;
|
||||
hResult = m_spAMCameraControl->GetRange(CameraControl_Tilt, &lMin, &lMax, &lSteppingSize, &lDefaults, &lFlags);
|
||||
if (S_OK == hResult)
|
||||
{
|
||||
m_lDigitalTiltMin = lMin;
|
||||
m_lDigitalTiltMax = lMax;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
bool CWebcamController::ParseDevicePath(const wchar_t *devicePath, DWORD &vid, DWORD &pid)
|
||||
{
|
||||
if(swscanf_s(devicePath, L"\\\\?\\usb#vid_%04x&pid_%04x", &vid, &pid) != 2)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWebcamController::GetVidPid(DWORD& vid, DWORD& pid)
|
||||
{
|
||||
vid = m_dwVid;
|
||||
pid = m_dwPid;
|
||||
}
|
||||
|
||||
void CWebcamController::GotoHome()
|
||||
{
|
||||
// Zoom to Home
|
||||
{
|
||||
DWORD dwValue = 0;
|
||||
SetProperty(XU_VIDEOPIPE_CONTROL, XU_VIDEO_FW_ZOOM_CONTROL, sizeof(dwValue), &dwValue);
|
||||
}
|
||||
// Zoom to Home
|
||||
// Home = No Action
|
||||
// 1 ?
|
||||
// 2 ?
|
||||
// Goto Home = 3
|
||||
// 8 Presets
|
||||
// Preset 1-8 = 4-11,
|
||||
// Goto Preset 1-8 = 12-19
|
||||
// Test 22
|
||||
{
|
||||
DWORD dwValue(3);
|
||||
SetProperty(XU_PERIPHERAL_CONTROL, XU_PERIPHERALCONTROL_PANTILT_MODE_CONTROL, sizeof(DWORD), &dwValue);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void CWebcamController::SavePreset(int iNum)
|
||||
{
|
||||
if (iNum<0 || iNum>=NUM_PRESETS)
|
||||
return;
|
||||
|
||||
// Zoom to Home
|
||||
// Home = No Action
|
||||
// 1 ?
|
||||
// 2 ?
|
||||
// Goto Home = 3
|
||||
// 8 Presets
|
||||
// Preset 1-8 = 4-11,
|
||||
// Goto Preset 1-8 = 12-19
|
||||
// Test 22
|
||||
DWORD dwValue(iNum+4);
|
||||
SetProperty(XU_PERIPHERAL_CONTROL, XU_PERIPHERALCONTROL_PANTILT_MODE_CONTROL, sizeof(DWORD), &dwValue);
|
||||
}
|
||||
|
||||
void CWebcamController::GotoPreset(int iNum)
|
||||
{
|
||||
if (iNum<0 || iNum>=NUM_PRESETS)
|
||||
return;
|
||||
|
||||
// Zoom to Home
|
||||
// Home = No Action
|
||||
// 1 ?
|
||||
// 2 ?
|
||||
// Goto Home = 3
|
||||
// 8 Presets
|
||||
// Preset 1-8 = 4-11,
|
||||
// Goto Preset 1-8 = 12-19
|
||||
// Test 22
|
||||
DWORD dwValue(iNum + 12);
|
||||
SetProperty(XU_PERIPHERAL_CONTROL, XU_PERIPHERALCONTROL_PANTILT_MODE_CONTROL, sizeof(DWORD), &dwValue);
|
||||
}
|
||||
|
||||
int CWebcamController::GetCurrentZoom()
|
||||
{
|
||||
if (!m_spAMCameraControl)
|
||||
return -1;
|
||||
|
||||
long oldZoom = 0, oldFlags = 0;
|
||||
oldFlags = CameraControl_Flags_Manual;
|
||||
m_spAMCameraControl->Get(CameraControl_Zoom, &oldZoom, &oldFlags);
|
||||
return oldZoom;
|
||||
}
|
||||
|
||||
int CWebcamController::Zoom(int direction)
|
||||
{
|
||||
if (!m_spAMCameraControl)
|
||||
return -1;
|
||||
|
||||
long lZoomMin = 0, lZoomMax = 0, lZoomDefault = 0, lZoomStep = 0, lFlags = CameraControl_Flags_Manual;
|
||||
m_spAMCameraControl->GetRange(CameraControl_Zoom, &lZoomMin, &lZoomMax, &lZoomStep, &lZoomDefault, &lFlags);
|
||||
|
||||
long lOldZoom = GetCurrentZoom();
|
||||
if (lOldZoom<lZoomMin || lOldZoom>lZoomMax)
|
||||
lOldZoom = lZoomDefault;
|
||||
|
||||
long lNewZoom = lOldZoom;
|
||||
|
||||
// Devide in 150 parts
|
||||
int iStep = (lZoomMax-lZoomMin)/150;
|
||||
if (iStep==0)
|
||||
iStep = 1;
|
||||
|
||||
// calculate new zoom
|
||||
lNewZoom = lOldZoom + lZoomStep*direction*iStep; // Just get 100 steps
|
||||
|
||||
m_spAMCameraControl->Set(CameraControl_Zoom, lNewZoom, CameraControl_Flags_Manual);
|
||||
return lNewZoom;
|
||||
}
|
||||
|
||||
void CWebcamController::Tilt(int yDirection)
|
||||
{
|
||||
if (m_spAMCameraControl)
|
||||
m_spAMCameraControl->Set(KSPROPERTY_CAMERACONTROL_TILT_RELATIVE, yDirection!=0 ? (yDirection < 0 ? -1 : 1) : 0, 0);
|
||||
}
|
||||
|
||||
void CWebcamController::MoveTilt(int yDirection)
|
||||
{
|
||||
if (m_bUseLogitechMotionControl && m_dwXUPeripheralControlNodeId!=NONODE)
|
||||
{
|
||||
DWORD dwValue = MAKELONG(MAKEWORD(0, 0), MAKEWORD(0, yDirection < 0 ? 1 : -1));
|
||||
SetProperty(XU_PERIPHERAL_CONTROL, XU_PERIPHERALCONTROL_PANTILT_RELATIVE_CONTROL, sizeof(DWORD), &dwValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_spAMCameraControl)
|
||||
return;
|
||||
|
||||
if (m_bMechanicalPanTilt)
|
||||
{
|
||||
if (yDirection != 0)
|
||||
{
|
||||
Tilt(yDirection);
|
||||
MySleep(m_iMotorIntervalTimer);
|
||||
Tilt(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
long lValue(0), lFlags(0);
|
||||
if (yDirection != 0)
|
||||
{
|
||||
HRESULT hResult = m_spAMCameraControl->Get(CameraControl_Tilt, &lValue, &lFlags);
|
||||
if (S_OK == hResult)
|
||||
{
|
||||
lValue += yDirection;
|
||||
if (yDirection > 0 && lValue > m_lDigitalTiltMax)
|
||||
lValue = m_lDigitalTiltMax;
|
||||
if (yDirection < 0 && lValue < m_lDigitalTiltMin)
|
||||
lValue = m_lDigitalTiltMin;
|
||||
hResult = m_spAMCameraControl->Set(CameraControl_Tilt, lValue, lFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void CWebcamController::Pan(int xDirection)
|
||||
{
|
||||
if (m_spAMCameraControl)
|
||||
m_spAMCameraControl->Set(KSPROPERTY_CAMERACONTROL_PAN_RELATIVE, xDirection!=0 ? (xDirection < 0 ? -1 : 1) : 0, 0);
|
||||
}
|
||||
|
||||
void CWebcamController::MovePan(int xDirection)
|
||||
{
|
||||
if (m_bUseLogitechMotionControl)
|
||||
{
|
||||
DWORD dwValue = MAKELONG(MAKEWORD(0, xDirection), MAKEWORD(0, 0));
|
||||
SetProperty(XU_PERIPHERAL_CONTROL, XU_PERIPHERALCONTROL_PANTILT_RELATIVE_CONTROL, sizeof(DWORD), &dwValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_spAMCameraControl)
|
||||
return;
|
||||
|
||||
if (m_bMechanicalPanTilt)
|
||||
{
|
||||
if (xDirection != 0)
|
||||
{
|
||||
Pan(xDirection);
|
||||
MySleep(m_iMotorIntervalTimer);
|
||||
Pan(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
long lValue(0), lFlags(0);
|
||||
if (xDirection != 0)
|
||||
{
|
||||
HRESULT hResult = m_spAMCameraControl->Get(CameraControl_Pan, &lValue, &lFlags);
|
||||
if (S_OK == hResult)
|
||||
{
|
||||
lValue += xDirection;
|
||||
if (xDirection > 0 && lValue > m_lDigitalPanMax)
|
||||
lValue = m_lDigitalPanMax;
|
||||
if (xDirection < 0 && lValue < m_lDigitalPanMin)
|
||||
lValue = m_lDigitalPanMin;
|
||||
hResult = m_spAMCameraControl->Set(CameraControl_Pan, lValue, lFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Tries to locate the node that carries H.264 XU extension and saves its ID.
|
||||
*/
|
||||
HRESULT CWebcamController::InitializeXUNodesArray(CComPtr<IKsControl> pKsControl)
|
||||
{
|
||||
// Get the IKsTopologyInfo interface
|
||||
CComQIPtr<IKsTopologyInfo> pKsTopologyInfo = pKsControl;
|
||||
if (!pKsTopologyInfo)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
// Retrieve the number of nodes in the filter
|
||||
DWORD dwNumNodes = 0;
|
||||
HRESULT hr = pKsTopologyInfo->get_NumNodes(&dwNumNodes);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
// Go through all extension unit nodes and try to find the required XU node
|
||||
hr = E_FAIL;
|
||||
std::set<CString> setGuids;
|
||||
for(unsigned int nodeId = 0; nodeId < dwNumNodes; nodeId++)
|
||||
{
|
||||
GUID guidNodeType;
|
||||
hr = pKsTopologyInfo->get_NodeType(nodeId, &guidNodeType);
|
||||
if(FAILED(hr))
|
||||
continue;
|
||||
|
||||
// All Node types we have
|
||||
// { 941C7AC0 - C559 - 11D0 - 8A2B - 00A0C9255AC1 } KSNODETYPE_DEV_SPECIFIC
|
||||
// { DFF229E1 - F70F - 11D0 - B917 - 00A0C9223196 } KSNODETYPE_VIDEO_STREAMING
|
||||
// { DFF229E5 - F70F - 11D0 - B917 - 00A0C9223196 } KSNODETYPE_VIDEO_PROCESSING
|
||||
// { DFF229E6 - F70F - 11D0 - B917 - 00A0C9223196 } KSNODETYPE_VIDEO_CAMERA_TERMINAL
|
||||
{
|
||||
wchar_t szText[100];
|
||||
StringFromGUID2(guidNodeType, szText, _countof(szText));
|
||||
setGuids.emplace(szText);
|
||||
}
|
||||
|
||||
|
||||
if(!IsEqualGUID(guidNodeType, KSNODETYPE_DEV_SPECIFIC))
|
||||
continue;
|
||||
|
||||
if(IsExtensionUnitSupported(pKsControl,LOGITECH_XU_DEVICE_INFORMATION,nodeId))
|
||||
{
|
||||
m_dwXUDeviceInformationNodeId = nodeId;
|
||||
}
|
||||
else if(IsExtensionUnitSupported(pKsControl,LOGITECH_XU_VIDEOPIPE_CONTROL,nodeId))
|
||||
{
|
||||
m_dwXUVideoPipeControlNodeId = nodeId;
|
||||
}
|
||||
else if(IsExtensionUnitSupported(pKsControl,LOGITECH_XU_TEST_DEBUG,nodeId))
|
||||
{
|
||||
m_dwXUTestDebugNodeId = nodeId;
|
||||
}
|
||||
else if(IsExtensionUnitSupported(pKsControl,LOGITECH_XU_PERIPHERAL_CONTROL,nodeId))
|
||||
{
|
||||
m_dwXUPeripheralControlNodeId = nodeId;
|
||||
}
|
||||
// else if (IsExtensionUnitSupported(pKsControl, PROPSETID_VIDCAP_CAMERACONTROL, nodeId))
|
||||
// {
|
||||
// // DWORD dwNodeId = nodeId;
|
||||
// }
|
||||
}
|
||||
for (const auto &str : setGuids)
|
||||
TRACE(__FUNCTION__ " - %ls\n", str.GetString());
|
||||
return hr;
|
||||
}
|
||||
|
||||
bool CWebcamController::IsExtensionUnitSupported(CComPtr<IKsControl> pKsControl,const GUID& guidExtension,unsigned int nodeId)
|
||||
{
|
||||
KSP_NODE extProp{};
|
||||
extProp.Property.Set = guidExtension;
|
||||
extProp.Property.Id = 0;
|
||||
extProp.Property.Flags = KSPROPERTY_TYPE_SETSUPPORT | KSPROPERTY_TYPE_TOPOLOGY;
|
||||
extProp.NodeId = nodeId;
|
||||
extProp.Reserved = 0;
|
||||
ULONG ulBytesReturned = 0;
|
||||
HRESULT hr = pKsControl->KsProperty((PKSPROPERTY)&extProp, sizeof(extProp), NULL, 0, &ulBytesReturned);
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
|
||||
void CWebcamController::ListDevices(CStringArray &aDevices)
|
||||
{
|
||||
aDevices.RemoveAll();
|
||||
|
||||
// Get a device list
|
||||
CComPtr<ICreateDevEnum> pSysDevEnum;
|
||||
HRESULT hr;
|
||||
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pSysDevEnum);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
//create a device class enumerator
|
||||
CComPtr<IEnumMoniker> pIEnumMoniker;
|
||||
HRESULT hResult = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pIEnumMoniker, 0);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ULONG pFetched = NULL;
|
||||
CComPtr<IMoniker> pImoniker;
|
||||
while (S_OK == pIEnumMoniker->Next(1, &pImoniker, &pFetched))
|
||||
{
|
||||
CComPtr<IPropertyBag> pPropBag;
|
||||
hResult = pImoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropBag);
|
||||
if (SUCCEEDED(hResult) && pPropBag!=nullptr)
|
||||
{
|
||||
CComVariant varCameraName, varDevicePath;
|
||||
pPropBag->Read(L"FriendlyName", &varCameraName, 0);
|
||||
pPropBag->Read(L"DevicePath", &varDevicePath, 0);
|
||||
|
||||
if (SUCCEEDED(varCameraName.ChangeType(VT_BSTR)) &&
|
||||
SUCCEEDED(varDevicePath.ChangeType(VT_BSTR)))
|
||||
{
|
||||
CString strCameraName(varCameraName.bstrVal), strDevicePath(varDevicePath.bstrVal);
|
||||
aDevices.Add(strCameraName + _T('\t') + strDevicePath);
|
||||
}
|
||||
}
|
||||
|
||||
// Set to null
|
||||
pImoniker = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
75
PTZControl/ExtensionUnit.h
Normal file
75
PTZControl/ExtensionUnit.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
#include <Ks.h>
|
||||
#include <KsProxy.h> // For IKsControl
|
||||
#include <vidcap.h> // For IKsNodeControl
|
||||
|
||||
#include "ExtensionUnitDefines.h"
|
||||
|
||||
|
||||
#define DEFAULT_MOTOR_INTERVAL_TIMER 70
|
||||
|
||||
/**
|
||||
* CWebcamExtensionUnit encapsulates the USB extension unit capability of the device.
|
||||
* (see https://msdn.microsoft.com/en-us/library/windows/hardware/ff568656(v=vs.85).aspx).
|
||||
*/
|
||||
|
||||
class CWebcamController
|
||||
{
|
||||
public:
|
||||
CWebcamController(void);
|
||||
~CWebcamController(void);
|
||||
|
||||
HRESULT OpenDevice(BSTR bstrDevicePath, DWORD wVID, DWORD wPID);
|
||||
void CloseDevice();
|
||||
HRESULT IsPeripheralPropertySetSupported();
|
||||
HRESULT GetProperty(LOGITECH_XU_PROPERTYSET lPropertySet, ULONG ulPropertyId, ULONG ulSize, VOID* pValue);
|
||||
HRESULT SetProperty(LOGITECH_XU_PROPERTYSET lPropertySet, ULONG ulPropertyId, ULONG ulSize, VOID* pValue);
|
||||
void GetVidPid(DWORD& vid, DWORD& pid);
|
||||
|
||||
int GetCurrentZoom();
|
||||
int Zoom(int direction);
|
||||
void MoveTilt(int yDirection);
|
||||
void MovePan(int xDirection);
|
||||
void Tilt(int yDirection);
|
||||
void Pan(int xDirection);
|
||||
|
||||
void GotoHome();
|
||||
void SavePreset(int iNum);
|
||||
void GotoPreset(int iNum);
|
||||
|
||||
static void ListDevices(CStringArray &aDevices);
|
||||
static const int NUM_PRESETS = 8;
|
||||
|
||||
bool UseLogitechMotionControl() const { return m_bUseLogitechMotionControl; }
|
||||
void UseLogitechMotionControl(bool val) { m_bUseLogitechMotionControl = val; }
|
||||
|
||||
int GetMotorIntervalTimer() const { return m_iMotorIntervalTimer; }
|
||||
void SetMotorIntervalTimer(int val) { m_iMotorIntervalTimer = val; }
|
||||
|
||||
private:
|
||||
bool DeviceMatches(CComPtr<IMoniker> pMoniker, BSTR devicePath, DWORD wVID, DWORD wPID);
|
||||
HRESULT OpenDevice(CComPtr<IMoniker> pMoniker);
|
||||
bool ParseDevicePath(const wchar_t* devicePath, DWORD& vid, DWORD& pid);
|
||||
HRESULT InitializeXUNodesArray(CComPtr<IKsControl> pKsControl);
|
||||
bool IsExtensionUnitSupported(CComPtr<IKsControl> pKsControl, const GUID& guidExtension, unsigned int nodeId);
|
||||
|
||||
private:
|
||||
CComPtr<IKsControl> m_spKsControl;
|
||||
CComQIPtr<IAMCameraControl> m_spAMCameraControl;
|
||||
CComQIPtr<IKsPropertySet> m_spsPropertySet;
|
||||
CComQIPtr<ICameraControl> m_spCameraControl;
|
||||
|
||||
DWORD m_dwXUDeviceInformationNodeId;
|
||||
DWORD m_dwXUVideoPipeControlNodeId;
|
||||
DWORD m_dwXUTestDebugNodeId;
|
||||
DWORD m_dwXUPeripheralControlNodeId;
|
||||
DWORD m_dwVid;
|
||||
DWORD m_dwPid;
|
||||
|
||||
bool m_bMechanicalPanTilt;
|
||||
long m_lDigitalTiltMin, m_lDigitalTiltMax,
|
||||
m_lDigitalPanMin, m_lDigitalPanMax;
|
||||
|
||||
bool m_bUseLogitechMotionControl;
|
||||
int m_iMotorIntervalTimer;
|
||||
};
|
||||
120
PTZControl/ExtensionUnitDefines.h
Normal file
120
PTZControl/ExtensionUnitDefines.h
Normal file
@@ -0,0 +1,120 @@
|
||||
#pragma once
|
||||
|
||||
DEFINE_GUID(LOGITECH_XU_DEVICE_INFORMATION, 0x69678EE4, 0x410F, 0x40DB, 0xA8, 0x50, 0x74, 0x20, 0xD7, 0xD8, 0x24, 0x0E);
|
||||
DEFINE_GUID(LOGITECH_XU_VIDEOPIPE_CONTROL, 0x49E40215, 0xF434, 0x47FE, 0xB1, 0x58, 0x0E, 0x88, 0x50, 0x23, 0xE5, 0x1B);
|
||||
DEFINE_GUID(LOGITECH_XU_TEST_DEBUG, 0x1F5D4CA9, 0xDE11, 0x4487, 0x84, 0x0D, 0x50, 0x93, 0x3C, 0x8E, 0xC8, 0xD1);
|
||||
DEFINE_GUID(LOGITECH_XU_PERIPHERAL_CONTROL, 0xFFE52D21, 0x8030, 0x4E2C, 0x82, 0xD9, 0xF5, 0x87, 0xD0, 0x05, 0x40, 0xBD);
|
||||
|
||||
enum //LOGITECH_XU_DEVICE_INFORMATION
|
||||
{
|
||||
XU_DEVICE_INFORMATION_UNDEFINED_CONTROL = 0x00,
|
||||
XU_FIRMWARE_VERSION_CONTROL = 0x01,
|
||||
XU_FIRMWARE_CRC_CONTROL = 0x02,
|
||||
XU_EEPROM_VERSION_CONTROL = 0x03,
|
||||
XU_SENSOR_INFORMATION_CONTROL = 0x04,
|
||||
XU_PROCESSOR_INFORMATION_CONTROL = 0x05,
|
||||
XU_USB_INFORMATION_CONTROL = 0x06,
|
||||
XU_Reserved1 = 0x07,
|
||||
XU_Reserved2 = 0x08,
|
||||
XU_LENS_FOV_CONTROL = 0x09,
|
||||
XU_SENSOR_DIMENSION_CONTROL = 0x0A,
|
||||
XU_EXTENDED_FIRMWARE_VERSION_CONTROL = 0x0B,
|
||||
};
|
||||
|
||||
enum //LOGITECH_XU_VIDEOPIPE_CONTROL
|
||||
{
|
||||
XU_VIDEO_UNDEFINED_CONTROL = 0x00,
|
||||
XU_VIDEO_COLOR_BOOST_CONTROL = 0x01,
|
||||
XU_VIDEO_NATIVE_MODE_FORCED_CONTROL = 0x02,
|
||||
XU_VIDEO_NATIVE_MODE_AUTO_CONTROL = 0x03,
|
||||
XU_VIDEO_RIGHTLIGHT_MODE_CONTROL = 0x04,
|
||||
XU_VIDEO_RIGHTLIGHT_ZOI_CONTROL = 0x05,
|
||||
XU_VIDEO_FW_ZOOM_CONTROL = 0x06,
|
||||
XU_VIDEO_DUAL_ISO_ENABLE_CONTROL = 0x07,
|
||||
XU_VIDEO_SENSOR_CROPPING_DIMENSION_CONTROL = 0x08,
|
||||
XU_VIDEO_MJPEG_RESYNC_MARKER_CONTROL = 0x09,
|
||||
XU_VIDEO_ADVANCE_DIGITAL_ZOOM_CONTROL = 0x0A,
|
||||
XU_VIDEO_MJPEG_COMPRESS_RATIO_CONTROL = 0x0B,
|
||||
XU_VIDEO_HDR_CONTROL = 0x0C,
|
||||
};
|
||||
|
||||
enum //LOGITECH_XU_TEST_DEBUG
|
||||
{
|
||||
XU_TESTDEBUG_UNDEFINED_CONTROL = 0x00,
|
||||
XU_TEST_REGISTER_ADDRESS_CONTROL = 0x01,
|
||||
XU_TEST_REGISTER_ACCESS_CONTROL = 0x02,
|
||||
XU_TEST_EEPROM_ADDRESS_CONTROL = 0x03,
|
||||
XU_TEST_EEPROM_ACCESS_CONTROL = 0x04,
|
||||
XU_TEST_SENSOR_ADDRESS_CONTROL = 0x05,
|
||||
XU_TEST_SENSOR_ACCESS_CONTROL = 0x06,
|
||||
XU_PERIPHERAL_MODE_CONTROL = 0x07,
|
||||
XU_PERIPHERAL_OP_CONTROL = 0x08,
|
||||
XU_PERIPHERAL_ACCESS_CONTROL = 0x09,
|
||||
XU_TEST_TDE_MODE_CONTROL = 0x0A,
|
||||
XU_TEST_GAIN_ACCESS_CONTROL = 0x0B,
|
||||
XU_TEST_LOW_LIGHT_PRIORITY_CONTROL = 0x0C,
|
||||
XU_TEST_COLOR_PROCESSING_DISABLE_CONTROL = 0x0D,
|
||||
XU_TEST_PIXEL_DEFECT_CORRECTION_CONTROL = 0x0E,
|
||||
XU_TEST_LENS_SHADING_COMPENSATION_CONTROL = 0x0F,
|
||||
XU_TEST_GAMMA_CONTROL = 0x10,
|
||||
XU_TEST_INTEGRATION_TIME_CONTROL = 0x11,
|
||||
XU_TEST_RAW_DATA_BITS_PER_PIXEL_CONTROL = 0x12,
|
||||
XU_TEST_ISP_ADDRESS_CONTROL = 0x13,
|
||||
XU_TEST_ISP_ACCESS_CONTROL = 0x14,
|
||||
XU_PERIPHERAL_ACCESS_EXT_CONTROL = 0x15,
|
||||
XU_H264_FRAME_NO_CONTROL = 0x16,
|
||||
|
||||
};
|
||||
|
||||
// Seams that only 2 modes are defined for the PTZ Pro 2
|
||||
// XU_PERIPHERALCONTROL_PANTILT_RELATIVE_CONTROL = pan tilt
|
||||
// XU_PERIPHERALCONTROL_PANTILT_MODE_CONTROL = Preset and recall position
|
||||
enum //LOGITECH_XU_PERIPHERAL_CONTROL
|
||||
{
|
||||
XU_PERIPHERAL_UNDEFINED_CONTROL = 0x00,
|
||||
XU_PERIPHERALCONTROL_PANTILT_RELATIVE_CONTROL = 0x01, // pan tilt
|
||||
XU_PERIPHERALCONTROL_PANTILT_MODE_CONTROL = 0x02, // Preset and recall position
|
||||
XU_PERIPHERALCONTROL_MAXIMUM_RESOLUTION_SUPPORT_FOR_PANTILT_CONTROL = 0x03,
|
||||
XU_PERIPHERALCONTROL_AF_MOTORCONTROL = 0x04,
|
||||
XU_PERIPHERALCONTROL_AF_BLOB_CONTROL = 0x05,
|
||||
XU_PERIPHERALCONTROL_AF_VCM_PARAMETERS = 0x06,
|
||||
XU_PERIPHERALCONTROL_AF_STATUS = 0x07,
|
||||
XU_PERIPHERALCONTROL_AF_THRESHOLDS = 0x08,
|
||||
XU_PERIPHERALCONTROL_LED = 0x09,
|
||||
XU_PERIPHERAL_CONTROL_PERIPHERAL_STATUS = 0x0A,
|
||||
XU_PERIPHERAL_CONTROL_SPEAKER_VOLUME = 0x0B,
|
||||
XU_PERIPHERAL_CONTROL_DEVICE_CODEC_STATUS = 0x0C,
|
||||
XU_PERIPHERAL_CONTROL_SPEAKER = 0x0D,
|
||||
XU_PERIPHERAL_CONTROL_MODE = 0x0E,
|
||||
XU_AUDIO_LIBRARY_MODE_CONTROL = 0x0F,
|
||||
XU_PERIPHERAL_MOTOR_STEPS_CONTROL = 0x10,
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
XU_DEVICE_INFORMATION,
|
||||
XU_VIDEOPIPE_CONTROL,
|
||||
XU_TEST_DEBUG,
|
||||
XU_PERIPHERAL_CONTROL,
|
||||
} LOGITECH_XU_PROPERTYSET;
|
||||
|
||||
/**
|
||||
* Preset enumerations
|
||||
*/
|
||||
enum
|
||||
{
|
||||
RESET_NOACTION = 0,
|
||||
SET_PRESET = 1,
|
||||
GOTO_PRESET = 2,
|
||||
GOTOHOME = 3
|
||||
};
|
||||
|
||||
// enum
|
||||
// {
|
||||
// RESET_NOACTION = 0,
|
||||
// RESET_PAN = 1,
|
||||
// RESET_TILT = 2,
|
||||
// };
|
||||
|
||||
BIN
PTZControl/PTZControl.aps
Normal file
BIN
PTZControl/PTZControl.aps
Normal file
Binary file not shown.
169
PTZControl/PTZControl.cpp
Normal file
169
PTZControl/PTZControl.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
|
||||
// PTZControl.cpp : Defines the class behaviors for the application.
|
||||
//
|
||||
|
||||
#include "pch.h"
|
||||
#include "framework.h"
|
||||
#include "PTZControl.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAgvipCommandLineInfo
|
||||
// The program must be started with the parameters /conn:<connectionfile>
|
||||
// and /user:<userid>. For the Debug mode special Options are prepared.
|
||||
|
||||
class CPTZControlCommandLineInfo : public CCommandLineInfo
|
||||
{
|
||||
public:
|
||||
// Construction
|
||||
CPTZControlCommandLineInfo()
|
||||
: m_bNoReset(false)
|
||||
, m_bNoGuard(false)
|
||||
, m_bShowDevices(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Overwritten virtual
|
||||
virtual void ParseParam(const TCHAR* pszParam,BOOL bFlag,BOOL bLast);
|
||||
#ifdef _UNICODE
|
||||
virtual void ParseParam(const char* pszParam, BOOL bFlag, BOOL bLast);
|
||||
#endif
|
||||
|
||||
public:
|
||||
// Data
|
||||
CString m_strDevName; // Device name from the command line to search for
|
||||
bool m_bNoReset; // No Reset of web cam
|
||||
bool m_bNoGuard; // Prevent a guard thread
|
||||
bool m_bShowDevices; // SHow message box with devicenames on open.
|
||||
|
||||
// Currently not used (may be used if we ant yes/no/undefined)
|
||||
enum class Mode
|
||||
{
|
||||
False = 0,
|
||||
True = 1,
|
||||
Undefined = -1,
|
||||
};
|
||||
};
|
||||
|
||||
#ifdef _UNICODE
|
||||
void CPTZControlCommandLineInfo::ParseParam(const TCHAR* pszParam,BOOL bFlag,BOOL bLast)
|
||||
{
|
||||
ParseParam(CT2CA(pszParam),bFlag,bLast);
|
||||
}
|
||||
#endif
|
||||
|
||||
void CPTZControlCommandLineInfo::ParseParam(const char* pszParam,BOOL bFlag,BOOL bLast)
|
||||
{
|
||||
if (bFlag)
|
||||
{
|
||||
if (_strnicmp(pszParam,"device:",7)==0)
|
||||
{
|
||||
// Get address set name
|
||||
pszParam += 7;
|
||||
m_strDevName = pszParam;
|
||||
::PathUnquoteSpaces(CStrBuf(m_strDevName,0));
|
||||
}
|
||||
else if (_stricmp(pszParam, "noreset")==0)
|
||||
{
|
||||
m_bNoReset = true;
|
||||
}
|
||||
else if (_stricmp(pszParam, "noguard") == 0)
|
||||
{
|
||||
m_bNoGuard = true;
|
||||
}
|
||||
else if (_stricmp(pszParam, "showdevices") == 0)
|
||||
{
|
||||
m_bShowDevices = true;
|
||||
}
|
||||
else
|
||||
ParseParamFlag(pszParam);
|
||||
}
|
||||
else
|
||||
ParseParamNotFlag(pszParam);
|
||||
|
||||
// Standard implementation
|
||||
ParseLast(bLast);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CPTZControlApp
|
||||
|
||||
BEGIN_MESSAGE_MAP(CPTZControlApp, CWinApp)
|
||||
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CPTZControlApp construction
|
||||
|
||||
CPTZControlApp::CPTZControlApp()
|
||||
: m_bNoReset(false)
|
||||
, m_bNoGuard(false)
|
||||
, m_bShowDevices(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// The one and only CPTZControlApp object
|
||||
|
||||
CPTZControlApp theApp;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CPTZControlApp initialization
|
||||
|
||||
BOOL CPTZControlApp::InitInstance()
|
||||
{
|
||||
CWinApp::InitInstance();
|
||||
|
||||
// Activate "Windows Native" visual manager for enabling themes in MFC controls
|
||||
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
|
||||
|
||||
// Taken from Logitech
|
||||
// PTZDemo\ConferenceCamPTZDemoDlg.cpp
|
||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
//-------------Registry-------------------------------------------------
|
||||
|
||||
SetRegistryKey(_T("MRi-Software"));
|
||||
|
||||
//-------------Commandline parsing--------------------------------------
|
||||
|
||||
// Parse command line for standard shell commands, DDE, file open
|
||||
CPTZControlCommandLineInfo cmdInfo;
|
||||
ParseCommandLine(cmdInfo);
|
||||
|
||||
m_strDevName = cmdInfo.m_strDevName;
|
||||
|
||||
// Registry is overruled command line
|
||||
m_bNoReset = GetProfileInt(REG_OPTIONS,REG_NORESET,FALSE)!=0 || cmdInfo.m_bNoReset;
|
||||
m_bNoGuard = GetProfileInt(REG_OPTIONS,REG_NOGUARD,FALSE)!=0 || cmdInfo.m_bNoGuard;
|
||||
m_bShowDevices = cmdInfo.m_bShowDevices;
|
||||
|
||||
//-------------Main ----------------------------------------------------
|
||||
|
||||
// Create the Dialog
|
||||
m_pDlg = new CPTZControlDlg();
|
||||
if (m_pDlg->Create(CPTZControlDlg::IDD))
|
||||
m_pMainWnd = m_pDlg;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
// Succeeded
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int CPTZControlApp::ExitInstance()
|
||||
{
|
||||
#if !defined(_AFXDLL) && !defined(_AFX_NO_MFC_CONTROLS_IN_DIALOGS)
|
||||
ControlBarCleanUp();
|
||||
#endif
|
||||
|
||||
return __super::ExitInstance();
|
||||
}
|
||||
76
PTZControl/PTZControl.h
Normal file
76
PTZControl/PTZControl.h
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
// PTZControl.h : main header file for the PROJECT_NAME application
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "PTZControlDlg.h"
|
||||
|
||||
#ifndef __AFXWIN_H__
|
||||
#error "include 'pch.h' before including this file for PCH"
|
||||
#endif
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define REG_WINDOW _T("Window")
|
||||
#define REG_WINDOW_POSX _T("X")
|
||||
#define REG_WINDOW_POSY _T("Y")
|
||||
#define REG_TOOLTIP _T("Tooltip%d")
|
||||
|
||||
#define REG_DEVICE _T("Device")
|
||||
#define REG_USELOGOTECHMOTIONCONTROL _T("LogitechMotionControl")
|
||||
#define REG_MOTORINTERVALTIMER _T("MotorIntervalTimer")
|
||||
#define REG_DEVICENAME _T("DeviceName")
|
||||
|
||||
#define REG_OPTIONS _T("Options")
|
||||
#define REG_NORESET _T("NoReset")
|
||||
#define REG_NOGUARD _T("NoGuard")
|
||||
|
||||
#define DEFAULT_DEVICE_NAME_1 _T("PTZ Pro 2")
|
||||
#define DEFAULT_DEVICE_NAME_2 _T("Logi Rally")
|
||||
|
||||
#define TIMER_FOCUS_CHECK 4711
|
||||
#define TIMER_AUTO_REPEAT 4712
|
||||
#define TIMER_CLEAR_MEMORY 4713
|
||||
|
||||
#define FOCUS_CHECK_DELAY 250 // After 250msec we move the focus away from a button.
|
||||
#define AUTO_REPEAT_DELAY 50 // Autorepeat is on the fastest possible delay of 50msec
|
||||
#define AUTO_REPEAT_INITIAL_DELAY 500 // after 1/2 second we start autorepeat
|
||||
#define CLEAR_MEMORY_DELAY 5000 // After 5 seconds clear the memory
|
||||
|
||||
#define COLOR_GREEN RGB(0,240,0)
|
||||
#define COLOR_RED RGB(240,0,0)
|
||||
#define COLOR_ORANGE RGB(255,140,0)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CPTZControlApp:
|
||||
// See PTZControl.cpp for the implementation of this class
|
||||
//
|
||||
|
||||
class CPTZControlApp : public CWinApp
|
||||
{
|
||||
public:
|
||||
CPTZControlApp();
|
||||
|
||||
// Overrides
|
||||
public:
|
||||
virtual BOOL InitInstance();
|
||||
|
||||
// Implementation
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
virtual int ExitInstance();
|
||||
|
||||
public:
|
||||
// command line flags
|
||||
CString m_strDevName; // Device name from the command line to search for
|
||||
bool m_bNoReset; // No Reset of web cam
|
||||
bool m_bNoGuard; // Prevent a guard thread
|
||||
bool m_bShowDevices;
|
||||
|
||||
private:
|
||||
CPTZControlDlg* m_pDlg;
|
||||
};
|
||||
|
||||
extern CPTZControlApp theApp;
|
||||
BIN
PTZControl/PTZControl.rc
Normal file
BIN
PTZControl/PTZControl.rc
Normal file
Binary file not shown.
31
PTZControl/PTZControl.sln
Normal file
31
PTZControl/PTZControl.sln
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30804.86
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PTZControl", "PTZControl.vcxproj", "{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Debug|x64.Build.0 = Debug|x64
|
||||
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Debug|x86.Build.0 = Debug|Win32
|
||||
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Release|x64.ActiveCfg = Release|x64
|
||||
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Release|x64.Build.0 = Release|x64
|
||||
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Release|x86.ActiveCfg = Release|Win32
|
||||
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {750BD145-2459-46BB-A622-E3902280AE01}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
224
PTZControl/PTZControl.vcxproj
Normal file
224
PTZControl/PTZControl.vcxproj
Normal file
@@ -0,0 +1,224 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}</ProjectGuid>
|
||||
<Keyword>MFCProj</Keyword>
|
||||
<RootNamespace>PTZControl</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<Midl>
|
||||
<MkTypLibCompatible>false</MkTypLibCompatible>
|
||||
<ValidateAllParameters>true</ValidateAllParameters>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<Midl>
|
||||
<MkTypLibCompatible>false</MkTypLibCompatible>
|
||||
<ValidateAllParameters>true</ValidateAllParameters>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<Midl>
|
||||
<MkTypLibCompatible>false</MkTypLibCompatible>
|
||||
<ValidateAllParameters>true</ValidateAllParameters>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<Midl>
|
||||
<MkTypLibCompatible>false</MkTypLibCompatible>
|
||||
<ValidateAllParameters>true</ValidateAllParameters>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ExtensionUnit.h" />
|
||||
<ClInclude Include="ExtensionUnitDefines.h" />
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="PTZControl.h" />
|
||||
<ClInclude Include="PTZControlDlg.h" />
|
||||
<ClInclude Include="Resource.h" />
|
||||
<ClInclude Include="SettingsDlg.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ExtensionUnit.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PTZControl.cpp" />
|
||||
<ClCompile Include="PTZControlDlg.cpp" />
|
||||
<ClCompile Include="SettingsDlg.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="PTZControl.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="res\PTZControl.rc2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="res\CameraControl.bmp" />
|
||||
<Image Include="res\PTZControl.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="Readme.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
829
PTZControl/PTZControlDlg.cpp
Normal file
829
PTZControl/PTZControlDlg.cpp
Normal file
@@ -0,0 +1,829 @@
|
||||
|
||||
// PTZControlDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "pch.h"
|
||||
#include "framework.h"
|
||||
#include "PTZControl.h"
|
||||
#include "PTZControlDlg.h"
|
||||
#include "SettingsDlg.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ON_BN_UNPUSHED(id, memberFxn) \
|
||||
ON_CONTROL(BN_UNPUSHED, id, memberFxn)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CPTZButton
|
||||
|
||||
IMPLEMENT_DYNAMIC(CPTZButton,CMFCButton)
|
||||
|
||||
CPTZButton::CPTZButton()
|
||||
: m_bAutoRepeat(false)
|
||||
, m_uiSent(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CPTZButton::PreSubclassWindow()
|
||||
{
|
||||
__super::PreSubclassWindow();
|
||||
SetTooltip(_T(""));
|
||||
// Setting delay time doesn't seam to work.
|
||||
GetToolTipCtrl().SetDelayTime(0);
|
||||
}
|
||||
|
||||
void CPTZButton::OnDrawBorder(CDC* pDC, CRect& rectClient, UINT uiState)
|
||||
{
|
||||
__super::OnDrawBorder(pDC,rectClient,uiState);
|
||||
|
||||
// Give the button our button face. But only when the mouse isn't over
|
||||
if (m_bWinXPTheme && m_clrFace!=COLORREF(-1)/* && !m_bHover && !m_bHighlighted*/)
|
||||
pDC->FillSolidRect(rectClient, m_clrFace);
|
||||
}
|
||||
|
||||
void CPTZButton::OnDrawFocusRect(CDC* pDC, const CRect& rectClient)
|
||||
{
|
||||
UNUSED_ALWAYS(pDC); UNUSED_ALWAYS(rectClient);
|
||||
}
|
||||
|
||||
void CPTZButton::OnLButtonDown(UINT nFlags, CPoint point)
|
||||
{
|
||||
if (m_bAutoRepeat)
|
||||
{
|
||||
SetTimer(TIMER_AUTO_REPEAT, AUTO_REPEAT_INITIAL_DELAY, NULL);
|
||||
m_uiSent = 0;
|
||||
}
|
||||
__super::OnLButtonDown(nFlags, point);
|
||||
}
|
||||
|
||||
void CPTZButton::OnLButtonUp(UINT nFlags, CPoint point)
|
||||
{
|
||||
if (m_bAutoRepeat)
|
||||
{
|
||||
KillTimer(TIMER_AUTO_REPEAT);
|
||||
|
||||
if (GetCapture() != NULL)
|
||||
{
|
||||
// If we never sent a message we do it once.
|
||||
if (m_uiSent==0 && (GetState() & BST_PUSHED) != 0)
|
||||
GetParent()->SendMessage(WM_COMMAND, MAKELONG(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
|
||||
else
|
||||
GetParent()->SendMessage(WM_COMMAND, MAKELONG(GetDlgCtrlID(), BN_UNPUSHED), (LPARAM)m_hWnd);
|
||||
// release capture
|
||||
ReleaseCapture();
|
||||
}
|
||||
}
|
||||
else
|
||||
// Never call the default in auto repeat
|
||||
__super::OnLButtonUp(nFlags, point);
|
||||
}
|
||||
|
||||
void CPTZButton::OnTimer(UINT_PTR nIDEvent)
|
||||
{
|
||||
if (nIDEvent==TIMER_AUTO_REPEAT)
|
||||
{
|
||||
if (m_bAutoRepeat)
|
||||
{
|
||||
if ((GetState() & BST_PUSHED) == 0)
|
||||
return;
|
||||
++m_uiSent;
|
||||
SetTimer(TIMER_AUTO_REPEAT, AUTO_REPEAT_DELAY, NULL);
|
||||
GetParent()->SendMessage(WM_COMMAND, MAKELONG(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
|
||||
}
|
||||
}
|
||||
|
||||
__super::OnTimer(nIDEvent);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL AdjustVisibleWindowRect(LPRECT lpRect, HWND hWndParent=NULL)
|
||||
{
|
||||
RECT rcOrg(*lpRect);
|
||||
|
||||
RECT rcBase;
|
||||
if (hWndParent)
|
||||
// Any parent given?
|
||||
::GetClientRect(hWndParent,&rcBase);
|
||||
else
|
||||
{
|
||||
::MONITORINFO mi;
|
||||
mi.cbSize = sizeof(mi);
|
||||
if (!AfxGetMainWnd())
|
||||
// If we have no main window we just try to use the main screen point 0,0
|
||||
::GetMonitorInfo(::MonitorFromPoint(CPoint(0,0), MONITOR_DEFAULTTONEAREST), &mi);
|
||||
else
|
||||
// Get the main window monitor
|
||||
::GetMonitorInfo(::MonitorFromWindow(AfxGetMainWnd()->m_hWnd, MONITOR_DEFAULTTONEAREST), &mi);
|
||||
rcBase = mi.rcWork;
|
||||
}
|
||||
|
||||
// To large?
|
||||
if (lpRect->bottom-lpRect->top>rcBase.bottom-rcBase.top)
|
||||
lpRect->bottom -= (lpRect->bottom-lpRect->top)-(rcBase.bottom-rcBase.top);
|
||||
if (lpRect->right-lpRect->left>rcBase.right-rcBase.left)
|
||||
lpRect->right -= (lpRect->right-lpRect->left)-(rcBase.right-rcBase.left);
|
||||
|
||||
// Check if rect is visible
|
||||
if (lpRect->bottom>rcBase.bottom)
|
||||
::OffsetRect(lpRect,0,rcBase.bottom-lpRect->bottom);
|
||||
if (lpRect->top<rcBase.top)
|
||||
::OffsetRect(lpRect,0,rcBase.top-lpRect->top);
|
||||
if (lpRect->right>rcBase.right)
|
||||
::OffsetRect(lpRect,rcBase.right-lpRect->right,0);
|
||||
if (lpRect->left<rcBase.left)
|
||||
::OffsetRect(lpRect,rcBase.left-lpRect->left,0);
|
||||
|
||||
// Check if coords changes
|
||||
return !EqualRect(lpRect,&rcOrg);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CPTZControlDlg dialog
|
||||
|
||||
CPTZControlDlg::CPTZControlDlg(CWnd* pParent /*=nullptr*/)
|
||||
: CDialogEx(IDD_PTZCONTROL_DIALOG, pParent)
|
||||
, m_hAccel(NULL)
|
||||
, m_iCurrentWebCam(0)
|
||||
, m_iNumWebCams(0)
|
||||
, m_evTerminating(FALSE,TRUE)
|
||||
, m_pGuardThread(nullptr)
|
||||
{
|
||||
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
||||
m_hAccel = ::LoadAccelerators(AfxFindResourceHandle(IDR_ACCELERATOR, RT_ACCELERATOR), MAKEINTRESOURCE(IDR_ACCELERATOR));
|
||||
}
|
||||
|
||||
CPTZControlDlg::~CPTZControlDlg()
|
||||
{
|
||||
for (auto &webcam : m_aWebCams)
|
||||
webcam.CloseDevice();
|
||||
}
|
||||
|
||||
void CPTZControlDlg::PostNcDestroy()
|
||||
{
|
||||
__super::PostNcDestroy();
|
||||
|
||||
// Cleanup the guard thread.
|
||||
m_evTerminating.SetEvent();
|
||||
if (m_pGuardThread)
|
||||
::WaitForSingleObject(m_pGuardThread->m_hThread,INFINITE);
|
||||
m_pGuardThread = nullptr;
|
||||
|
||||
// Finally delete the application.
|
||||
delete this;
|
||||
}
|
||||
|
||||
BOOL CPTZControlDlg::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return __super::OnCommand(wParam,lParam);
|
||||
}
|
||||
|
||||
|
||||
BOOL CPTZControlDlg::PreTranslateMessage(MSG* pMsg)
|
||||
{
|
||||
if (pMsg->message>=WM_KEYFIRST && pMsg->message<=WM_KEYLAST)
|
||||
{
|
||||
if (m_hAccel)
|
||||
{
|
||||
if (::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return __super::PreTranslateMessage(pMsg);
|
||||
}
|
||||
|
||||
void CPTZControlDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
__super::DoDataExchange(pDX);
|
||||
DDX_Control(pDX, IDC_BT_ZOOM_IN, m_btZoomIn);
|
||||
DDX_Control(pDX, IDC_BT_ZOOM_OUT, m_btZoomOut);
|
||||
DDX_Control(pDX, IDC_BT_UP, m_btUp);
|
||||
DDX_Control(pDX, IDC_BT_DOWN, m_btDown);
|
||||
DDX_Control(pDX, IDC_BT_HOME, m_btHome);
|
||||
DDX_Control(pDX, IDC_BT_LEFT, m_btLeft);
|
||||
DDX_Control(pDX, IDC_BT_RIGHT, m_btRight);
|
||||
DDX_Control(pDX, IDC_BT_MEMORY, m_btMemory);
|
||||
DDX_Control(pDX, IDC_BT_PRESET1, m_btPreset[0]);
|
||||
DDX_Control(pDX, IDC_BT_PRESET2, m_btPreset[1]);
|
||||
DDX_Control(pDX, IDC_BT_PRESET3, m_btPreset[2]);
|
||||
DDX_Control(pDX, IDC_BT_PRESET4, m_btPreset[3]);
|
||||
DDX_Control(pDX, IDC_BT_PRESET5, m_btPreset[4]);
|
||||
DDX_Control(pDX, IDC_BT_PRESET6, m_btPreset[5]);
|
||||
DDX_Control(pDX, IDC_BT_PRESET7, m_btPreset[6]);
|
||||
DDX_Control(pDX, IDC_BT_PRESET8, m_btPreset[7]);
|
||||
DDX_Control(pDX, IDC_BT_EXIT, m_btExit);
|
||||
DDX_Control(pDX, IDC_BT_SETTINGS, m_btSettings);
|
||||
DDX_Control(pDX, IDC_BT_WEBCAM1, m_btWebCam[0]);
|
||||
DDX_Control(pDX, IDC_BT_WEBCAM2, m_btWebCam[1]);
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CPTZControlDlg, CDialogEx)
|
||||
ON_WM_PAINT()
|
||||
ON_WM_QUERYDRAGICON()
|
||||
ON_WM_CLOSE()
|
||||
ON_WM_NCHITTEST()
|
||||
ON_BN_CLICKED(IDC_BT_EXIT, &CPTZControlDlg::OnBtExit)
|
||||
ON_WM_SETFOCUS()
|
||||
ON_BN_CLICKED(IDC_BT_MEMORY, &CPTZControlDlg::OnBtMemory)
|
||||
ON_COMMAND_EX(IDC_BT_WEBCAM1, &CPTZControlDlg::OnBtWebCam)
|
||||
ON_COMMAND_EX(IDC_BT_WEBCAM2, &CPTZControlDlg::OnBtWebCam)
|
||||
ON_COMMAND_EX(IDC_BT_PRESET1, &CPTZControlDlg::OnBtPreset)
|
||||
ON_COMMAND_EX(IDC_BT_PRESET2, &CPTZControlDlg::OnBtPreset)
|
||||
ON_COMMAND_EX(IDC_BT_PRESET3, &CPTZControlDlg::OnBtPreset)
|
||||
ON_COMMAND_EX(IDC_BT_PRESET4, &CPTZControlDlg::OnBtPreset)
|
||||
ON_COMMAND_EX(IDC_BT_PRESET5, &CPTZControlDlg::OnBtPreset)
|
||||
ON_COMMAND_EX(IDC_BT_PRESET6, &CPTZControlDlg::OnBtPreset)
|
||||
ON_COMMAND_EX(IDC_BT_PRESET7, &CPTZControlDlg::OnBtPreset)
|
||||
ON_COMMAND_EX(IDC_BT_PRESET8, &CPTZControlDlg::OnBtPreset)
|
||||
ON_BN_CLICKED(IDC_BT_ZOOM_IN, &CPTZControlDlg::OnBtZoomIn)
|
||||
ON_BN_CLICKED(IDC_BT_ZOOM_OUT, &CPTZControlDlg::OnBtZoomOut)
|
||||
ON_BN_CLICKED(IDC_BT_UP, &CPTZControlDlg::OnBtUp)
|
||||
ON_BN_CLICKED(IDC_BT_DOWN, &CPTZControlDlg::OnBtDown)
|
||||
ON_BN_CLICKED(IDC_BT_LEFT, &CPTZControlDlg::OnBtLeft)
|
||||
ON_BN_CLICKED(IDC_BT_HOME, &CPTZControlDlg::OnBtHome)
|
||||
ON_BN_CLICKED(IDC_BT_RIGHT, &CPTZControlDlg::OnBtRight)
|
||||
ON_BN_CLICKED(IDC_BT_SETTINGS, &CPTZControlDlg::OnBtSettings)
|
||||
ON_BN_UNPUSHED(IDC_BT_UP, &CPTZControlDlg::OnBtUnpushed)
|
||||
ON_BN_UNPUSHED(IDC_BT_DOWN, &CPTZControlDlg::OnBtUnpushed)
|
||||
ON_BN_UNPUSHED(IDC_BT_LEFT, &CPTZControlDlg::OnBtUnpushed)
|
||||
ON_BN_UNPUSHED(IDC_BT_RIGHT, &CPTZControlDlg::OnBtUnpushed)
|
||||
ON_WM_TIMER()
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CPTZControlDlg message handlers
|
||||
|
||||
void CPTZControlDlg::ResetAllColors()
|
||||
{
|
||||
for (CWnd* pWnd = GetWindow(GW_CHILD); pWnd; pWnd = pWnd->GetWindow(GW_HWNDNEXT))
|
||||
{
|
||||
auto *pButton = DYNAMIC_DOWNCAST(CPTZButton, pWnd);
|
||||
|
||||
// Don't reset color for web cam button
|
||||
bool bIsWebCamBtn = false;
|
||||
for (auto &btn : m_btWebCam)
|
||||
bIsWebCamBtn |= pButton==&btn;
|
||||
|
||||
// Reset color for all other buttons
|
||||
if (pButton && !bIsWebCamBtn)
|
||||
pButton->SetFaceColor(COLORREF(-1), TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void CPTZControlDlg::ResetMemButton()
|
||||
{
|
||||
// Clear the mem button
|
||||
KillTimer(TIMER_CLEAR_MEMORY);
|
||||
m_btMemory.SetCheck(0);
|
||||
m_btMemory.SetFaceColor(COLORREF(-1));
|
||||
}
|
||||
|
||||
CWebcamController& CPTZControlDlg::GetCurrentWebCam()
|
||||
{
|
||||
return m_aWebCams[m_iCurrentWebCam];
|
||||
}
|
||||
|
||||
void CPTZControlDlg::SetActiveCam(int iCam)
|
||||
{
|
||||
if (iCam >= 0 && iCam < m_iNumWebCams)
|
||||
{
|
||||
// Clear mem button
|
||||
ResetMemButton();
|
||||
|
||||
// Save the colors of the current buttons and set the old ones
|
||||
for (CWnd* pWnd = GetWindow(GW_CHILD); pWnd; pWnd = pWnd->GetWindow(GW_HWNDNEXT))
|
||||
{
|
||||
auto* pButton = DYNAMIC_DOWNCAST(CPTZButton, pWnd);
|
||||
if (pButton)
|
||||
{
|
||||
// Save the color of the current buttons for the current web cam and get
|
||||
// the saved color from the map we have for the new cam.
|
||||
auto nId = pButton->GetDlgCtrlID();
|
||||
m_aMapBtnColors[m_iCurrentWebCam][nId] = pButton->GetFaceColor();
|
||||
auto it = m_aMapBtnColors[iCam].find(nId);
|
||||
if (it!=m_aMapBtnColors[iCam].end())
|
||||
pButton->SetFaceColor(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the tooltips
|
||||
for (int i=0; i<CWebcamController::NUM_PRESETS; ++i)
|
||||
m_btPreset[i].SetTooltip(m_strTooltips[iCam][i]);
|
||||
|
||||
// Set the new webcam
|
||||
m_iCurrentWebCam = iCam;
|
||||
auto Enable = [&](CPTZButton &btn, bool bActive)
|
||||
{
|
||||
btn.SetCheck(bActive);
|
||||
btn.SetFaceColor(bActive ? COLOR_ORANGE : -1, TRUE);
|
||||
};
|
||||
int iWebCam = 0;
|
||||
for (auto &btn : m_btWebCam)
|
||||
Enable(btn,m_iCurrentWebCam==iWebCam++);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// It seams that in some cases a camera my block.
|
||||
// This thread should help that the blocking thread is detected. and the
|
||||
// application terminates.
|
||||
|
||||
UINT AFX_CDECL CPTZControlDlg::GuardThread(LPVOID p)
|
||||
{
|
||||
auto *pWnd = static_cast<CPTZControlDlg*>(p);
|
||||
|
||||
// This thread end when the application exists.
|
||||
// For ever all 2000 seconds check if the application still runs and accepts messages.
|
||||
for (;;)
|
||||
{
|
||||
// Check if we have an event, wait for 1 sec
|
||||
CSingleLock lock(&pWnd->m_evTerminating,FALSE);
|
||||
if (lock.Lock(1000))
|
||||
// Event is set.
|
||||
return 0;
|
||||
|
||||
DWORD dwResult = 0;
|
||||
// Check if the application is blocking
|
||||
if (::SendMessageTimeout(pWnd->GetSafeHwnd(), WM_NULL, 0, 0, SMTO_ABORTIFHUNG | SMTO_NORMAL, 1000, &dwResult)==0)
|
||||
{
|
||||
// Exit the current process
|
||||
::ExitProcess(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CPTZControlDlg::OnInitDialog()
|
||||
{
|
||||
__super::OnInitDialog();
|
||||
|
||||
// Set the icon for this dialog. The framework does this automatically
|
||||
// when the application's main window is not a dialog
|
||||
SetIcon(m_hIcon, TRUE); // Set big icon
|
||||
SetIcon(m_hIcon, FALSE); // Set small icon
|
||||
|
||||
// Load the bitmap
|
||||
{
|
||||
CMFCToolBarImages images;
|
||||
images.SetImageSize(CSize(16, 16));
|
||||
images.Load(IDB_BUTTONS);
|
||||
|
||||
int iImage = 0;
|
||||
CPTZButton* apButtons[] =
|
||||
{
|
||||
&m_btDown,
|
||||
&m_btLeft,
|
||||
&m_btRight,
|
||||
&m_btUp,
|
||||
&m_btHome,
|
||||
&m_btZoomIn,
|
||||
&m_btZoomOut,
|
||||
&m_btMemory,
|
||||
&m_btPreset[0],
|
||||
&m_btPreset[1],
|
||||
&m_btPreset[2],
|
||||
&m_btPreset[3],
|
||||
&m_btPreset[4],
|
||||
&m_btPreset[5],
|
||||
&m_btPreset[6],
|
||||
&m_btPreset[7],
|
||||
&m_btExit,
|
||||
&m_btSettings,
|
||||
&m_btWebCam[0],
|
||||
&m_btWebCam[1],
|
||||
};
|
||||
for (auto* pBtn : apButtons)
|
||||
{
|
||||
HICON hIcon = images.ExtractIcon(iImage++);
|
||||
pBtn->SetImage(hIcon);
|
||||
// we have a graphic now, we skip the text
|
||||
pBtn->SetWindowText(_T(""));
|
||||
}
|
||||
}
|
||||
|
||||
// Set auto repeat buttons
|
||||
m_btLeft.SetAutoRepeat(true);
|
||||
m_btRight.SetAutoRepeat(true);
|
||||
m_btDown.SetAutoRepeat(true);
|
||||
m_btUp.SetAutoRepeat(true);
|
||||
m_btZoomIn.SetAutoRepeat(true);
|
||||
m_btZoomOut.SetAutoRepeat(true);
|
||||
|
||||
// This is a check box style
|
||||
m_btMemory.SetCheckStyle();
|
||||
for (auto &btn : m_btWebCam)
|
||||
btn.SetCheckStyle();
|
||||
|
||||
// First Center
|
||||
CenterWindow();
|
||||
|
||||
// Adjust the window
|
||||
CRect rect;
|
||||
GetWindowRect(rect);
|
||||
CPoint pt = rect.TopLeft();
|
||||
rect.OffsetRect(-pt);
|
||||
pt.x = theApp.GetProfileInt(REG_WINDOW,REG_WINDOW_POSX,pt.x);
|
||||
pt.y = theApp.GetProfileInt(REG_WINDOW,REG_WINDOW_POSY,pt.y);
|
||||
rect.OffsetRect(pt);
|
||||
AdjustVisibleWindowRect(rect);
|
||||
|
||||
// Move it
|
||||
SetWindowPos(&CWnd::wndTopMost, rect.left, rect.top, 0, 0, SWP_NOSIZE);
|
||||
|
||||
// Try to find the Device list
|
||||
CStringArray aDevices;
|
||||
CWebcamController::ListDevices(aDevices);
|
||||
|
||||
auto OpenWebCam = [](CWebcamController& webCam, CString strDevToken)->bool
|
||||
{
|
||||
HRESULT hr = webCam.OpenDevice(CComBSTR(strDevToken), 0, 0);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
AfxMessageBox(IDP_ERR_OPENFAILED);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load the default setting
|
||||
webCam.UseLogitechMotionControl(theApp.GetProfileInt(REG_DEVICE, REG_USELOGOTECHMOTIONCONTROL, FALSE) != 0);
|
||||
webCam.SetMotorIntervalTimer(theApp.GetProfileInt(REG_DEVICE, REG_MOTORINTERVALTIMER, DEFAULT_MOTOR_INTERVAL_TIMER));
|
||||
return true;
|
||||
};
|
||||
|
||||
// Find the devices to search for. We have some default devices if no other is set in
|
||||
// the registry o on the command line.
|
||||
CStringArray aStrCameraNameToSearch;
|
||||
aStrCameraNameToSearch.Add(DEFAULT_DEVICE_NAME_1);
|
||||
aStrCameraNameToSearch.Add(DEFAULT_DEVICE_NAME_2);
|
||||
CString strCameraNameToSearch = theApp.GetProfileString(REG_DEVICE,REG_DEVICENAME,_T(""));
|
||||
if (!strCameraNameToSearch.IsEmpty())
|
||||
aStrCameraNameToSearch.Add(strCameraNameToSearch);
|
||||
if (!theApp.m_strDevName.IsEmpty())
|
||||
aStrCameraNameToSearch.Add(theApp.m_strDevName);
|
||||
|
||||
// Search for the PTZ PRO 2
|
||||
CString strDevToken, strCameras;
|
||||
for (int i = 0; i<aDevices.GetCount() && m_iNumWebCams<NUM_MAX_WEBCAMS; ++i)
|
||||
{
|
||||
CString strDevice = aDevices[i], strCameraName, strCameraDevice;
|
||||
int iPos = strDevice.Find(_T('\t'));
|
||||
if (iPos != -1)
|
||||
{
|
||||
// Get name and device token
|
||||
strCameraName = strDevice.Left(iPos);
|
||||
strDevToken = strDevice.Mid(iPos + 1);
|
||||
|
||||
// Build list of names found
|
||||
if (!strCameras.IsEmpty())
|
||||
strCameras += _T("\r\n");
|
||||
strCameras += strCameraName;
|
||||
|
||||
// Check if the name matches
|
||||
for (int j=0; j<aStrCameraNameToSearch.GetCount(); ++j)
|
||||
{
|
||||
// Check if we have a asterisk. Or a partial name match.
|
||||
if (aStrCameraNameToSearch[j]==_T("*") || strCameraName.Find(aStrCameraNameToSearch[j]) != -1)
|
||||
{
|
||||
if (OpenWebCam(m_aWebCams[m_iNumWebCams], strDevToken))
|
||||
++m_iNumWebCams;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// On SHIFT and CTRL key down we show all found camera device names.
|
||||
if (theApp.m_bShowDevices || (::GetAsyncKeyState(VK_SHIFT) & 0x8000) && (::GetAsyncKeyState(VK_CONTROL) & 0x8000))
|
||||
{
|
||||
CString strMsg(MAKEINTRESOURCE(IDP_TXT_CAMERAS)), strText;
|
||||
strText.FormatMessage(strMsg, strCameras.GetString());
|
||||
AfxMessageBox(strText);
|
||||
}
|
||||
|
||||
// Check how many web cams we found
|
||||
if (m_iNumWebCams==0)
|
||||
{
|
||||
// If we have no cam, show message
|
||||
AfxMessageBox(IDP_ERR_NO_CAMERA, MB_ICONERROR);
|
||||
}
|
||||
|
||||
// Only 1 or none, we don't need the camera selection buttons
|
||||
if (m_iNumWebCams<=1)
|
||||
{
|
||||
// Sow the web cam buttons only if we have 2 cams
|
||||
for (auto &btn : m_btWebCam)
|
||||
btn.ShowWindow(SW_HIDE);
|
||||
}
|
||||
|
||||
for (int i = 0; i < CWebcamController::NUM_PRESETS; ++i)
|
||||
{
|
||||
for (int j = 0; j < CPTZControlDlg::NUM_MAX_WEBCAMS; ++j)
|
||||
{
|
||||
CString str;
|
||||
str.Format(REG_TOOLTIP, i + 1 + j*100);
|
||||
m_strTooltips[j][i] = theApp.GetProfileString(REG_WINDOW, str);
|
||||
}
|
||||
}
|
||||
|
||||
EnableToolTips(TRUE);
|
||||
|
||||
// Start a guard thread that takes care about a blocking app.
|
||||
if (!theApp.m_bNoGuard)
|
||||
m_pGuardThread = AfxBeginThread(&GuardThread,this);
|
||||
|
||||
// Set a time to move the focus to the parent window
|
||||
SetTimer(TIMER_FOCUS_CHECK,FOCUS_CHECK_DELAY,nullptr);
|
||||
SetFocus();
|
||||
|
||||
// Move all cams to home position. And WebCam 0 will be the active one.
|
||||
if (theApp.m_bNoReset)
|
||||
{
|
||||
// Activate camera 0.
|
||||
if (m_iNumWebCams>0)
|
||||
SetActiveCam(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset the cameras to home position. and leave the first camera
|
||||
// (index 0) the active one ((loop backwards).
|
||||
for (int i = m_iNumWebCams; i > 0; --i)
|
||||
{
|
||||
SetActiveCam(i - 1);
|
||||
OnBtHome();
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// If you add a minimize button to your dialog, you will need the code below
|
||||
// to draw the icon. For MFC applications using the document/view model,
|
||||
// this is automatically done for you by the framework.
|
||||
|
||||
void CPTZControlDlg::OnPaint()
|
||||
{
|
||||
if (IsIconic())
|
||||
{
|
||||
CPaintDC dc(this); // device context for painting
|
||||
|
||||
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
|
||||
|
||||
// Center icon in client rectangle
|
||||
int cxIcon = GetSystemMetrics(SM_CXICON);
|
||||
int cyIcon = GetSystemMetrics(SM_CYICON);
|
||||
CRect rect;
|
||||
GetClientRect(&rect);
|
||||
int x = (rect.Width() - cxIcon + 1) / 2;
|
||||
int y = (rect.Height() - cyIcon + 1) / 2;
|
||||
|
||||
// Draw the icon
|
||||
dc.DrawIcon(x, y, m_hIcon);
|
||||
}
|
||||
else
|
||||
{
|
||||
__super::OnPaint();
|
||||
}
|
||||
}
|
||||
|
||||
// The system calls this function to obtain the cursor to display while the user drags
|
||||
// the minimized window.
|
||||
HCURSOR CPTZControlDlg::OnQueryDragIcon()
|
||||
{
|
||||
return static_cast<HCURSOR>(m_hIcon);
|
||||
}
|
||||
|
||||
LRESULT CPTZControlDlg::OnNcHitTest(CPoint point)
|
||||
{
|
||||
// Allow drag & drop
|
||||
LRESULT lResult = __super::OnNcHitTest(point);
|
||||
if (lResult == HTCLIENT)
|
||||
lResult = HTCAPTION;
|
||||
return lResult;
|
||||
}
|
||||
|
||||
void CPTZControlDlg::OnClose()
|
||||
{
|
||||
CRect rect;
|
||||
GetWindowRect(rect);
|
||||
theApp.WriteProfileInt(REG_WINDOW,REG_WINDOW_POSX,rect.left);
|
||||
theApp.WriteProfileInt(REG_WINDOW,REG_WINDOW_POSY,rect.top);
|
||||
|
||||
DestroyWindow();
|
||||
}
|
||||
|
||||
void CPTZControlDlg::OnBtExit()
|
||||
{
|
||||
PostMessage(WM_CLOSE);
|
||||
}
|
||||
|
||||
|
||||
void CPTZControlDlg::OnOK()
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
|
||||
|
||||
void CPTZControlDlg::OnCancel()
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CPTZControlDlg::OnBtMemory()
|
||||
{
|
||||
ResetAllColors();
|
||||
bool bCheck = !m_btMemory.GetCheck();
|
||||
m_btMemory.SetCheck(bCheck);
|
||||
if (bCheck)
|
||||
{
|
||||
// Remember the mem button, but clear it after some delay.
|
||||
m_btMemory.SetFaceColor(COLOR_RED, TRUE);
|
||||
SetTimer(TIMER_CLEAR_MEMORY,CLEAR_MEMORY_DELAY,nullptr);
|
||||
}
|
||||
else
|
||||
m_btMemory.SetFaceColor(COLORREF(-1),TRUE);
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CPTZButton, CMFCButton)
|
||||
ON_WM_LBUTTONDOWN()
|
||||
ON_WM_TIMER()
|
||||
ON_WM_LBUTTONUP()
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
BOOL CPTZControlDlg::OnBtPreset(UINT nId)
|
||||
{
|
||||
UINT uiPreset = 0;
|
||||
while (uiPreset<CWebcamController::NUM_PRESETS)
|
||||
{
|
||||
if (static_cast<UINT>(m_btPreset[uiPreset].GetDlgCtrlID())==nId)
|
||||
break;
|
||||
++uiPreset;
|
||||
}
|
||||
|
||||
if (uiPreset<CWebcamController::NUM_PRESETS)
|
||||
{
|
||||
ResetAllColors();
|
||||
bool bStore = m_btMemory.GetCheck();
|
||||
if (bStore)
|
||||
{
|
||||
// Save as new preset
|
||||
GetCurrentWebCam().SavePreset(uiPreset);
|
||||
ResetMemButton();
|
||||
}
|
||||
else
|
||||
GetCurrentWebCam().GotoPreset(uiPreset);
|
||||
|
||||
// Set color
|
||||
STATIC_DOWNCAST(CPTZButton,GetDlgItem(nId))->SetFaceColor(COLOR_GREEN,TRUE);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CPTZControlDlg::OnBtWebCam(UINT nId)
|
||||
{
|
||||
SetActiveCam(nId==IDC_BT_WEBCAM1 ? 0 : 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CPTZControlDlg::OnBtHome()
|
||||
{
|
||||
ResetAllColors();
|
||||
GetCurrentWebCam().GotoHome();
|
||||
m_btHome.SetFaceColor(COLOR_GREEN,TRUE);
|
||||
}
|
||||
|
||||
|
||||
void CPTZControlDlg::OnBtZoomIn()
|
||||
{
|
||||
ResetAllColors();
|
||||
GetCurrentWebCam().Zoom(1);
|
||||
}
|
||||
|
||||
|
||||
void CPTZControlDlg::OnBtZoomOut()
|
||||
{
|
||||
ResetAllColors();
|
||||
GetCurrentWebCam().Zoom(-1);
|
||||
}
|
||||
|
||||
|
||||
void CPTZControlDlg::OnBtDown()
|
||||
{
|
||||
ResetAllColors();
|
||||
if (m_btDown.InAutoRepeat())
|
||||
GetCurrentWebCam().Tilt(-1);
|
||||
else
|
||||
GetCurrentWebCam().MoveTilt(-1);
|
||||
}
|
||||
|
||||
void CPTZControlDlg::OnBtUp()
|
||||
{
|
||||
ResetAllColors();
|
||||
if (m_btUp.InAutoRepeat())
|
||||
GetCurrentWebCam().Tilt(1);
|
||||
else
|
||||
GetCurrentWebCam().MoveTilt(1);
|
||||
}
|
||||
|
||||
|
||||
void CPTZControlDlg::OnBtLeft()
|
||||
{
|
||||
ResetAllColors();
|
||||
if (m_btLeft.InAutoRepeat())
|
||||
GetCurrentWebCam().Pan(-1);
|
||||
else
|
||||
GetCurrentWebCam().MovePan(-1);
|
||||
}
|
||||
|
||||
|
||||
void CPTZControlDlg::OnBtRight()
|
||||
{
|
||||
ResetAllColors();
|
||||
if (m_btRight.InAutoRepeat())
|
||||
GetCurrentWebCam().Pan(1);
|
||||
else
|
||||
GetCurrentWebCam().MovePan(1);
|
||||
}
|
||||
|
||||
|
||||
void CPTZControlDlg::OnSetFocus(CWnd* pOldWnd)
|
||||
{
|
||||
// Do nothing. Never set the focus to a child.
|
||||
UNUSED_ALWAYS(pOldWnd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CPTZControlDlg::OnTimer(UINT_PTR nIDEvent)
|
||||
{
|
||||
if (nIDEvent == TIMER_FOCUS_CHECK)
|
||||
{
|
||||
CWnd* pWndFocus = GetFocus();
|
||||
if (pWndFocus &&
|
||||
pWndFocus->GetParent()==this &&
|
||||
(GetAsyncKeyState(VK_LBUTTON) & 0x8000)==0)
|
||||
// only move the focus, when a button has the focus and the mouse is not down.
|
||||
SetFocus();
|
||||
}
|
||||
else if (nIDEvent == TIMER_CLEAR_MEMORY)
|
||||
{
|
||||
// Clear the mem button after some delay
|
||||
ResetMemButton();
|
||||
}
|
||||
|
||||
__super::OnTimer(nIDEvent);
|
||||
}
|
||||
|
||||
void CPTZControlDlg::OnBtUnpushed()
|
||||
{
|
||||
GetCurrentWebCam().Pan(0);
|
||||
GetCurrentWebCam().Tilt(0);
|
||||
}
|
||||
|
||||
void CPTZControlDlg::OnBtSettings()
|
||||
{
|
||||
CSettingsDlg dlg;
|
||||
dlg.m_strCameraName = m_strCameraDeviceName;
|
||||
dlg.m_bLogitechCameraControl = GetCurrentWebCam().UseLogitechMotionControl();
|
||||
dlg.m_iMotorIntervalTimer = GetCurrentWebCam().GetMotorIntervalTimer();
|
||||
|
||||
// Get a copy of the tooltips
|
||||
for (int i = 0; i < CWebcamController::NUM_PRESETS; ++i)
|
||||
{
|
||||
for (int j = 0; j < CPTZControlDlg::NUM_MAX_WEBCAMS; ++j)
|
||||
{
|
||||
dlg.m_strTooltip[j][i] = m_strTooltips[j][i];
|
||||
}
|
||||
}
|
||||
|
||||
if (dlg.DoModal()!=IDOK)
|
||||
return;
|
||||
|
||||
// Copy back and save
|
||||
for (int i = 0; i < CWebcamController::NUM_PRESETS; ++i)
|
||||
{
|
||||
for (int j = 0; j < CPTZControlDlg::NUM_MAX_WEBCAMS; ++j)
|
||||
{
|
||||
m_strTooltips[j][i] = dlg.m_strTooltip[j][i];
|
||||
CString str;
|
||||
str.Format(REG_TOOLTIP, i + 1 + j*100);
|
||||
theApp.WriteProfileString(REG_WINDOW, str, m_strTooltips[j][i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Camera control
|
||||
GetCurrentWebCam().UseLogitechMotionControl(dlg.m_bLogitechCameraControl!=0);
|
||||
theApp.WriteProfileInt(REG_DEVICE, REG_USELOGOTECHMOTIONCONTROL, dlg.m_bLogitechCameraControl);
|
||||
GetCurrentWebCam().SetMotorIntervalTimer(dlg.m_iMotorIntervalTimer);
|
||||
theApp.WriteProfileInt(REG_DEVICE, REG_USELOGOTECHMOTIONCONTROL, dlg.m_bLogitechCameraControl);
|
||||
|
||||
// Set tooltips again
|
||||
SetActiveCam(m_iCurrentWebCam);
|
||||
}
|
||||
|
||||
151
PTZControl/PTZControlDlg.h
Normal file
151
PTZControl/PTZControlDlg.h
Normal file
@@ -0,0 +1,151 @@
|
||||
|
||||
// PTZControlDlg.h : header file
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "resource.h"
|
||||
#include "ExtensionUnit.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CPTZButton
|
||||
|
||||
class CPTZButton : public CMFCButton
|
||||
{
|
||||
DECLARE_DYNAMIC(CPTZButton)
|
||||
public:
|
||||
CPTZButton();
|
||||
void SetCheckStyle()
|
||||
{
|
||||
m_bCheckButton = TRUE;
|
||||
m_bAutoCheck = FALSE;
|
||||
}
|
||||
|
||||
void SetAutoRepeat(bool bVal)
|
||||
{
|
||||
m_bAutoRepeat = bVal;
|
||||
}
|
||||
bool InAutoRepeat()
|
||||
{
|
||||
return m_uiSent!=0;
|
||||
}
|
||||
COLORREF GetFaceColor()
|
||||
{
|
||||
return m_clrFace;
|
||||
}
|
||||
|
||||
void SetTooltip(LPCTSTR lpszToolTipText)
|
||||
{
|
||||
// We keep an internal copy of the tooltip
|
||||
m_strTooltip = lpszToolTipText;
|
||||
__super::SetTooltip(lpszToolTipText);
|
||||
}
|
||||
CString GetTooltip()
|
||||
{
|
||||
return m_strTooltip;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Data
|
||||
bool m_bAutoRepeat;
|
||||
UINT m_uiSent;
|
||||
CString m_strTooltip;
|
||||
|
||||
protected:
|
||||
void PreSubclassWindow() override;
|
||||
void OnDrawBorder(CDC* pDC, CRect& rectClient, UINT uiState) override;
|
||||
void OnDrawFocusRect(CDC* pDC, const CRect& rectClient) override;
|
||||
|
||||
public:
|
||||
DECLARE_MESSAGE_MAP()
|
||||
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
|
||||
afx_msg void OnTimer(UINT_PTR nIDEvent);
|
||||
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CPTZControlDlg dialog
|
||||
|
||||
class CPTZControlDlg : public CDialogEx
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CPTZControlDlg(CWnd* pParent = nullptr); // standard constructor
|
||||
~CPTZControlDlg();
|
||||
// Dialog Data
|
||||
enum { IDD = IDD_PTZCONTROL_DIALOG };
|
||||
static const int NUM_MAX_WEBCAMS = 2;
|
||||
|
||||
protected:
|
||||
CPTZButton m_btZoomIn;
|
||||
CPTZButton m_btZoomOut;
|
||||
CPTZButton m_btUp;
|
||||
CPTZButton m_btDown;
|
||||
CPTZButton m_btHome;
|
||||
CPTZButton m_btLeft;
|
||||
CPTZButton m_btRight;
|
||||
CPTZButton m_btMemory;
|
||||
CPTZButton m_btPreset[CWebcamController::NUM_PRESETS];
|
||||
CPTZButton m_btExit;
|
||||
CPTZButton m_btSettings;
|
||||
CPTZButton m_btWebCam[NUM_MAX_WEBCAMS];
|
||||
|
||||
// The controller
|
||||
CWebcamController m_aWebCams[NUM_MAX_WEBCAMS];
|
||||
|
||||
// Map to save the colors of the buttons per Webcam
|
||||
typedef std::map<UINT,COLORREF> TMAP_BTNCOLORS;
|
||||
TMAP_BTNCOLORS m_aMapBtnColors[NUM_MAX_WEBCAMS];
|
||||
|
||||
// Tooltips per WebCam
|
||||
CString m_strTooltips[NUM_MAX_WEBCAMS][CWebcamController::NUM_PRESETS];
|
||||
|
||||
HACCEL m_hAccel;
|
||||
CString m_strCameraDeviceName;
|
||||
int m_iCurrentWebCam; // zero based index to m_aWebCams
|
||||
int m_iNumWebCams;
|
||||
|
||||
void ResetAllColors();
|
||||
CWebcamController &GetCurrentWebCam();
|
||||
void SetActiveCam(int iCam);
|
||||
|
||||
// Guard thread
|
||||
CEvent m_evTerminating;
|
||||
CWinThread* m_pGuardThread;
|
||||
static UINT AFX_CDECL GuardThread(LPVOID hWnd); // AFX_THREADPROC
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
HICON m_hIcon;
|
||||
|
||||
// Generated message map functions
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void PostNcDestroy();
|
||||
virtual void OnOK();
|
||||
virtual void OnCancel();
|
||||
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam) override;
|
||||
afx_msg void OnPaint();
|
||||
afx_msg HCURSOR OnQueryDragIcon();
|
||||
DECLARE_MESSAGE_MAP()
|
||||
afx_msg void OnBtExit();
|
||||
afx_msg void OnClose();
|
||||
afx_msg LRESULT OnNcHitTest(CPoint point);
|
||||
afx_msg void OnBtMemory();
|
||||
afx_msg BOOL OnBtPreset(UINT nId);
|
||||
|
||||
void ResetMemButton();
|
||||
|
||||
afx_msg BOOL OnBtWebCam(UINT nId);
|
||||
afx_msg void OnSetFocus(CWnd* pOldWnd);
|
||||
afx_msg void OnBtZoomIn();
|
||||
afx_msg void OnBtZoomOut();
|
||||
afx_msg void OnBtUp();
|
||||
afx_msg void OnBtLeft();
|
||||
afx_msg void OnBtHome();
|
||||
afx_msg void OnBtRight();
|
||||
afx_msg void OnBtDown();
|
||||
afx_msg void OnTimer(UINT_PTR nIDEvent);
|
||||
afx_msg void OnBtUnpushed();
|
||||
afx_msg void OnBtSettings();
|
||||
};
|
||||
77
PTZControl/SettingsDlg.cpp
Normal file
77
PTZControl/SettingsDlg.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
// SettingsDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "pch.h"
|
||||
#include "PTZControl.h"
|
||||
#include "SettingsDlg.h"
|
||||
#include "afxdialogex.h"
|
||||
|
||||
|
||||
// CSettingsDlg dialog
|
||||
|
||||
IMPLEMENT_DYNAMIC(CSettingsDlg, CDialogEx)
|
||||
|
||||
CSettingsDlg::CSettingsDlg(CWnd* pParent /*=nullptr*/)
|
||||
: CDialogEx(IDD_SETTINGS, pParent)
|
||||
, m_bLogitechCameraControl(FALSE)
|
||||
, m_iMotorIntervalTimer(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CSettingsDlg::~CSettingsDlg()
|
||||
{
|
||||
}
|
||||
|
||||
void CSettingsDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialogEx::DoDataExchange(pDX);
|
||||
DDX_Text(pDX, IDC_ED_CAMERA, m_strCameraName);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_1_1, m_strTooltip[0][0]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_1_2, m_strTooltip[0][1]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_1_3, m_strTooltip[0][2]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_1_4, m_strTooltip[0][3]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_1_5, m_strTooltip[0][4]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_1_6, m_strTooltip[0][5]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_1_7, m_strTooltip[0][6]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_1_8, m_strTooltip[0][7]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_2_1, m_strTooltip[1][0]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_2_2, m_strTooltip[1][1]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_2_3, m_strTooltip[1][2]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_2_4, m_strTooltip[1][3]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_2_5, m_strTooltip[1][4]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_2_6, m_strTooltip[1][5]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_2_7, m_strTooltip[1][6]);
|
||||
DDX_Text(pDX, IDC_ED_TOOLTIP_2_8, m_strTooltip[1][7]);
|
||||
DDX_Check(pDX, IDC_CH_LOGITECHCONTROL, m_bLogitechCameraControl);
|
||||
DDX_Text(pDX, IDC_ED_MOTORTIME, m_iMotorIntervalTimer);
|
||||
DDX_Control(pDX, IDC_ED_MOTORTIME, m_edMotorInterval);
|
||||
DDX_Control(pDX, IDC_CH_LOGITECHCONTROL, m_chLogitechControl);
|
||||
if (pDX->m_bSaveAndValidate)
|
||||
m_iMotorIntervalTimer = min(max(10,m_iMotorIntervalTimer),1000);
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CSettingsDlg, CDialogEx)
|
||||
ON_BN_CLICKED(IDC_CH_LOGITECHCONTROL, &CSettingsDlg::OnChLogitechcontrol)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
// CSettingsDlg message handlers
|
||||
|
||||
|
||||
void CSettingsDlg::OnChLogitechcontrol()
|
||||
{
|
||||
m_edMotorInterval.EnableWindow(!m_chLogitechControl.GetCheck());
|
||||
}
|
||||
|
||||
|
||||
BOOL CSettingsDlg::OnInitDialog()
|
||||
{
|
||||
CDialogEx::OnInitDialog();
|
||||
|
||||
OnChLogitechcontrol();
|
||||
|
||||
CenterWindow();
|
||||
return TRUE;
|
||||
}
|
||||
34
PTZControl/SettingsDlg.h
Normal file
34
PTZControl/SettingsDlg.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "ExtensionUnit.h"
|
||||
#include "PTZControlDlg.h"
|
||||
|
||||
// CSettingsDlg dialog
|
||||
|
||||
class CSettingsDlg : public CDialogEx
|
||||
{
|
||||
DECLARE_DYNAMIC(CSettingsDlg)
|
||||
|
||||
public:
|
||||
CSettingsDlg(CWnd* pParent = nullptr); // standard constructor
|
||||
virtual ~CSettingsDlg();
|
||||
|
||||
// Dialog Data
|
||||
#ifdef AFX_DESIGN_TIME
|
||||
enum { IDD = IDD_SETTINGS };
|
||||
#endif
|
||||
public:
|
||||
CString m_strCameraName;
|
||||
CString m_strTooltip[CPTZControlDlg::NUM_MAX_WEBCAMS][CWebcamController::NUM_PRESETS];
|
||||
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
DECLARE_MESSAGE_MAP()
|
||||
public:
|
||||
BOOL m_bLogitechCameraControl;
|
||||
int m_iMotorIntervalTimer;
|
||||
afx_msg void OnChLogitechcontrol();
|
||||
CEdit m_edMotorInterval;
|
||||
CButton m_chLogitechControl;
|
||||
virtual BOOL OnInitDialog();
|
||||
};
|
||||
31
PTZControl/framework.h
Normal file
31
PTZControl/framework.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef VC_EXTRALEAN
|
||||
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
|
||||
#endif
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
|
||||
|
||||
// turns off MFC's hiding of some common and often safely ignored warning messages
|
||||
#define _AFX_ALL_WARNINGS
|
||||
|
||||
#include <afxwin.h> // MFC core and standard components
|
||||
#include <afxext.h> // MFC extensions
|
||||
|
||||
#ifndef _AFX_NO_OLE_SUPPORT
|
||||
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
|
||||
#endif
|
||||
#ifndef _AFX_NO_AFXCMN_SUPPORT
|
||||
#include <afxcmn.h> // MFC support for Windows Common Controls
|
||||
#endif // _AFX_NO_AFXCMN_SUPPORT
|
||||
|
||||
#include <afxcontrolbars.h> // MFC support for ribbons and control bars
|
||||
#include <afxdialogex.h>
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
5
PTZControl/pch.cpp
Normal file
5
PTZControl/pch.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
// pch.cpp: source file corresponding to the pre-compiled header
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
|
||||
13
PTZControl/pch.h
Normal file
13
PTZControl/pch.h
Normal file
@@ -0,0 +1,13 @@
|
||||
// pch.h: This is a precompiled header file.
|
||||
// Files listed below are compiled only once, improving build performance for future builds.
|
||||
// This also affects IntelliSense performance, including code completion and many code browsing features.
|
||||
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
|
||||
// Do not add files here that you will be updating frequently as this negates the performance advantage.
|
||||
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
|
||||
// add headers that you want to pre-compile here
|
||||
#include "framework.h"
|
||||
|
||||
#endif //PCH_H
|
||||
BIN
PTZControl/res/CameraControl.bmp
Normal file
BIN
PTZControl/res/CameraControl.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
BIN
PTZControl/res/PTZControl.ico
Normal file
BIN
PTZControl/res/PTZControl.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 194 KiB |
BIN
PTZControl/res/PTZControl.rc2
Normal file
BIN
PTZControl/res/PTZControl.rc2
Normal file
Binary file not shown.
66
PTZControl/resource.h
Normal file
66
PTZControl/resource.h
Normal file
@@ -0,0 +1,66 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by PTZControl.rc
|
||||
//
|
||||
#define IDD_PTZCONTROL_DIALOG 102
|
||||
#define IDD_PTZCONTROL 102
|
||||
#define IDR_MAINFRAME 128
|
||||
#define IDB_BUTTONS 130
|
||||
#define IDP_ERR_NO_CAMERA 131
|
||||
#define IDP_ERR_OPENFAILED 132
|
||||
#define IDR_ACCELERATOR 132
|
||||
#define IDD_SETTINGS 133
|
||||
#define IDP_TXT_CAMERAS 133
|
||||
#define IDC_BT_LEFT 1000
|
||||
#define IDC_BT_RIGHT 1001
|
||||
#define IDC_CHECK1 1001
|
||||
#define IDC_CH_LOGITECHCONTROL 1001
|
||||
#define IDC_BT_UP 1002
|
||||
#define IDC_ED_TOOLTIP_1_1 1002
|
||||
#define IDC_BT_DOWN 1003
|
||||
#define IDC_ED_TOOLTIP_1_2 1003
|
||||
#define IDC_BT_HOME 1004
|
||||
#define IDC_ED_TOOLTIP_1_3 1004
|
||||
#define IDC_BT_MEMORY 1005
|
||||
#define IDC_ED_TOOLTIP_1_4 1005
|
||||
#define IDC_BT_PRESET1 1006
|
||||
#define IDC_ED_TOOLTIP_1_5 1006
|
||||
#define IDC_BT_PRESET2 1007
|
||||
#define IDC_ED_TOOLTIP_1_6 1007
|
||||
#define IDC_BT_PRESET3 1008
|
||||
#define IDC_ED_TOOLTIP_1_7 1008
|
||||
#define IDC_BT_PRESET4 1009
|
||||
#define IDC_ED_TOOLTIP_1_8 1009
|
||||
#define IDC_BT_PRESET5 1010
|
||||
#define IDC_ED_CAMERA 1010
|
||||
#define IDC_BT_PRESET6 1011
|
||||
#define IDC_EDIT1 1011
|
||||
#define IDC_ED_MOTORTIME 1011
|
||||
#define IDC_BT_PRESET7 1012
|
||||
#define IDC_ED_TOOLTIP_2_1 1012
|
||||
#define IDC_BT_PRESET8 1013
|
||||
#define IDC_ED_TOOLTIP_2_2 1013
|
||||
#define IDC_BT_ZOOM_IN 1014
|
||||
#define IDC_ED_TOOLTIP_2_3 1014
|
||||
#define IDC_BT_ZOOM_OUT 1015
|
||||
#define IDC_ED_TOOLTIP_2_4 1015
|
||||
#define IDC_BT_EXIT 1016
|
||||
#define IDC_ED_TOOLTIP_2_5 1016
|
||||
#define IDC_BT_SETTINGS 1017
|
||||
#define IDC_ED_TOOLTIP_2_6 1017
|
||||
#define IDC_BT_WEBCAM1 1018
|
||||
#define IDC_ED_TOOLTIP_2_7 1018
|
||||
#define IDC_BT_WEBCAM2 1019
|
||||
#define IDC_ED_TOOLTIP_2_8 1019
|
||||
#define DC_BT_SETTINGS 32791
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 135
|
||||
#define _APS_NEXT_COMMAND_VALUE 32793
|
||||
#define _APS_NEXT_CONTROL_VALUE 1012
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
8
PTZControl/targetver.h
Normal file
8
PTZControl/targetver.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
// Including SDKDDKVer.h defines the highest available Windows platform.
|
||||
|
||||
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
|
||||
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
|
||||
|
||||
#include <SDKDDKVer.h>
|
||||
Reference in New Issue
Block a user