9 Commits

Author SHA1 Message Date
d5aa14ba8b Added fourth camera. 2024-05-04 22:19:33 +02:00
Martin Richter
31d356e7b4 Small fix for a 64bit build. Compile error due to wrong type usage.
Switch to VS-2022 platform v143.
2023-09-07 08:11:36 +02:00
Martin Richter
eb09cf2aa1 Merge pull request #15 from cuppajoeman/patch-1
Update README.md
@cuppajoeman  Thanks for the fixes
2023-05-25 09:18:51 +02:00
ccn
32bdee48a6 Update README.md
typos
2023-05-24 16:08:15 -04:00
Martin Richter
546152b568 Minor changes to the readme. 2022-12-10 13:48:08 +01:00
Martin Richter
a3282a0044 Added support for a thrid camera and a dynamic layout so save screen space.
Added support for the ConferenceCam CC3000e Camera.
Some redisgn.
2022-12-10 13:39:26 +01:00
Martin Richter
cd0af32a1f Added support for Logitech PTZ Pro camera.
Fixed bug, that settigs dialog didn't show the matching camera names.
2022-10-30 11:58:27 +01:00
Martin Richter
74b5a32679 Delete PTZControl.aps
Not required.
2022-10-06 18:19:01 +02:00
Martin Richter
77eb4db494 Added docu for hotkeys. 2022-10-06 18:17:30 +02:00
64 changed files with 345 additions and 57 deletions

BIN
.vs/PTZControl/v17/.wsuo Normal file

Binary file not shown.

View File

@@ -0,0 +1,23 @@
{
"Version": 1,
"WorkspaceRootPath": "C:\\Users\\mspel\\source\\repos\\PTZControl\\",
"Documents": [],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": -1,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{cce594b6-0c39-4442-ba28-10c64ac7e89f}"
}
]
}
]
}
]
}

View File

@@ -0,0 +1,7 @@
{
"ExpandedNodes": [
""
],
"SelectedNode": "\\PTZControl.sln",
"PreviewInSolutionExplorer": false
}

View File

@@ -635,7 +635,7 @@ void CWebcamController::ListDevices(CStringArray &aDevices)
//create a device class enumerator
CComPtr<IEnumMoniker> pIEnumMoniker;
HRESULT hResult = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pIEnumMoniker, 0);
if (SUCCEEDED(hr))
if (SUCCEEDED(hr) && (hResult == S_OK))
{
ULONG pFetched = NULL;
CComPtr<IMoniker> pImoniker;
@@ -661,5 +661,11 @@ void CWebcamController::ListDevices(CStringArray &aDevices)
pImoniker = nullptr;
}
}
//else {
// aDevices.Add(CString("PTZ Pro 1\tPTZ Pro 1"));
// aDevices.Add(CString("PTZ Pro 2\tPTZ Pro 2"));
// aDevices.Add(CString("PTZ Pro 3\tPTZ Pro 3"));
// aDevices.Add(CString("PTZ Pro 4\tPTZ Pro 4"));
//}
}
}

Binary file not shown.

View File

@@ -27,9 +27,6 @@
#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

Binary file not shown.

View File

@@ -29,14 +29,14 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</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>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Static</UseOfMfc>
@@ -44,14 +44,14 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</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>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Static</UseOfMfc>

View File

@@ -0,0 +1,23 @@
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.pch
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\vc143.pdb
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\vc143.idb
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\pch.obj
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\settingsdlg.obj
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontroldlg.obj
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.obj
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\extensionunit.obj
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.exe
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.pdb
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.res
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.ilk
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.tlog\cl.command.1.tlog
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.tlog\cl.items.tlog
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.tlog\cl.read.1.tlog
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.tlog\cl.write.1.tlog
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.tlog\link.command.1.tlog
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.tlog\link.read.1.tlog
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.tlog\link.secondary.1.tlog
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.tlog\link.write.1.tlog
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.tlog\rc.command.1.tlog
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.tlog\rc.read.1.tlog
c:\users\mspel\source\repos\ptzcontrol\ptzcontrol\ptzcontrol\x64\debug\ptzcontrol.tlog\rc.write.1.tlog

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<ProjectOutputs>
<ProjectOutput>
<FullPath>C:\Users\mspel\source\repos\PTZControl\PTZControl\x64\Debug\PTZControl.exe</FullPath>
</ProjectOutput>
</ProjectOutputs>
<ContentFiles />
<SatelliteDlls />
<NonRecipeFileRefs />
</Project>

Binary file not shown.

View File

@@ -0,0 +1 @@
 PTZControl.vcxproj -> C:\Users\mspel\source\repos\PTZControl\PTZControl\x64\Debug\PTZControl.exe

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,5 @@
C:\Users\mspel\source\repos\PTZControl\PTZControl\ExtensionUnit.cpp;C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl\x64\Debug\ExtensionUnit.obj
C:\Users\mspel\source\repos\PTZControl\PTZControl\pch.cpp;C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl\x64\Debug\pch.obj
C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl.cpp;C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl\x64\Debug\PTZControl.obj
C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControlDlg.cpp;C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl\x64\Debug\PTZControlDlg.obj
C:\Users\mspel\source\repos\PTZControl\PTZControl\SettingsDlg.cpp;C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl\x64\Debug\SettingsDlg.obj

View File

@@ -0,0 +1,2 @@
PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.39.33519:TargetPlatformVersion=10.0.22621.0:
Debug|x64|C:\Users\mspel\source\repos\PTZControl\PTZControl\|

View File

@@ -0,0 +1,2 @@
^C:\USERS\MSPEL\SOURCE\REPOS\PTZCONTROL\PTZCONTROL\PTZCONTROL\X64\DEBUG\EXTENSIONUNIT.OBJ|C:\USERS\MSPEL\SOURCE\REPOS\PTZCONTROL\PTZCONTROL\PTZCONTROL\X64\DEBUG\PCH.OBJ|C:\USERS\MSPEL\SOURCE\REPOS\PTZCONTROL\PTZCONTROL\PTZCONTROL\X64\DEBUG\PTZCONTROL.OBJ|C:\USERS\MSPEL\SOURCE\REPOS\PTZCONTROL\PTZCONTROL\PTZCONTROL\X64\DEBUG\PTZCONTROL.RES|C:\USERS\MSPEL\SOURCE\REPOS\PTZCONTROL\PTZCONTROL\PTZCONTROL\X64\DEBUG\PTZCONTROLDLG.OBJ|C:\USERS\MSPEL\SOURCE\REPOS\PTZCONTROL\PTZCONTROL\PTZCONTROL\X64\DEBUG\SETTINGSDLG.OBJ
C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl\x64\Debug\PTZControl.ilk

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<ProjectOutputs>
<ProjectOutput>
<FullPath>C:\Users\mspel\source\repos\PTZControl\PTZControl\x64\Release\PTZControl.exe</FullPath>
</ProjectOutput>
</ProjectOutputs>
<ContentFiles />
<SatelliteDlls />
<NonRecipeFileRefs />
</Project>

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,7 @@
 ExtensionUnit.cpp
Generating code
6 of 739 functions ( 0.8%) were compiled, the rest were copied from previous compilation.
0 functions were new in current compilation
8 functions had inline decision re-evaluated but remain unchanged
Finished generating code
PTZControl.vcxproj -> C:\Users\mspel\source\repos\PTZControl\PTZControl\x64\Release\PTZControl.exe

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,5 @@
C:\Users\mspel\source\repos\PTZControl\PTZControl\ExtensionUnit.cpp;C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl\x64\Release\ExtensionUnit.obj
C:\Users\mspel\source\repos\PTZControl\PTZControl\pch.cpp;C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl\x64\Release\pch.obj
C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl.cpp;C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl\x64\Release\PTZControl.obj
C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControlDlg.cpp;C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl\x64\Release\PTZControlDlg.obj
C:\Users\mspel\source\repos\PTZControl\PTZControl\SettingsDlg.cpp;C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl\x64\Release\SettingsDlg.obj

View File

@@ -0,0 +1,2 @@
PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.39.33519:TargetPlatformVersion=10.0.22621.0:
Release|x64|C:\Users\mspel\source\repos\PTZControl\PTZControl\|

View File

@@ -0,0 +1,3 @@
^C:\USERS\MSPEL\SOURCE\REPOS\PTZCONTROL\PTZCONTROL\PTZCONTROL\X64\RELEASE\EXTENSIONUNIT.OBJ|C:\USERS\MSPEL\SOURCE\REPOS\PTZCONTROL\PTZCONTROL\PTZCONTROL\X64\RELEASE\PCH.OBJ|C:\USERS\MSPEL\SOURCE\REPOS\PTZCONTROL\PTZCONTROL\PTZCONTROL\X64\RELEASE\PTZCONTROL.OBJ|C:\USERS\MSPEL\SOURCE\REPOS\PTZCONTROL\PTZCONTROL\PTZCONTROL\X64\RELEASE\PTZCONTROL.RES|C:\USERS\MSPEL\SOURCE\REPOS\PTZCONTROL\PTZCONTROL\PTZCONTROL\X64\RELEASE\PTZCONTROLDLG.OBJ|C:\USERS\MSPEL\SOURCE\REPOS\PTZCONTROL\PTZCONTROL\PTZCONTROL\X64\RELEASE\SETTINGSDLG.OBJ
C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl\x64\Release\PTZControl.IPDB
C:\Users\mspel\source\repos\PTZControl\PTZControl\PTZControl\x64\Release\PTZControl.iobj

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -13,6 +13,103 @@
#endif
//////////////////////////////////////////////////////////////////////////////////////////
// Array of supported cameras
// Allow the cameras with the following tags in the device name.
// This will match all Logitech PRT Pro, PTZ Pro 2 and Rally cameras.
// Also the ConferenceCam CC3000e Camera will be detected.
// Remember: Just a partial token must match the name.
static const LPCTSTR g_aCameras[] =
{
_T("PTZ Pro"),
_T("Logi Rally"),
_T("ConferenceCam"),
};
//////////////////////////////////////////////////////////////////////////////////////////
// We have several layouts for the Buttons
// 0-1 cameras (dialog will shrink by one column)
// E |
// S |
// 2 cameras
// S E
// - -
// 1 2
// 3 cameras
// 1 E
// 2 S
// 3
struct SPosition
{
UINT nId; // Id of button
bool bShow; // Show or hide
int x, y; // outside raster, left two columns
};
struct SLayout
{
int cxDelta; // Num to shrink / grow the dialog
const SPosition* pButtons; // List of entries terminated with nId==0.
};
static const SPosition layoutBtns1[] // 0 or 1 camera (uses only 1 column)
{
IDC_BT_EXIT, true, 0, 0, // one columns
IDC_BT_SETTINGS, true, 0, 1,
// Invisible
IDC_BT_WEBCAM1, false, 0, 0,
IDC_BT_WEBCAM2, false, 0, 0,
IDC_BT_WEBCAM3, false, 0, 0,
IDC_BT_WEBCAM4, false, 0, 0,
0
};
static const SPosition layoutBtns2[] // 2 cameras (uses 2 columns)
{
IDC_BT_SETTINGS, true, 0, 0, // Top row
IDC_BT_EXIT, true, 1, 0,
IDC_BT_WEBCAM1, true, 0, 2, // bottom row
IDC_BT_WEBCAM2, true, 1, 2,
// Invisible
IDC_BT_WEBCAM3, false, 0, 0,
IDC_BT_WEBCAM4, false, 0, 0,
0
};
static const SPosition layoutBtns3[] // 3 cameras
{
IDC_BT_EXIT, true, 1, 0, // Outer left column
IDC_BT_SETTINGS, true, 1, 1,
IDC_BT_WEBCAM1, true, 0, 0, // all in one column left (top down)
IDC_BT_WEBCAM2, true, 0, 1,
IDC_BT_WEBCAM3, true, 0, 2,
IDC_BT_WEBCAM4, true, 0, 0,
0
};
static const SPosition layoutBtns4[] // 4 cameras
{
IDC_BT_EXIT, true, 1, 0, // Outer left column
IDC_BT_SETTINGS, true, 1, 1,
IDC_BT_WEBCAM1, true, 0, 0, // all in one column left (top down)
IDC_BT_WEBCAM2, true, 0, 1,
IDC_BT_WEBCAM3, true, 0, 2,
IDC_BT_WEBCAM4, true, 1, 2,
0
};
const SLayout g_layout[CPTZControlDlg::NUM_MAX_WEBCAMS+1] =
{
-1, layoutBtns1, // 0 or 1 camera (shrink dialog)
-1, layoutBtns1, // 0 or 1 camera (shrink dialog)
0, layoutBtns2, // 2 cameras (keep size)
0, layoutBtns3, // 3 cameras (keep size)
0, layoutBtns4, // 4 cameras (keep size)
};
//////////////////////////////////////////////////////////////////////////////////////////
// Special new notification
#define ON_BN_UNPUSHED(id, memberFxn) \
ON_CONTROL(BN_UNPUSHED, id, memberFxn)
@@ -221,6 +318,8 @@ void CPTZControlDlg::DoDataExchange(CDataExchange* pDX)
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]);
DDX_Control(pDX, IDC_BT_WEBCAM3, m_btWebCam[2]);
DDX_Control(pDX, IDC_BT_WEBCAM4, m_btWebCam[3]);
}
BEGIN_MESSAGE_MAP(CPTZControlDlg, CDialogEx)
@@ -233,6 +332,8 @@ BEGIN_MESSAGE_MAP(CPTZControlDlg, CDialogEx)
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_WEBCAM3, &CPTZControlDlg::OnBtWebCam)
ON_COMMAND_EX(IDC_BT_WEBCAM4, &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)
@@ -349,7 +450,7 @@ UINT AFX_CDECL CPTZControlDlg::GuardThread(LPVOID p)
// Event is set.
return 0;
DWORD dwResult = 0;
DWORD_PTR dwResult = 0;
// Check if the application is blocking
if (::SendMessageTimeout(pWnd->GetSafeHwnd(), WM_NULL, 0, 0, SMTO_ABORTIFHUNG | SMTO_NORMAL, 1000, &dwResult)==0)
{
@@ -363,6 +464,9 @@ BOOL CPTZControlDlg::OnInitDialog()
{
__super::OnInitDialog();
//---------------------------------------------------------------------
// INIT MFC STUFF
// 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
@@ -397,6 +501,8 @@ BOOL CPTZControlDlg::OnInitDialog()
&m_btSettings,
&m_btWebCam[0],
&m_btWebCam[1],
&m_btWebCam[2],
&m_btWebCam[3],
};
for (auto* pBtn : apButtons)
{
@@ -420,22 +526,9 @@ BOOL CPTZControlDlg::OnInitDialog()
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);
//---------------------------------------------------------------------
// INIT AND FIND WEB CAMS
//
// Try to find the Device list
CStringArray aDevices;
CWebcamController::ListDevices(aDevices);
@@ -457,10 +550,10 @@ BOOL CPTZControlDlg::OnInitDialog()
// 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(""));
CStringArray aStrCameraNameToSearch;
for (const auto *p : g_aCameras)
aStrCameraNameToSearch.Add(p);
CString strCameraNameToSearch = theApp.GetProfileString(REG_DEVICE, REG_DEVICENAME, _T(""));
if (!strCameraNameToSearch.IsEmpty())
aStrCameraNameToSearch.Add(strCameraNameToSearch);
if (!theApp.m_strDevName.IsEmpty())
@@ -496,6 +589,9 @@ CStringArray aStrCameraNameToSearch;
}
}
// save the camera names.
m_strCameraDeviceNames = strCameras;
// 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))
{
@@ -511,14 +607,52 @@ CStringArray aStrCameraNameToSearch;
AfxMessageBox(IDP_ERR_NO_CAMERA, MB_ICONERROR);
}
// Only 1 or none, we don't need the camera selection buttons
if (m_iNumWebCams<=1)
//---------------------------------------------------------------------
// ADJUST THE DIALOG
// Calculate the with an position of the Grid.
CRect rectBtn11, rectBtn12, rectBtn21;
m_btWebCam[0].GetWindowRect(rectBtn11);
m_btWebCam[1].GetWindowRect(rectBtn12);
m_btExit.GetWindowRect(rectBtn21);
ScreenToClient(rectBtn11);
ScreenToClient(rectBtn12);
ScreenToClient(rectBtn21);
CPoint pointBase { rectBtn11.TopLeft() };
CSize sizeRaster { rectBtn21.left-rectBtn11.left, rectBtn12.top-rectBtn11.top };
// Get the required layout
const auto &layout = g_layout[m_iNumWebCams];
for (const auto* pLayoutBtn = layout.pButtons; pLayoutBtn->nId; ++pLayoutBtn)
{
// Sow the web cam buttons only if we have 2 cams
for (auto &btn : m_btWebCam)
btn.ShowWindow(SW_HIDE);
CWnd *pWnd = GetDlgItem(pLayoutBtn->nId);
// Move the button and hide or show the button
pWnd->SetWindowPos(nullptr,
pointBase.x + pLayoutBtn->x * sizeRaster.cx, pointBase.y + pLayoutBtn->y * sizeRaster.cy,
0, 0, SWP_NOSIZE|SWP_NOZORDER|(pLayoutBtn->bShow ? SWP_SHOWWINDOW : SWP_HIDEWINDOW)
);
pWnd->EnableWindow(pLayoutBtn->bShow);
}
// 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, rect.Width()+layout.cxDelta*sizeRaster.cx, rect.Height(), 0);
// Set the tooltips for all presets
for (int i = 0; i < CWebcamController::NUM_PRESETS; ++i)
{
for (int j = 0; j < CPTZControlDlg::NUM_MAX_WEBCAMS; ++j)
@@ -687,7 +821,9 @@ BOOL CPTZControlDlg::OnBtPreset(UINT nId)
BOOL CPTZControlDlg::OnBtWebCam(UINT nId)
{
SetActiveCam(nId==IDC_BT_WEBCAM1 ? 0 : 1);
SetActiveCam(nId==IDC_BT_WEBCAM1 ? 0 :
nId==IDC_BT_WEBCAM2 ? 1 :
nId==IDC_BT_WEBCAM3 ? 2 : 3);
return 1;
}
@@ -789,7 +925,8 @@ void CPTZControlDlg::OnBtUnpushed()
void CPTZControlDlg::OnBtSettings()
{
CSettingsDlg dlg;
dlg.m_strCameraName = m_strCameraDeviceName;
dlg.m_strCameraName = m_strCameraDeviceNames;
dlg.m_strCameraName.Replace(_T("\r\n"), _T(", "));
dlg.m_bLogitechCameraControl = GetCurrentWebCam().UseLogitechMotionControl();
dlg.m_iMotorIntervalTimer = GetCurrentWebCam().GetMotorIntervalTimer();

View File

@@ -73,7 +73,7 @@ public:
~CPTZControlDlg();
// Dialog Data
enum { IDD = IDD_PTZCONTROL_DIALOG };
static const int NUM_MAX_WEBCAMS = 2;
static const int NUM_MAX_WEBCAMS = 4;
protected:
CPTZButton m_btZoomIn;
@@ -100,7 +100,7 @@ protected:
CString m_strTooltips[NUM_MAX_WEBCAMS][CWebcamController::NUM_PRESETS];
HACCEL m_hAccel;
CString m_strCameraDeviceName;
CString m_strCameraDeviceNames;
int m_iCurrentWebCam; // zero based index to m_aWebCams
int m_iNumWebCams;

View File

@@ -27,6 +27,12 @@ void CSettingsDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_ED_CAMERA, m_strCameraName);
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);
// Tooltips
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]);
@@ -43,10 +49,15 @@ void CSettingsDlg::DoDataExchange(CDataExchange* pDX)
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);
DDX_Text(pDX, IDC_ED_TOOLTIP_3_1, m_strTooltip[2][0]);
DDX_Text(pDX, IDC_ED_TOOLTIP_3_2, m_strTooltip[2][1]);
DDX_Text(pDX, IDC_ED_TOOLTIP_3_3, m_strTooltip[2][2]);
DDX_Text(pDX, IDC_ED_TOOLTIP_3_4, m_strTooltip[2][3]);
DDX_Text(pDX, IDC_ED_TOOLTIP_3_5, m_strTooltip[2][4]);
DDX_Text(pDX, IDC_ED_TOOLTIP_3_6, m_strTooltip[2][5]);
DDX_Text(pDX, IDC_ED_TOOLTIP_3_7, m_strTooltip[2][6]);
DDX_Text(pDX, IDC_ED_TOOLTIP_3_8, m_strTooltip[2][7]);
if (pDX->m_bSaveAndValidate)
m_iMotorIntervalTimer = min(max(10,m_iMotorIntervalTimer),1000);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -52,6 +52,27 @@
#define IDC_ED_TOOLTIP_2_7 1018
#define IDC_BT_WEBCAM2 1019
#define IDC_ED_TOOLTIP_2_8 1019
#define IDC_BT_WEBCAM3 1020
#define IDC_ED_TOOLTIP_3_1 1020
#define IDC_ED_TOOLTIP_3_2 1021
#define IDC_ED_TOOLTIP__3_3 1022
#define IDC_ED_TOOLTIP_3_3 1022
#define IDC_ED_TOOLTIP_3_4 1023
#define IDC_ED_TOOLTIP_3_5 1024
#define IDC_ED_TOOLTIP_3_6 1025
#define IDC_ED_TOOLTIP_3_7 1026
#define IDC_ED_TOOLTIP_3_8 1027
#define IDC_BT_WEBCAM4 1028
#define IDC_ED_TOOLTIP_4_1 1028
#define IDC_ED_TOOLTIP_4_2 1029
#define IDC_ED_TOOLTIP__4_3 1030
#define IDC_ED_TOOLTIP_4_3 1031
#define IDC_ED_TOOLTIP_4_4 1032
#define IDC_ED_TOOLTIP_4_5 1033
#define IDC_ED_TOOLTIP_4_6 1034
#define IDC_ED_TOOLTIP_4_7 1035
#define IDC_ED_TOOLTIP_4_8 1036
#define DC_BT_SETTINGS 32791
// Next default values for new objects

View File

@@ -5,12 +5,13 @@ This small program is designed to control a Logitech PTZ 2 Pro. The camera was p
Unfortunately, it quickly turned out that the operation with the remote control is possible but cumbersome and inaccurate. The camera was installed directly behind and above the video technician and always pointing back with the remote control was not comfortable.
The control Logitech software shipped with the camera is completely worthless.
So, I made the decision to build a corresponding control program.
Some months later we bought a second camera, and the program was extended by the function to control another camera. A maximum of two cameras are supported.
And finally, I added support for the Logitech Rally.
Some months later we bought a second camera, and the program was extended by the function to control another camera. At this time a maximum of two cameras was supported.
Later added support for the Logitech Rally, the PTZ Pro and other Logitech cameras.
And finnaly as last feature the PTZcontrol now supports three cameras.
### Where is the basic code from?
It wasn't easy to get code that shows how to control a PTZ camera.
Finally I contacted Lgoitech and I received download link to the `Logitech Collaboration Software Reference Kit` (Logitech CSRK)
Finally I contacted Logitech and I received download link to the `Logitech Collaboration Software Reference Kit` (Logitech CSRK)
I found some Lync remote control code in it, that gave me some hints and the guids and usage for the Logitect camera interface.
## Used interfaces
@@ -28,14 +29,14 @@ Standard controls from the Windows Driver API are used
The program supports tooltips that and you can define them yourself to give the camera presets useful names. (Separate for each camera)
## Used environment and libraries
I used the Visual Studoi 2019 Community Edition to develop this program with C++.
MFC and ATL as the library. No additional software is used.
The EXE runs alone, without installing any other files.
I used the Visual Studio 2019 Community Edition to develop this program with C++.
Using MFC and ATL as libraries. No additional software is used.
The EXE runs alone, without installing any other files or DLLs or any installation.
## Behaviour
The program is always in the foreground and has been designed relatively compact and small, so that you can hover somewhere over your OBS program and it is really easy to use.
Current selected preset or home position are shown with a green background on the buttons.
Recalling a presets are simply done by clicking on one of the number buttons.
Currently selected preset or home position are shown with a green background on the buttons.
Recalling a preset is simply done by clicking on one of the number buttons.
Presets are changed by pressing the M button (Memory) followed by a number key. The M button turns red as long as it is active.
The program remembers its last position on the screen and is automatically repositioned to when it is started.
@@ -43,12 +44,13 @@ All settings are stored in the registry under the branch `HKEY_CURRENT_USER\SOFT
See the command line secion too.
### Supported Cameras
Currently, the Logitech PTZ 2 Pro and Logitech Rally cameras are automatically detected.
Currently, the Logitech PTZ 2 Pro, PTZ Pro, Logitech Rally cameras and ConferenceCam CC3000e Camera are automatically detected.
For other cameras, you can try to force detection by specifying the name (or part of the name) of the cameras in the registry or on the command line.
Internally, all cameras that have one of the following tokens in the name are automatically used:
- *PTZ 2 Pro*
- *PTZ Pro*
- *Logi Rally*
- *ConferenceCam*
### Guard Thread
Unfortunately, we have sometimes had the experience that OBS or the USB bus hangs with a camera. The PTZControl program then usually stops and stops responding because the camera control commands block the application.
@@ -56,7 +58,7 @@ Through an internal guard thread, the application can determine that it is no lo
Otherwise you would have to use the task manager and this can take a lot of time to terminate the application in the hustle and bustle of a livestream.
### Logitech Motion Control
The Logitech cameras have their own interface for pan/tilt control. This moves the camera in X/Y Axe by a certain step value, This control is a special Logitech feature.
The Logitech cameras have their own interface for pan/tilt control. This moves the camera in X/Y axes by a certain step value, This control is a special Logitech feature.
If you click on a direction button once, exactly one step pulse is output.
If you hold down a direction button, a pulse is sent to the camera again and again at a certain interval to change the direction.
@@ -68,12 +70,24 @@ If you click on a direction button once, the motor is turned on and off again af
If the direction button remains pressed, the motor remains switched on for the corresponding direction until the button is released again.
This control seems more effective and accurate to me and is the standard. The disadvantage is that if the timer interval is too small, the camera does not react immediately when a button is clicked. But since precision was more important to me because our camera is installed relatively far away from the podium, I use this setting with a 70msec timer.
## Hotkeys
The program has serveral hotkeys that allows a control without the mouse when it has the focus.
- Pan-Tilt control with Left, Right, Up, Down keys.
- Home position with Num-0, Home keys.
- Memory function with the M-key.
- Recall stored position with the numeric keys 1-8 or the numeric key pad keys Num-1 to Num-8.#
- Open the setings dialog with Num-Divide or Num-Multiply
- Zoom in/out Page-Up/Down, Num+Plus, Num-Minus
- Select Camera 1. Alt+1, Alt+Num-1, Alt+Page-Up
- Select Camera 2. Alt+2, Alt+Num-2, Alt+Page-Down
## Command Line Options
A few options can be set from the command line. Command-line switches override the settings in the registry.
**-device:"name of device"**
The device option can be used to specify a name component of a camera to be used for control.
If you enter "*" as the name, then each camera will be recognized.
If you enter "*" as the name, then any camera will be recognized.
**-showdevices**
Displays a message box after startup showing the name(s) of the detected cameras.
@@ -84,10 +98,10 @@ At startup, a detected camera is moved to the home position (Logitech Preset) an
**-noguard**
-noguard prevents the application from terminating itself in a controlled manner. This can be especially important in the event of a bug and for testing.
## Registry
## Registry settings
In the registry branch `HKEY_CURRENT_USER\SOFTWARE\MRi-Software\PTZControl\Options` it is possible to preset the following options without using the command line.
**NoReset (DWORD value**
**NoReset (DWORD value)**
*Value <>0:* Has the same function as -noreset on the command line. The current camera and zoom position is maintained when starting the program. Value = 0: When starting the program, you move to the home position and zoom to maximum wide angle. (Default)
**NoGuard (DWORD value)**